MCPcopy Create free account
hub / github.com/codename-co/stack / DarkModeSwitcher

Function DarkModeSwitcher

packages/website/src/components/DarkModeSwitcher.tsx:5–79  ·  view source on GitHub ↗
({
  children,
})

Source from the content-addressed store, hash-verified

3import { Button } from "performative-ui";
4
5type Theme = "light" | "dark" | "system";
6
7/**
8 * Two consumers, one decision: Tailwind switches on the `.dark` class,
9 * performative-ui switches on `[data-theme]`. Everything below writes both,
10 * always, so a component can never render in the opposite palette to the page
11 * it sits on.
12 */
13const paint = (dark: boolean) => {
14 const root = document.documentElement;
15 root.classList.toggle("dark", dark);
16 root.setAttribute("data-theme", dark ? "dark" : "light");
17};
18
19const systemPrefersDark = () =>
20 window.matchMedia("(prefers-color-scheme: dark)").matches;
21
22const SunIcon = () => (
23 <svg
24 className="stroke-current w-4 h-4 inline align-middle"
25 xmlns="http://www.w3.org/2000/svg"
26 viewBox="0 0 24 24"
27 fill="none"
28 stroke-width="2"
29 stroke-linecap="round"
30 aria-hidden="true"
31 >
32 <circle cx="12" cy="12" r="4" />
33 <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41" />
34 </svg>
35);
36
37const MoonIcon = () => (
38 <svg
39 className="stroke-current w-4 h-4 inline align-middle"
40 xmlns="http://www.w3.org/2000/svg"
41 viewBox="0 0 24 24"
42 fill="none"
43 stroke-width="2"
44 stroke-linecap="round"
45 stroke-linejoin="round"
46 aria-hidden="true"
47 >
48 <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
49 </svg>
50);
51
52export const DarkModeSwitcher: React.FC<{ children?: any }> = ({
53 children,
54}) => {
55 const [activeTheme, setActiveTheme] = useState<Theme>("system");
56
57 useEffect(() => {
58 const savedTheme = (localStorage.getItem("theme") as Theme) || "system";
59 setActiveTheme(savedTheme);
60 paint(savedTheme === "system" ? systemPrefersDark() : savedTheme === "dark");
61
62 const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");

Callers

nothing calls this directly

Calls 3

applySystemThemeFunction · 0.85
applyThemeFunction · 0.85
switchThemeFunction · 0.85

Tested by

no test coverage detected