Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/MaxwellCohen/solid-free-chat.
Something went wrong. Try again.
2.1 kB · 73 lines
TypeScript
at main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374import { createEffect, createMemo, createSignal, onSettled } from 'solid-js'import type { Accessor } from 'solid-js'
import type { ThemeContextValue } from './theme-context'import { readStoredPreference, resolveEffectiveTheme, THEME_STORAGE_KEY, writeStoredPreference,} from './theme-preference'import type { ThemePreference } from './theme-preference'
export function createThemeController(): ThemeContextValue & { htmlClass: Accessor<string>} { const [preference, setPreferenceState] = createSignal<ThemePreference>( typeof window === 'undefined' ? 'system' : readStoredPreference(), )
const [systemDark, setSystemDark] = createSignal( typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches, )
const effective = createMemo(() => resolveEffectiveTheme(preference(), systemDark()), )
const htmlClass = createMemo(() => (effective() === 'dark' ? 'dark' : ''))
const setPreference = (pref: ThemePreference) => { setPreferenceState(pref) writeStoredPreference(pref) }
onSettled(() => { if (typeof window === 'undefined') return const mq = window.matchMedia('(prefers-color-scheme: dark)') const onChange = (e: MediaQueryListEvent) => setSystemDark(e.matches) mq.addEventListener('change', onChange)
const fromStorage = readStoredPreference() if (fromStorage !== preference()) { setPreferenceState(fromStorage) }
const onStorage = (e: StorageEvent) => { if (e.key !== null && e.key !== THEME_STORAGE_KEY) return setPreferenceState(readStoredPreference()) } window.addEventListener('storage', onStorage)
return () => { mq.removeEventListener('change', onChange) window.removeEventListener('storage', onStorage) } })
createEffect( () => effective() === 'dark', (dark) => { if (typeof document === 'undefined') return document.documentElement.style.colorScheme = dark ? 'dark' : 'light' }, )
return { preference, setPreference, effective, htmlClass, }}