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