diff options
author | Hailey <me@haileyok.com> | 2024-02-06 11:43:51 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-06 11:43:51 -0800 |
commit | ec86282403ea34704d0faab7b04ca033bd3a0650 (patch) | |
tree | ca5881ada59d7ad634bd799efe3c751a4c5509d2 /src/alf | |
parent | 856f80fc6df731b1dbe9efa289ad6a4f728d4e0d (diff) | |
download | voidsky-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.ts | 85 | ||||
-rw-r--r-- | src/alf/util/useColorModeTheme.ts | 54 |
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 + } } |