UNPKG

@dazl/color-scheme

Version:
90 lines 2.98 kB
function initiateColorScheme({ saveConfig, loadConfig, cssClass }) { const state = { listeners: new Set(), config: loadConfig(), }; const isDarkQuery = window.matchMedia('(prefers-color-scheme: dark)'); const resolveSystem = () => (isDarkQuery.matches ? 'dark' : 'light'); const onSystemChange = () => { if (state.config !== 'system') return; updateDocument(); }; const currentState = () => { const config = state.config; const resolved = config === 'system' ? resolveSystem() : config; return { config, resolved }; }; const updateDocument = () => { const current = currentState(); const root = document.documentElement; root.classList.remove(cssClass.light, cssClass.dark); root.classList.add(cssClass[current.resolved]); root.style.colorScheme = current.resolved === 'dark' ? 'dark' : 'light'; state.listeners.forEach((listener) => listener(current)); }; // set initial color scheme and listen for system changes updateDocument(); isDarkQuery.addEventListener('change', onSystemChange); return { get config() { return state.config; }, set config(config) { if (config === state.config) return; state.config = config; updateDocument(); saveConfig(config); }, get currentState() { return currentState(); }, get resolvedSystem() { return resolveSystem(); }, getRootCssClass(resolved = currentState().resolved) { return cssClass[resolved]; }, subscribe: (sub) => { state.listeners.add(sub); return () => { state.listeners.delete(sub); }; }, dispose: () => { state.listeners.clear(); isDarkQuery.removeEventListener('change', onSystemChange); }, }; } const storageKey = 'color-scheme'; const scriptDataset = document.currentScript?.dataset; const darkCssClass = scriptDataset?.darkClass || 'dark-theme'; const lightCssClass = scriptDataset?.lightClass || 'light-theme'; window.colorSchemeApi ??= initiateColorScheme({ loadConfig() { try { const config = localStorage.getItem(storageKey); return config === 'light' || config === 'dark' ? config : 'system'; } catch { return 'system'; } }, saveConfig(config) { try { if (config === 'system') { localStorage.removeItem(storageKey); } else { localStorage.setItem(storageKey, config); } } catch { // Fallback to no-op if localStorage is not available } }, cssClass: { light: lightCssClass, dark: darkCssClass }, }); //# sourceMappingURL=client.js.map