UNPKG

mode-watcher

Version:

SSR-friendly light and dark mode for SvelteKit

61 lines (60 loc) 2.64 kB
import { get } from "svelte/store"; import { derivedMode, derivedTheme, disableTransitions, modeStorageKey, systemPrefersMode, themeColors, themeStorageKey, theme as themeStore, userPrefersMode, } from "./stores.js"; /** Toggle between light and dark mode */ export function toggleMode() { userPrefersMode.set(get(derivedMode) === "dark" ? "light" : "dark"); } /** Set the mode to light or dark */ export function setMode(mode) { userPrefersMode.set(mode); } /** Reset the mode to operating system preference */ export function resetMode() { userPrefersMode.set("system"); } /** Set the theme to a custom value */ export function setTheme(theme) { themeStore.set(theme); } export function defineConfig(config) { return config; } /** Used to set the mode on initial page load to prevent FOUC */ export function setInitialMode({ defaultMode = "system", themeColors, darkClassNames = ["dark"], lightClassNames = [], defaultTheme = "", modeStorageKey = "mode-watcher-mode", themeStorageKey = "mode-watcher-theme", }) { const rootEl = document.documentElement; const mode = localStorage.getItem(modeStorageKey) || defaultMode; const theme = localStorage.getItem(themeStorageKey) || defaultTheme; const light = mode === "light" || (mode === "system" && window.matchMedia("(prefers-color-scheme: light)").matches); if (light) { if (darkClassNames.length) rootEl.classList.remove(...darkClassNames); if (lightClassNames.length) rootEl.classList.add(...lightClassNames); } else { if (lightClassNames.length) rootEl.classList.remove(...lightClassNames); if (darkClassNames.length) rootEl.classList.add(...darkClassNames); } rootEl.style.colorScheme = light ? "light" : "dark"; if (themeColors) { const themeMetaEl = document.querySelector('meta[name="theme-color"]'); if (themeMetaEl) { themeMetaEl.setAttribute("content", mode === "light" ? themeColors.light : themeColors.dark); } } if (theme) { rootEl.setAttribute("data-theme", theme); localStorage.setItem(themeStorageKey, theme); } localStorage.setItem(modeStorageKey, mode); } /** * A type-safe way to generate the source expression used to set the initial mode and avoid FOUC. */ export function generateSetInitialModeExpression(config = {}) { return `(${setInitialMode.toString()})(${JSON.stringify(config)});`; } export { modeStorageKey, themeStorageKey, derivedTheme as theme, userPrefersMode, systemPrefersMode, derivedMode as mode, themeColors, disableTransitions, };