Skip to content

ComposeDebugDrawer#

Open in GitHub

Latest Release Last Update License

Stars Forks

This library offers you a simple and easily extendable debug drawer.

📷 Screenshots#

Demos
Demo Demo Demo Demo
Demo Demo Demo
Demo Demo Demo

Features#

  • easily extendible
  • one line integration
  • can be easily enabled/diabled in debug/release builds or based on a user setting
  • predefined optional modules

All features are splitted into separate modules, just include the modules you want to use!

🔗 Dependencies#

Compose

Dependency Version Infos
Compose BOM 2024.04.00 Mapping
Material3 1.2.1

Library

Module Dependency Version
core -
Info Modules
infos-build -
infos-device -
Plugins
plugin-lumberjack Lumberjack 6.0.7
plugin-kotpreferences KotPreferences 0.5.1

Setup Gradle#

This library is distributed via JitPack.io.

1/2: Add jitpack to your project's build.gradle
repositories {
    maven { url "https://jitpack.io" }
}
2/2: Add dependencies to your module's build.gradle
// use the latest version of the library
val composedebugdrawer = "<LATEST-VERSION>" 

// include necessary modules

// core module
implementation("com.github.MFlisar.ComposeDebugDrawer:core:$composedebugdrawer")

// info module
implementation("com.github.MFlisar.ComposeDebugDrawer:infos-build:$composedebugdrawer")
implementation("com.github.MFlisar.ComposeDebugDrawer:infos-device:$composedebugdrawer")

// plugin module
implementation("com.github.MFlisar.ComposeDebugDrawer:plugin-lumberjack:$composedebugdrawer")
implementation("com.github.MFlisar.ComposeDebugDrawer:plugin-kotpreferences:$composedebugdrawer")

⌨ Usage#

It works as simple as following:

DebugDrawer
// wrap your app content inside the drawer like following
val drawerState = rememberDebugDrawerState()
ComposeAppTheme  {
    DebugDrawer(
        enabled = BuildConfig.DEBUG, // if disabled the drawer will not be created at all, in this case inside a release build...
        drawerState = drawerState,
        drawerContent = {
            // drawer content
        },
        content = {
            // your wrapped app content
        }
    )
}
Example Drawer Content
@Composable
private fun Drawer(drawerState: DebugDrawerState) {
    DebugDrawerBuildInfos(drawerState)
    DebugDrawerActions(drawerState)
    DebugDrawerDeviceInfos(drawerState)

    // lumberjack module for logs
    DebugDrawerLumberjack(
        drawerState = drawerState,
        setup = DemoLogging.fileLoggingSetup,
        mailReceiver = "feedback@gmail.com"
    )

    // kotpreferences module for delegate based preferences (another library of mine)
    DebugDrawerRegion(
        icon = Icons.Default.ColorLens,
        label = "Demo Preferences",
        drawerState = drawerState
    ) {
        DebugDrawerDivider(info = "Boolean")
        DebugDrawerSettingCheckbox(setting = DemoPrefs.devBoolean1)
        DebugDrawerSettingCheckbox(setting = DemoPrefs.devBoolean2)
        DebugDrawerDivider(info = "Enum")
        DebugDrawerSettingDropdown(setting = DemoPrefs.devStyle,items = DemoPrefs.UIStyle.values())
    }

    // manual checkboxes, dropdowns, infos
    DebugDrawerRegion(
        icon = Icons.Default.Info,
        label = "Manual",
        drawerState = drawerState
    ) {
        // Checkbox
        var test1 by remember { mutableStateOf(false) }
        DebugDrawerCheckbox(
            label = "Checkbox",
            description = "Some debug flag",
            checked = test1
        ) {
            test1 = it
        }

        // Button
        DebugDrawerButton(
            icon = Icons.Default.BugReport, 
            label = "Button (Filled)"
        ) {
            // on click
        }

        // Dropdown
        val items = listOf("Entry 1", "Entry 2", "Entry 3")
        var selected by remember { mutableStateOf(items[0]) }
        DebugDrawerDropdown(
            modifier = modifier,
            label = "Items",
            selected = selected,
            items = items
        ) {
            selected = it
        }

        // Sectioned Button
        val items2 = listOf("L1", "L2", "L3")
        val level = remember { mutableStateOf(items2[0]) }
        DebugDrawerSegmentedButtons(
            selected = level, 
            items = items2
        )

        // Info
        DebugDrawerInfo(title = "Custom Info", info = "Value of custom info...")
    }
}

🧬 Demo#

A full demo is included inside the demo module, it shows nearly every usage with working examples.

Modules and Extensions#

Module Build Infos

This simple module allows you to add a build info region to the debug drawer.

DebugDrawerBuildInfos(drawerState)
Module Device Infos

This simple module allows you to add a device info region to the debug drawer.

DebugDrawerDeviceInfos(drawerState)
Extension Lumberjack

This simple module allows you to add a region for my lumberjack logging library. And will show buttons to show the log file, send it via mail or to clear it.

DebugDrawerLumberjack.kt
@Composable
fun DebugDrawerLumberjack(
    drawerState: DebugDrawerState,
    setup: IFileLoggingSetup,
    mailReceiver: String,
    icon: ImageVector = Icons.Default.Description,
    label: String = "Logging",
    id: String = label,
    collapsible: Boolean = true,
    content: @Composable ColumnScope.() -> Unit = {}
Extension KotPreferences

This simple module allows you to use my delegate based preference library KotPreferences inside the debug drawer. With this extension labels are e.g. directly derived from the KotPreference property. It offers overloads for Checkbox, Dropdown and SegmentedButton debug drawer fields.

DebugDrawerSettingCheckbox.kt
 fun DebugDrawerSettingCheckbox(
     setting: StorageSetting<Boolean>,
     modifier: Modifier = Modifier,
     icon: ImageVector,
     foregroundTint: Color? = null,
     label: String = setting.getDebugLabel(),
     description: String = ""
 ) {

 fun DebugDrawerSettingCheckbox(
     setting: StorageSetting<Boolean>,
     modifier: Modifier = Modifier,
     image: @Composable (() -> Unit)? = null,
     foregroundTint: Color? = null,
     label: String = setting.getDebugLabel(),
     description: String = ""
 ) {
DebugDrawerSettingDropdown.kt
 fun <E : Enum<E>> DebugDrawerSettingDropdown(
     modifier: Modifier = Modifier,
     setting: StorageSetting<E>,
     items: Array<E>,
     icon: ImageVector,
     label: String = setting.getDebugLabel()
 ) {

 fun <E : Enum<E>> DebugDrawerSettingDropdown(
     modifier: Modifier = Modifier,
     setting: StorageSetting<E>,
     items: Array<E>,
     image: @Composable (() -> Unit)? = null,
     label: String = setting.getDebugLabel()
 ) {
DebugDrawerSettingSegmentedButtons.kt
 fun <E : Enum<E>> DebugDrawerSettingSegmentedButtons(
     modifier: Modifier = Modifier,
     setting: StorageSetting<E>,
     items: Array<E>,
     icon: ImageVector,
 ) {

 fun <E : Enum<E>> DebugDrawerSettingSegmentedButtons(
     modifier: Modifier = Modifier,
     setting: StorageSetting<E>,
     items: Array<E>,
     image: @Composable (() -> Unit)? = null,
 ) {