Files
bsky-social-app/src/alf/util/useColorModeTheme.ts
T
2026-08-25 09:40:14 +03:00

65 lines
1.7 KiB
TypeScript

import {useLayoutEffect} from 'react'
import {type ColorSchemeName, useColorScheme} from 'react-native'
import {type ThemeName} from '@bsky.app/alf'
import {useThemePrefs} from '#/state/shell'
import {dark, dim, light} from '#/alf/themes'
import {IS_WEB} from '#/env'
export function useColorModeTheme(): ThemeName {
const theme = useThemeName()
useLayoutEffect(() => {
updateDocument(theme)
}, [theme])
return theme
}
export function useThemeName(): ThemeName {
const colorScheme = useColorScheme()
const {colorMode, darkTheme} = useThemePrefs()
return getThemeName(colorScheme, colorMode, darkTheme)
}
function getThemeName(
colorScheme: ColorSchemeName | null | undefined,
colorMode: 'system' | 'light' | 'dark',
darkTheme?: ThemeName,
) {
if (
(colorMode === 'system' && colorScheme === 'light') ||
colorMode === 'light'
) {
return 'light'
} else {
return darkTheme ?? 'dim'
}
}
function updateDocument(theme: ThemeName) {
if (IS_WEB && typeof window !== 'undefined') {
const html = window.document.documentElement
const meta = window.document.querySelector('meta[name="theme-color"]')
// remove any other color mode classes
html.className = html.className.replace(/(theme)--\w+/g, '')
html.classList.add(`theme--${theme}`)
// set color to 'theme-color' meta tag
meta?.setAttribute('content', getBackgroundColor(theme))
window.localStorage.setItem('ALF_THEME', theme)
}
}
export function getBackgroundColor(theme: ThemeName): string {
switch (theme) {
case 'light':
return light.atoms.bg.backgroundColor
case 'dark':
return dark.atoms.bg.backgroundColor
case 'dim':
return dim.atoms.bg.backgroundColor
}
}