Spaces:
Sleeping
Sleeping
File size: 1,554 Bytes
e327f0d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | /**
* Theme management — `light` | `dark` | `system`.
*
* Applies the `dark` class to `<html>` so Tailwind's `dark:` variants kick in.
* Subscribes to `prefers-color-scheme` while in `system` mode and updates live.
*/
export type ThemeMode = 'light' | 'dark' | 'system';
const MEDIA = '(prefers-color-scheme: dark)';
function systemPrefersDark(): boolean {
if (typeof window === 'undefined') return false;
return window.matchMedia(MEDIA).matches;
}
function applyClass(isDark: boolean) {
if (typeof document === 'undefined') return;
document.documentElement.classList.toggle('dark', isDark);
document.documentElement.style.colorScheme = isDark ? 'dark' : 'light';
}
let currentMode: ThemeMode = 'system';
let mediaListener: ((e: MediaQueryListEvent) => void) | null = null;
export function applyTheme(mode: ThemeMode): void {
currentMode = mode;
if (typeof window !== 'undefined' && mediaListener) {
window.matchMedia(MEDIA).removeEventListener('change', mediaListener);
mediaListener = null;
}
if (mode === 'system') {
applyClass(systemPrefersDark());
if (typeof window !== 'undefined') {
mediaListener = (e) => applyClass(e.matches);
window.matchMedia(MEDIA).addEventListener('change', mediaListener);
}
} else {
applyClass(mode === 'dark');
}
}
export function getCurrentMode(): ThemeMode {
return currentMode;
}
export function isCurrentlyDark(): boolean {
if (typeof document === 'undefined') return false;
return document.documentElement.classList.contains('dark');
}
|