import { type Theme, themeIcon } from "./shared"; // Progressive enhancement for the theme toggle. The server already rendered the // correct theme (data-theme + the dark sheet's media), so there's nothing to do // on load — we only intercept the toggle form to switch instantly without the // full-page reload the no-JS POST would cause, and keep the cookie in sync. const order: Theme[] = ["auto", "light", "dark"]; function current(): Theme { const value = document.documentElement.dataset.theme; return value === "light" || value === "dark" ? value : "auto"; } function apply(theme: Theme) { document.documentElement.dataset.theme = theme; const darkMedia = theme === "auto" ? "(prefers-color-scheme: dark)" : theme === "dark" ? "all" : "not all"; // Swap both dark sheets in lockstep: sakura (page chrome) and highlight.js // (code syntax). Each is null on pages that don't include it. for (const id of ["sakura-dark", "highlight-dark"]) { const sheet = document.getElementById(id) as HTMLLinkElement | null; if (sheet) sheet.media = darkMedia; } const button = document.getElementById("theme-toggle"); if (button) button.innerHTML = themeIcon(theme); // biome-ignore lint/suspicious/noDocumentCookie: a single non-HttpOnly cookie write; the async Cookie Store API isn't worth the complexity (or its weaker browser support) here document.cookie = `zbin-theme=${theme}; path=/; max-age=31536000; samesite=lax`; } document.getElementById("theme-form")?.addEventListener("submit", (e) => { e.preventDefault(); apply(order[(order.indexOf(current()) + 1) % order.length]); });