From 56dbdfeb3a67825d36cfae5258ec72fda149e64a Mon Sep 17 00:00:00 2001 From: David Herman Date: Sat, 14 Dec 2024 22:03:38 -0800 Subject: [PATCH] Add `color-theme` support to silk This ensures that Silk sites will update the browser UI affordances that surround the site when the theme changes. Fixes #627 --- .../kobweb/silk/theme/meta/MetaThemeColor.kt | 46 +++++++++++++++++++ .../theme/colors/palette/MetaThemeColor.kt | 11 +++++ .../playground/{MyApp.kt => AppEntry.kt} | 3 ++ 3 files changed, 60 insertions(+) create mode 100644 frontend/silk-foundation/src/jsMain/kotlin/com/varabyte/kobweb/silk/theme/meta/MetaThemeColor.kt create mode 100644 frontend/silk-widgets/src/jsMain/kotlin/com/varabyte/kobweb/silk/theme/colors/palette/MetaThemeColor.kt rename playground/site/src/jsMain/kotlin/playground/{MyApp.kt => AppEntry.kt} (97%) diff --git a/frontend/silk-foundation/src/jsMain/kotlin/com/varabyte/kobweb/silk/theme/meta/MetaThemeColor.kt b/frontend/silk-foundation/src/jsMain/kotlin/com/varabyte/kobweb/silk/theme/meta/MetaThemeColor.kt new file mode 100644 index 000000000..5e4d26aba --- /dev/null +++ b/frontend/silk-foundation/src/jsMain/kotlin/com/varabyte/kobweb/silk/theme/meta/MetaThemeColor.kt @@ -0,0 +1,46 @@ +package com.varabyte.kobweb.silk.theme.meta + +import androidx.compose.runtime.* +import com.varabyte.kobweb.silk.theme.colors.ColorMode +import kotlinx.browser.document +import org.jetbrains.compose.web.css.* + +@Composable +fun MetaThemeColor(color: CSSColorValue) = MetaThemeColor(color, color) + +@Composable +fun MetaThemeColor(light: CSSColorValue, dark: CSSColorValue) { + run { + // Add the following entries to the element + // + // + // + // + // + // The color-scheme value will be updated dynamically based on + LaunchedEffect(Unit) { + val themeColorElements = document.querySelectorAll("""meta[name="theme-color"]""") + if (themeColorElements.length == 0) { + ColorMode.entries.toList().forEach { colorMode -> + document.createElement("meta").apply { + setAttribute("name", "theme-color") + setAttribute("media", "(prefers-color-scheme: ${colorMode.name.lowercase()})") + setAttribute("content", (if (colorMode.isLight) light else dark).toString()) + }.also { document.head!!.appendChild(it) } + } + } + } + + val colorMode = ColorMode.current + LaunchedEffect(colorMode) { + var colorSchemeElement = document.querySelector("""meta[name="color-scheme"]""") + if (colorSchemeElement == null) { + colorSchemeElement = document.createElement("meta").apply { + setAttribute("name", "color-scheme") + }.also { document.head!!.appendChild(it) } + } + colorSchemeElement.setAttribute("content", colorMode.name.lowercase()) + } + } + +} \ No newline at end of file diff --git a/frontend/silk-widgets/src/jsMain/kotlin/com/varabyte/kobweb/silk/theme/colors/palette/MetaThemeColor.kt b/frontend/silk-widgets/src/jsMain/kotlin/com/varabyte/kobweb/silk/theme/colors/palette/MetaThemeColor.kt new file mode 100644 index 000000000..71cf1c954 --- /dev/null +++ b/frontend/silk-widgets/src/jsMain/kotlin/com/varabyte/kobweb/silk/theme/colors/palette/MetaThemeColor.kt @@ -0,0 +1,11 @@ +package com.varabyte.kobweb.silk.theme.meta + +import androidx.compose.runtime.* +import com.varabyte.kobweb.silk.theme.colors.ColorMode +import com.varabyte.kobweb.silk.theme.colors.palette.background +import com.varabyte.kobweb.silk.theme.colors.palette.toPalette + +@Composable +fun MetaThemeColor() { + MetaThemeColor(ColorMode.LIGHT.toPalette().background, ColorMode.DARK.toPalette().background) +} \ No newline at end of file diff --git a/playground/site/src/jsMain/kotlin/playground/MyApp.kt b/playground/site/src/jsMain/kotlin/playground/AppEntry.kt similarity index 97% rename from playground/site/src/jsMain/kotlin/playground/MyApp.kt rename to playground/site/src/jsMain/kotlin/playground/AppEntry.kt index fd06759c2..8be7e3160 100644 --- a/playground/site/src/jsMain/kotlin/playground/MyApp.kt +++ b/playground/site/src/jsMain/kotlin/playground/AppEntry.kt @@ -19,6 +19,7 @@ import com.varabyte.kobweb.silk.style.common.SmoothColorStyle import com.varabyte.kobweb.silk.style.toModifier import com.varabyte.kobweb.silk.theme.colors.ColorMode import com.varabyte.kobweb.silk.theme.colors.systemPreference +import com.varabyte.kobweb.silk.theme.meta.MetaThemeColor import kotlinx.browser.localStorage import org.jetbrains.compose.web.css.* @@ -72,6 +73,8 @@ fun registerGlobalStyles(ctx: InitSilkContext) = ctx.stylesheet.apply { @Composable fun AppEntry(content: @Composable () -> Unit) { SilkApp { + MetaThemeColor() + val colorMode = ColorMode.current LaunchedEffect(colorMode) { localStorage.setItem(COLOR_MODE_KEY, colorMode) }