You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
38 lines
1.2 KiB
TypeScript
38 lines
1.2 KiB
TypeScript
/**
|
|
* Theme runtime: mode (light/dark) + accent, applied as data attributes on
|
|
* <html> and persisted. localStorage for now; these become user-scope settings
|
|
* rows once the DB layer lands (config-driven principle).
|
|
*/
|
|
export type ThemeMode = 'light' | 'dark'
|
|
|
|
export const ACCENTS = ['indigo', 'blue', 'emerald', 'violet', 'rose', 'amber'] as const
|
|
export type Accent = (typeof ACCENTS)[number]
|
|
|
|
const MODE_KEY = 'ui.themeMode'
|
|
const ACCENT_KEY = 'ui.accent'
|
|
|
|
export function getThemeMode(): ThemeMode {
|
|
return localStorage.getItem(MODE_KEY) === 'dark' ? 'dark' : 'light'
|
|
}
|
|
|
|
export function getAccent(): Accent {
|
|
const stored = localStorage.getItem(ACCENT_KEY)
|
|
return (ACCENTS as readonly string[]).includes(stored ?? '') ? (stored as Accent) : 'indigo'
|
|
}
|
|
|
|
export function setThemeMode(mode: ThemeMode): void {
|
|
localStorage.setItem(MODE_KEY, mode)
|
|
document.documentElement.dataset['theme'] = mode
|
|
}
|
|
|
|
export function setAccent(accent: Accent): void {
|
|
localStorage.setItem(ACCENT_KEY, accent)
|
|
document.documentElement.dataset['accent'] = accent
|
|
}
|
|
|
|
/** Call once before first render. */
|
|
export function initTheme(): void {
|
|
document.documentElement.dataset['theme'] = getThemeMode()
|
|
document.documentElement.dataset['accent'] = getAccent()
|
|
}
|