본문으로 건너뛰기
유틸리티 / theme-toggle

ThemeToggle

light / system / dark 전환 컨트롤 — useTheme 위의 얇은 UI.
유틸리티theme-toggleStatic specimentheme toggle테마다크 모드light dark system
01 · Specimen

먼저 보고, 그다음 계약을 읽습니다

light / system / dark 전환 컨트롤 — useTheme 위의 얇은 UI.

Workbench 불러오는 중…
Component intent의도와 경계 읽기

라이트/시스템/다크 테마를 고르는 컨트롤. useTheme 을 통해 storage·DOM 반영을 ThemeProvider 에 위임하므로 항상 동기화된다(design 페이지가 documentElement 를 직접 만지던 버그를 SSOT 로 흡수). mode="segment"(기본) 는 3-버튼 segmented(활성=primary), mode="cycle" 은 단일 버튼이 light → system → dark 를 순환한다. 아이콘은 inline SVG(외부 아이콘 dep 0)로 currentColor 를 따라간다. 내부 버튼은 @axe/ui Button 을 재사용한다.

02 · Use

예제

SSOT에 등록된 실제 API 기준 snippet입니다. standalone 배지만 독립 실행 단위이며, fragment는 주변 state·handler 문맥을 생략합니다.

01segment (기본, 3-버튼)tsxfragment
segment (기본, 3-버튼)
import { ThemeToggle } from "@axe/ui";// ThemeProvider 하위 어디서든<ThemeToggle />
02cycle (단일 순환 버튼)tsxfragment
cycle (단일 순환 버튼)
import { ThemeToggle } from "@axe/ui";<ThemeToggle mode="cycle" size="md" />
03 · React

Props

TSX 소스가 진실입니다. 주요 export 컴포넌트의 public API만 노출합니다.

이름타입필수기본값설명
mode"segment" | "cycle""segment"segmented 3-버튼(light/system/dark) 또는 단일 순환 버튼.
size"sm" | "md""sm"내부 버튼 크기.
...restReact.HTMLAttributes<HTMLDivElement>className 등 나머지는 루트 <div> 로 전파.
04 · Any stack

.axe-* 클래스 계약

React 밖에서도 같은 표면을 그리는 공개 계약입니다. stable은 minor 버전 안에서 이름을 바꾸지 않습니다.

클래스안정성용도
.axe-theme-togglestable루트 래퍼 (버튼들을 감싸는 inline-flex 행).
.axe-theme-toggle__iconinternal테마 아이콘 SVG 슬롯 (1em 정사각 박스).
비-React 소비 노트
CSS-only 로는 .axe-theme-toggle + .axe-btn 로 시각 껍데기만 재현 가능하고, 실제 테마 전환(storage·DOM 반영)은 JS(useTheme)가 필요하다 — 순수 마크업만으로는 상태가 바뀌지 않는다.
05 · Inclusive

접근성

키보드, ARIA, 구현 노트를 함께 검토합니다.

Keyboard
  • Enter/Space 로 버튼 실행 (내부는 네이티브 <button> 인 Button)
  • segment: Tab 으로 3버튼 순회
  • cycle: Enter/Space 로 다음 테마 순환
ARIA

segment: 래퍼 role="group" + aria-label="테마 선택", 각 버튼에 aria-label(라이트/시스템/다크)과 활성 버튼 aria-pressed="true". cycle: 단일 버튼에 동적 aria-label("테마: <현재> (클릭 시 <다음>)")과 title. 아이콘 SVG 는 aria-hidden 이라 접근명은 aria-label/title 로만 제공.

Notes

useTheme() 에 의존하므로 반드시 ThemeProvider 하위에서 렌더해야 한다. 활성 버튼은 Button variant="primary", 비활성은 variant="ghost". 아이콘은 currentColor 로 테마색을 따른다.

06 · Judgment

권장 · 지양

권장
  • 앱 셸(TopNav 등)에서 테마 storage/DOM 반영은 ThemeProvider + useTheme 에 맡길 것.
  • 폭이 좁은 헤더/모바일에선 cycle, 넉넉하면 segment 를 쓸 것.
지양
  • documentElement 나 localStorage 를 직접 만지지 말 것 — useTheme 을 통할 것(과거 버그의 원인).
  • ThemeProvider 밖에서 렌더하지 말 것(useTheme 이 동작하지 않음).
검색창을 열면 컴포넌트 인덱스를 불러옵니다.