Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Dark Theme on Web #7

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion jsApp/src/jsMain/kotlin/main.js.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
Expand All @@ -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() {
Expand All @@ -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
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I was able isolate what the issue is. It's with TextField. You can repro with this snippet:

image

So likely a thing to go investigate with JetBrains.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is quite surprising. I recreated something similar to your example. From what I was able to test, the issue with TextField only happened after I added a Surface. But then I replaced the Surface with the .background modifier on Column, and this specific issue didn't seem to happen anymore. There are other issues, but toggling still works nonetheless when using .background for some reason.

useDarkTheme = it
}
)
}
Expand Down
10 changes: 8 additions & 2 deletions shared/src/commonMain/kotlin/ui/Playground.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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) {
Expand Down
61 changes: 47 additions & 14 deletions shared/src/commonMain/kotlin/ui/PreviewCanvas.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -25,7 +27,10 @@ fun PreviewCanvas(
childModifiersList: List<List<Pair<Any, Boolean>>>,
elementModifiersList: List<Pair<Any, Boolean>>,
showCode: Boolean,
onShowCode: (Boolean) -> Unit
onShowCode: (Boolean) -> Unit,
darkModeSupported: Boolean,
darkMode: Boolean,
onDarkModeChange: (Boolean) -> Unit
) {
Box(
modifier = modifier,
Expand Down Expand Up @@ -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),
)
}
}
}

}
}

Expand Down
3 changes: 2 additions & 1 deletion shared/src/jsMain/kotlin/ui/controls/DropdownMenu.js.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
) {
Expand Down