diff --git a/jsApp/src/jsMain/kotlin/main.js.kt b/jsApp/src/jsMain/kotlin/main.js.kt index 5fbc4d6..f00d192 100644 --- a/jsApp/src/jsMain/kotlin/main.js.kt +++ b/jsApp/src/jsMain/kotlin/main.js.kt @@ -1,3 +1,4 @@ +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.* import androidx.compose.ui.Modifier @@ -9,6 +10,8 @@ import kotlinx.browser.document import org.jetbrains.skiko.wasm.onWasmReady import ui.Playground import ui.theme.PlaygroundTheme +import ui.theme.appDarkColors +import ui.theme.appLightColors import utils.withTouchSlop fun main() { @@ -20,18 +23,30 @@ fun main() { BrowserViewportWindow("Compose Modifiers Playground") { var activeTemplate by remember { mutableStateOf(Templates.Rainbow) } + // Note: isSystemInDarkTheme() is not yet implemented in JS. It will always return false until + // the feature is implemented. + val isSystemInDarkTheme = isSystemInDarkTheme() + var useDarkTheme by remember { mutableStateOf(isSystemInDarkTheme) } + val themeColors = if (useDarkTheme) appDarkColors else appLightColors + // Decrease the touch slop. The default value of too high for desktop val vc = LocalViewConfiguration.current.withTouchSlop( with(LocalDensity.current) { 0.125.dp.toPx() }, ) CompositionLocalProvider(LocalViewConfiguration provides vc) { - PlaygroundTheme { + PlaygroundTheme(colors = themeColors) { Playground( modifier = Modifier.fillMaxSize(), activeTemplate = activeTemplate, onTemplateChange = { activeTemplate = it.copy() + }, + darkModeSupported = true, + darkMode = useDarkTheme, + onDarkModeChange = { + // TODO: Find out why toggling dark mode on or off doesn't work + useDarkTheme = it } ) } diff --git a/shared/src/commonMain/kotlin/ui/Playground.kt b/shared/src/commonMain/kotlin/ui/Playground.kt index 4c03355..316ffdb 100644 --- a/shared/src/commonMain/kotlin/ui/Playground.kt +++ b/shared/src/commonMain/kotlin/ui/Playground.kt @@ -25,7 +25,10 @@ import utils.calculateWindowSize fun Playground( modifier: Modifier = Modifier, activeTemplate: Template, - onTemplateChange: (Template) -> Unit + onTemplateChange: (Template) -> Unit, + darkModeSupported: Boolean = false, + darkMode: Boolean = false, + onDarkModeChange: (Boolean) -> Unit = { } ) { val density = LocalDensity.current val windowSize = calculateWindowSize() @@ -70,7 +73,10 @@ fun Playground( childModifiersList = childModifiersList, elementModifiersList = elementModifiersList, showCode = showCode, - onShowCode = { showCode = it } + onShowCode = { showCode = it }, + darkModeSupported = darkModeSupported, + darkMode = darkMode, + onDarkModeChange = onDarkModeChange ) if (showCode) { diff --git a/shared/src/commonMain/kotlin/ui/PreviewCanvas.kt b/shared/src/commonMain/kotlin/ui/PreviewCanvas.kt index 939e6ba..e438c99 100644 --- a/shared/src/commonMain/kotlin/ui/PreviewCanvas.kt +++ b/shared/src/commonMain/kotlin/ui/PreviewCanvas.kt @@ -6,6 +6,8 @@ import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Code import androidx.compose.material.icons.outlined.CodeOff +import androidx.compose.material.icons.outlined.DarkMode +import androidx.compose.material.icons.outlined.LightMode import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -25,7 +27,10 @@ fun PreviewCanvas( childModifiersList: List>>, elementModifiersList: List>, showCode: Boolean, - onShowCode: (Boolean) -> Unit + onShowCode: (Boolean) -> Unit, + darkModeSupported: Boolean, + darkMode: Boolean, + onDarkModeChange: (Boolean) -> Unit ) { Box( modifier = modifier, @@ -114,26 +119,54 @@ fun PreviewCanvas( } } - Surface( + Column( modifier = Modifier .align(Alignment.BottomEnd) - .padding(end = 8.dp, bottom = 8.dp) - .shadow(4.dp, shape = RoundedCornerShape(8.dp)) - .clip(RoundedCornerShape(8.dp)) - .size(32.dp), - elevation = 2.dp + .padding(end = 8.dp, bottom = 8.dp), + verticalArrangement = Arrangement.spacedBy(8.dp) ) { + // TODO: Figure out the design and placement for the dark mode toggle. + if (darkModeSupported) { + Surface( + modifier = Modifier + .shadow(4.dp, shape = RoundedCornerShape(8.dp)) + .clip(RoundedCornerShape(8.dp)) + .size(32.dp), + elevation = 2.dp + ) { + + IconButton( + onClick = { onDarkModeChange(!darkMode) } + ) { + Icon( + imageVector = if (darkMode) Icons.Outlined.LightMode else Icons.Outlined.DarkMode, + contentDescription = "Toggle dark mode on or off", + tint = LocalContentColor.current.copy(alpha = ContentAlpha.medium), + ) + } + } + } - IconButton( - onClick = { onShowCode(!showCode) } + Surface( + modifier = Modifier + .shadow(4.dp, shape = RoundedCornerShape(8.dp)) + .clip(RoundedCornerShape(8.dp)) + .size(32.dp), + elevation = 2.dp ) { - Icon( - imageVector = if (showCode) Icons.Outlined.CodeOff else Icons.Outlined.Code, - contentDescription = "Toggle code on or off", - tint = LocalContentColor.current.copy(alpha = ContentAlpha.medium), - ) + + IconButton( + onClick = { onShowCode(!showCode) } + ) { + Icon( + imageVector = if (showCode) Icons.Outlined.CodeOff else Icons.Outlined.Code, + contentDescription = "Toggle code on or off", + tint = LocalContentColor.current.copy(alpha = ContentAlpha.medium), + ) + } } } + } } diff --git a/shared/src/jsMain/kotlin/ui/controls/DropdownMenu.js.kt b/shared/src/jsMain/kotlin/ui/controls/DropdownMenu.js.kt index 368862b..73863a0 100644 --- a/shared/src/jsMain/kotlin/ui/controls/DropdownMenu.js.kt +++ b/shared/src/jsMain/kotlin/ui/controls/DropdownMenu.js.kt @@ -2,6 +2,7 @@ package ui.controls import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.MaterialTheme import androidx.compose.material.Surface import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -37,7 +38,7 @@ internal actual fun DropdownMenuEx( focusable = properties.focusable, ) { Surface( - color = Color.White, + color = MaterialTheme.colors.surface, elevation = 8.dp, shape = RoundedCornerShape(4.dp) ) {