Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/frontend/packages/shared/src/settings/theme-apply.ts
atlas 39b95c2ede treefmt: apply prettier
Pure `nix fmt` output from the commit before this one — no hand edits.
203 files: 52 md, 42 tsx, 32 js, 32 css, 21 ts, 13 html, 8 json, 3 mjs.

Reproduce with `nix develop -c nix fmt` on the parent commit; the result
should be byte-identical to this tree.

None of the 13 `.prettierignore` entries appears here — verified by
intersecting the changed-file list against the ignore file, with a
control proving the intersection finds a match when one exists.
2026-09-02 15:25:07 +02:00

46 lines
1.9 KiB
TypeScript

// Applies a stored theme override by setting `data-theme="light"|"dark"`
// on `<html>`, cleared when the override is "system" (letting the
// `prefers-color-scheme` media query in `./colors.css` resume control).
// No palette values live here — `colors.css`'s own
// `:root[data-theme='light']` / `:root[data-theme='dark']` blocks are
// what actually apply the colours.
//
// Callers own their own storage key (kept in their own small constant,
// not derived here) so two pages never silently share one browser-local
// setting by accident. `fallback` defaults to `'dark'`: `prefers-color-
// scheme` has no real "unset" value the way `prefers-reduced-motion`
// does, so a browser with no explicit dark-mode toggle reports `light`
// — `'system'` as a default silently reads as light-by-default for most
// first-time visitors (mara: "light mode seems to be default"). Still
// fully overridable per caller if a page ever wants a different default.
import { useEffect } from "preact/hooks";
import { useLocalSetting } from "./settings-storage.js";
export type ThemeOverride = "system" | "light" | "dark";
export function useThemeOverride(
key: string,
fallback: ThemeOverride = "dark",
) {
return useLocalSetting<ThemeOverride>(key, fallback);
}
// Mounted once, high in the tree — one mount point applies the override
// regardless of what else is rendering, and `useLocalSetting`'s
// same-tab subscription means `SettingsMenu` changing the value re-runs
// this effect without either component needing to know about the other
// directly.
export function useApplyThemeOverride(
key: string,
fallback: ThemeOverride = "dark",
): void {
const [override] = useThemeOverride(key, fallback);
useEffect(() => {
const root = document.documentElement;
if (override === "system") {
delete root.dataset.theme;
} else {
root.dataset.theme = override;
}
}, [override]);
}