File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
08-19
"use client";
import { useSyncExternalStore } from "react";
import { FoxSegmentedControl } from "../core/components/fox-segmented-control";
import { FoxSegmentedControlItem } from "../core/components/fox-segmented-control-item";
const THEME_ATTRIBUTE = "data-theme";
type ThemeChoice = "system" | "light" | "dark";
const CHOICES: { value: ThemeChoice; label: string }[] = [
{ value: "system", label: "시스템" },
{ value: "light", label: "라이트" },
{ value: "dark", label: "다크" },
];
function subscribe(onChange: () => void): () => void {
const observer = new MutationObserver(onChange);
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: [THEME_ATTRIBUTE],
});
return () => observer.disconnect();
}
function getSnapshot(): ThemeChoice {
const value = document.documentElement.getAttribute(THEME_ATTRIBUTE);
return value === "light" || value === "dark" ? value : "system";
}
function getServerSnapshot(): ThemeChoice {
return "system";
}
function apply(next: ThemeChoice): void {
const root = document.documentElement;
if (next === "system") {
root.removeAttribute(THEME_ATTRIBUTE);
} else {
root.setAttribute(THEME_ATTRIBUTE, next);
}
}
export function ThemeSwitch() {
const current = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
return (
<FoxSegmentedControl size="sm" name="dev-test-theme" label="테마 전환">
{CHOICES.map(({ value, label }) => (
<FoxSegmentedControlItem
key={value}
value={value}
label={label}
checked={current === value}
onChange={(next) => apply(next as ThemeChoice)}
/>
))}
</FoxSegmentedControl>
);
}