import { useThemePreference } from '@/app/(protected)/(basic)/_hooks/use-theme-preference'; import { IconButton } from '@/components/ui/icon-button'; import { MonitorIcon } from '@/components/ui/icons/monitor-icon'; import { MoonIcon } from '@/components/ui/icons/moon-icon'; import { SunIcon } from '@/components/ui/icons/sun-icon'; /** * 헤더 우측 테마 토글 버튼 — 아이콘 3종(모니터/해/달)을 항상 DOM에 전부 렌더하고, design이 * globals.css에 정의한 `theme-system`/`theme-light`/`theme-dark` 커스텀 variant가 `` 값에 따라 CSS만으로 하나만 보이게 한다. 서버·클라이언트 출력이 항상 동일해 * hydration 불일치가 없다 — React state로 아이콘을 고르지 않는다(계획 §4-4, §10 게이트 확정). * * 아이콘·라벨 쌍을 감싸는 `` 래퍼에 표시 전환을 * 건다(아이콘 자체나 `sr-only` 라벨 각각에 개별로 걸지 않는다) — `display: contents`는 자신의 * 박스를 없애는 것이라, `sr-only`의 clip 기법이 의존하는 박스 자체가 있는 요소(라벨 span)에 * 직접 걸면 클리핑이 무효화돼 텍스트가 그대로 노출된다. 래퍼는 그 자신의 박스만 지우고 * 자식(아이콘의 내부 span, 라벨 span)은 각자의 박스를 그대로 유지하므로 안전하다. 아이콘 * 컴포넌트에는 `className`을 넘기지 않는다 — svg가 아니라 이 래퍼가 표시를 전담한다. */ export function ThemeToggleButton() { const { cycleThemePreference } = useThemePreference(); return ( 테마 변경 (현재: 시스템 설정) 테마 변경 (현재: 라이트) 테마 변경 (현재: 다크) ); }