Chunte's picture
Chunte HF Staff
Minimal UI: nav icons + motion pass (transitions-dev + apple-design), UX unchanged
e63a744 verified
Raw History Blame Contribute Delete
1.38 kB
"use client";
import { useSyncExternalStore } from "react";
import { THEME_STORAGE_KEY } from "./theme-init";
export type Theme = "light" | "dark";
function getTheme(): Theme {
return document.documentElement.classList.contains("dark") ? "dark" : "light";
}
function subscribe(onChange: () => void): () => void {
const observer = new MutationObserver(onChange);
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ["class"],
});
return () => observer.disconnect();
}
export function setTheme(theme: Theme) {
const root = document.documentElement;
// Flip every surface in the same frame: without this, 120ms control fades lag the canvas and
// charts, which re-theme instantly (see .theme-switching in globals.css).
root.classList.add("theme-switching");
root.classList.toggle("dark", theme === "dark");
void root.offsetWidth;
requestAnimationFrame(() => root.classList.remove("theme-switching"));
try {
localStorage.setItem(THEME_STORAGE_KEY, theme);
} catch {
// Storage blocked (private mode, embedded iframe): the choice lasts for this page only.
}
}
/** The current theme, for code that needs actual colours (Three.js) rather than CSS variables. */
export function useTheme(): Theme {
return useSyncExternalStore(subscribe, getTheme, () => "dark");
}