Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | 1x 126x 19x 2x 17x 41x 17x 24x 19x 1x 18x 18x 18x 1x 17x 15x 1x 14x 14x 36x 5x 31x | import type { DarkModeMode } from "./types";
const DARK_QUERY = "(prefers-color-scheme: dark)";
/**
* Whether we're running in a browser environment.
*/
export function isBrowser(): boolean {
return typeof window !== "undefined";
}
/**
* Whether the OS currently prefers a dark color scheme. Returns `false` in SSR
* or when `matchMedia` is unavailable.
*/
export function prefersDark(): boolean {
if (!isBrowser() || typeof window.matchMedia !== "function") {
return false;
}
return window.matchMedia(DARK_QUERY).matches;
}
/**
* Resolve the effective dark state from a mode and the system preference.
*
* @example
* ```ts
* resolveIsDark("system", true); // true
* resolveIsDark("light", true); // false
* ```
*/
export function resolveIsDark(mode: DarkModeMode, systemDark: boolean): boolean {
if (mode === "system") {
return systemDark;
}
return mode === "dark";
}
/**
* Read the persisted mode from storage, falling back to `fallback` when absent,
* invalid, or inaccessible.
*/
export function readStoredMode(
storageKey: string,
fallback: DarkModeMode
): DarkModeMode {
if (!isBrowser()) {
return fallback;
}
try {
const raw = window.localStorage.getItem(storageKey);
if (raw === "system" || raw === "light" || raw === "dark") {
return raw;
}
} catch {
// Access can throw (privacy mode, disabled storage) — fall through.
}
return fallback;
}
/**
* Persist the mode to storage, ignoring failures (quota, disabled storage).
*/
export function writeStoredMode(storageKey: string, mode: DarkModeMode): void {
if (!isBrowser()) {
return;
}
try {
window.localStorage.setItem(storageKey, mode);
} catch {
// Ignore write failures.
}
}
/**
* Apply the theme to an element — either as an attribute or a toggled class.
*/
export function applyTheme(
element: HTMLElement,
isDark: boolean,
attribute: string | undefined,
darkClass: string
): void {
if (attribute) {
element.setAttribute(attribute, isDark ? "dark" : "light");
} else {
element.classList.toggle(darkClass, isDark);
}
}
|