Components
Switch
즉시 반영되는 설정용 on/off 토글. "Save" 버튼 없이 바로 적용되는 설정 전용.
Mobile
iOS·Android의 native switch 사이즈가 이미 충분히 크지만(약 51×31), 행 전체가 터치 영역이 되도록 구성하는 것이 권장된다.
- 설정 row 내부에 배치할 때 행 전체에
Pressable을 두고 탭 시 토글 → 사용자가 작은 스위치 손잡이를 정확히 노릴 필요 없음 (행 높이 ≥44pt) - 토글 직후 가벼운 haptic feedback (
impactLight) — iOS는 native switch가 기본 제공, Android는 수동 호출 필요 - "Save" 없이 즉시 반영되는 setting 전용이라는 시맨틱은 web과 동일 — 폼 제출 전 임시 상태가 필요하면 Checkbox 사용
Preview
States
| State | Track | 설명 |
|---|---|---|
checked | brown-800 | 기능 활성 |
unchecked | stone-200 | 기능 비활성 |
disabled | stone-200 + opacity-50 | 설정 불가 |
Sizes
단일 사이즈 (size prop 없음).
| 요소 | 크기 (web — Tiro 커스텀) | 크기 (mobile — native widget) | Tailwind / 비고 |
|---|---|---|---|
| Track | 32 × 16px | ~51 × 31px (iOS) / ~52 × 32px (Android) | web: h-4 w-8 · mobile은 native UISwitch 크기 |
| Thumb | 12 × 12px | ~27px (iOS) / ~20px (Android) | web: h-3 w-3 · mobile은 native |
| Thumb 이동거리 | 16px | native 처리 | web: translate-x-4 |
| Hit area | track 영역 | 행 전체 (≥44pt) | 모바일은 행 전체를 Pressable로 감싸 토글 |
Token Mapping
| Token | Value |
|---|---|
| track (checked) | brown-800 |
| track (unchecked) | stone-200 |
| thumb | white + shadow-lg |
| focus ring | ring-2 ring-brown-800/15 ring-offset-2 |
| disabled | opacity-50 + cursor-not-allowed |
| transition | transition-colors (track) · transition-transform (thumb) |
Props
// Radix UI SwitchPrimitives.Root props
interface SwitchProps {
checked?: boolean
defaultChecked?: boolean
onCheckedChange?: (checked: boolean) => void
disabled?: boolean
required?: boolean
name?: string
value?: string
}Usage
{/* 설정 화면 — label과 함께 */}
<div className="flex items-center justify-between">
<Label>Push 알림</Label>
<Switch
checked={pushEnabled}
onCheckedChange={setPushEnabled}
/>
</div>
{/* disabled */}
<Switch
checked={false}
disabled={updatePending}
onCheckedChange={handleChange}
/>A11y
- Radix UI가
role="switch"+aria-checked자동 처리 - 반드시 인접
<Label>또는aria-label로 목적을 명시 - on/off 상태가 텍스트로도 전달되어야 함 — 색만으로 구분 금지
Do / Don't
- Do: 즉시 반영되는 설정에만 사용 — 변경이 바로 서버에 저장될 때
- Do:
disabled상태일 때 이유를 인접 텍스트로 안내 - Don't: "Save" 버튼을 거쳐 저장하는 폼에는 금지 →
Checkbox사용 - Don't: 바이너리(on/off)가 아닌 다중 선택에 남용 금지
