about summary refs log tree commit diff
path: root/src/alf
diff options
context:
space:
mode:
authorHailey <me@haileyok.com>2024-02-06 11:43:51 -0800
committerGitHub <noreply@github.com>2024-02-06 11:43:51 -0800
commitec86282403ea34704d0faab7b04ca033bd3a0650 (patch)
treeca5881ada59d7ad634bd799efe3c751a4c5509d2 /src/alf
parent856f80fc6df731b1dbe9efa289ad6a4f728d4e0d (diff)
downloadvoidsky-ec86282403ea34704d0faab7b04ca033bd3a0650.tar.zst
Options for selecting dark theme, fix some white flashes when in dark mode (#2722)
* add dark theme selection to settings/schema

* use `useThemePrefs` where needed

* adjust theme providers to support various themes

* update storybook

* handle web themes

* better themeing for web

* dont show dark theme prefs when color mode is light

* drop the inverted text change on oled theme

* get the color mode inside of `useColorModeTheme`

* use `ThemeName` type everywhere

* typo

* use dim/dark instead of dark/oled

* prevent any fickers on web

* fix styles

* use `dim` for dark default

* more cleanup

* 🤔

* set system background color

* ts
Diffstat (limited to 'src/alf')
-rw-r--r--src/alf/themes.ts85
-rw-r--r--src/alf/util/useColorModeTheme.ts54
2 files changed, 69 insertions, 70 deletions
diff --git a/src/alf/themes.ts b/src/alf/themes.ts
index 7c6b7dab4..b36e782fd 100644
--- a/src/alf/themes.ts
+++ b/src/alf/themes.ts
@@ -71,7 +71,7 @@ export const lightPalette = {
 
 export const darkPalette: Palette = {
   white: tokens.color.gray_0,
-  black: tokens.color.gray_1000,
+  black: tokens.color.trueBlack,
 
   contrast_25: tokens.color.gray_975,
   contrast_50: tokens.color.gray_950,
@@ -130,6 +130,11 @@ export const darkPalette: Palette = {
   negative_975: tokens.color.red_975,
 } as const
 
+export const dimPalette: Palette = {
+  ...darkPalette,
+  black: tokens.color.gray_1000,
+} as const
+
 export const light = {
   name: 'light',
   palette: lightPalette,
@@ -191,70 +196,6 @@ export const light = {
   },
 }
 
-export const dim: Theme = {
-  name: 'dim',
-  palette: darkPalette,
-  atoms: {
-    text: {
-      color: darkPalette.white,
-    },
-    text_contrast_700: {
-      color: darkPalette.contrast_800,
-    },
-    text_contrast_600: {
-      color: darkPalette.contrast_700,
-    },
-    text_contrast_500: {
-      color: darkPalette.contrast_600,
-    },
-    text_contrast_400: {
-      color: darkPalette.contrast_500,
-    },
-    text_inverted: {
-      color: darkPalette.black,
-    },
-    bg: {
-      backgroundColor: darkPalette.contrast_50,
-    },
-    bg_contrast_25: {
-      backgroundColor: darkPalette.contrast_100,
-    },
-    bg_contrast_50: {
-      backgroundColor: darkPalette.contrast_200,
-    },
-    bg_contrast_100: {
-      backgroundColor: darkPalette.contrast_300,
-    },
-    bg_contrast_200: {
-      backgroundColor: darkPalette.contrast_400,
-    },
-    bg_contrast_300: {
-      backgroundColor: darkPalette.contrast_500,
-    },
-    border: {
-      borderColor: darkPalette.contrast_200,
-    },
-    border_contrast: {
-      borderColor: darkPalette.contrast_400,
-    },
-    shadow_sm: {
-      ...atoms.shadow_sm,
-      shadowOpacity: 0.7,
-      shadowColor: tokens.color.trueBlack,
-    },
-    shadow_md: {
-      ...atoms.shadow_md,
-      shadowOpacity: 0.7,
-      shadowColor: tokens.color.trueBlack,
-    },
-    shadow_lg: {
-      ...atoms.shadow_lg,
-      shadowOpacity: 0.7,
-      shadowColor: tokens.color.trueBlack,
-    },
-  },
-}
-
 export const dark: Theme = {
   name: 'dark',
   palette: darkPalette,
@@ -318,3 +259,17 @@ export const dark: Theme = {
     },
   },
 }
+
+export const dim: Theme = {
+  ...dark,
+  name: 'dim',
+  atoms: {
+    ...dark.atoms,
+    text_inverted: {
+      color: dimPalette.black,
+    },
+    bg: {
+      backgroundColor: dimPalette.black,
+    },
+  },
+}
diff --git a/src/alf/util/useColorModeTheme.ts b/src/alf/util/useColorModeTheme.ts
index 79cebc139..49e2ec8f5 100644
--- a/src/alf/util/useColorModeTheme.ts
+++ b/src/alf/util/useColorModeTheme.ts
@@ -1,10 +1,54 @@
+import React from 'react'
 import {useColorScheme} from 'react-native'
 
-import * as persisted from '#/state/persisted'
+import {useThemePrefs} from 'state/shell'
+import {isWeb} from 'platform/detection'
+import {ThemeName, light, dark, dim} from '#/alf/themes'
+import * as SystemUI from 'expo-system-ui'
 
-export function useColorModeTheme(
-  theme: persisted.Schema['colorMode'],
-): 'light' | 'dark' {
+export function useColorModeTheme(): ThemeName {
   const colorScheme = useColorScheme()
-  return (theme === 'system' ? colorScheme : theme) || 'light'
+  const {colorMode, darkTheme} = useThemePrefs()
+
+  return React.useMemo(() => {
+    if (
+      (colorMode === 'system' && colorScheme === 'light') ||
+      colorMode === 'light'
+    ) {
+      updateDocument('light')
+      updateSystemBackground('light')
+      return 'light'
+    } else {
+      const themeName = darkTheme ?? 'dim'
+      updateDocument(themeName)
+      updateSystemBackground(themeName)
+      return themeName
+    }
+  }, [colorMode, darkTheme, colorScheme])
+}
+
+function updateDocument(theme: ThemeName) {
+  // @ts-ignore web only
+  if (isWeb && typeof window !== 'undefined') {
+    // @ts-ignore web only
+    const html = window.document.documentElement
+    // remove any other color mode classes
+    html.className = html.className.replace(/(theme)--\w+/g, '')
+
+    html.classList.add(`theme--${theme}`)
+  }
+}
+
+function updateSystemBackground(theme: ThemeName) {
+  switch (theme) {
+    case 'light':
+      SystemUI.setBackgroundColorAsync(light.atoms.bg.backgroundColor)
+      break
+    case 'dark':
+      SystemUI.setBackgroundColorAsync(dark.atoms.bg.backgroundColor)
+      break
+    case 'dim':
+      SystemUI.setBackgroundColorAsync(dim.atoms.bg.backgroundColor)
+      break
+  }
 }