"use client"; import { useSyncExternalStore } from "react"; import styles from "./dev-test.module.scss"; /** `@fox/styles/_root.scss`가 읽는 수동 테마 선택 속성. */ 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: "다크" }, ]; /** * ``가 SSOT라 React state를 두지 않는다. 저장 키는 호스트 앱이 * 소유하는 값이라 `@fox`가 알면 포터빌리티가 깨지므로 선택을 저장하지 않는다. */ 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 (