1import { $$, asElement, storage } from "./dom";
2
3const STORAGE_KEY = "preferred-theme";
4
5type Theme = "light" | "dark";
6
7const systemTheme = (): Theme =>
8 window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
9
10const applyTheme = (theme: Theme): void => {
11 document.documentElement.dataset.theme = theme;
12};
13
14const syncSwitcher = (theme: Theme): void => {
15 $$("[data-theme-label]").forEach((el) => {
16 el.textContent = theme;
17 });
18};
19
20/** Apply the stored (or system) theme and reflect it on the switcher. */
21export const initTheme = (): void => {
22 const stored = storage?.getItem(STORAGE_KEY);
23 const theme: Theme = stored === "light" || stored === "dark" ? stored : systemTheme();
24 applyTheme(theme);
25 syncSwitcher(theme);
26};
27
28/**
29 * Wire the theme switchers. Bound once for the session: a delegated document
30 * listener keeps every switcher working — the mobile-menu copy lives in the
31 * header, which the router replaces on each swap. Each click toggles light/dark.
32 */
33export const bindThemeControls = (): void => {
34 document.addEventListener("click", (e) => {
35 if (!asElement(e.target)?.closest(".theme-switcher")) return;
36 const theme: Theme =
37 document.documentElement.dataset.theme === "dark" ? "light" : "dark";
38 applyTheme(theme);
39 syncSwitcher(theme);
40 storage?.setItem(STORAGE_KEY, theme);
41 });
42};