Tiro
Tiro Design
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

웹·데스크톱 승인 토큰(tokens/web-desktop.yaml switch/*). 트랙은 중립 반전, thumb 는 상태별로 다릅니다.

StateTrackThumb설명
checkedstone-800 (dark stone-50)stone-50 (dark stone-800)기능 활성
uncheckedstone-100 (dark stone-700)stone-400 (dark white 56%)기능 비활성
disabled위 트랙 + opacity-50—설정 불가

Sizes

단일 사이즈 (size prop 없음).

요소크기 (web — Tiro 커스텀)크기 (mobile — native widget)Tailwind / 비고
Track32 × 16px~51 × 31px (iOS) / ~52 × 32px (Android)web: h-4 w-8 · mobile은 native UISwitch 크기
Thumb12 × 12px~27px (iOS) / ~20px (Android)web: h-3 w-3 · mobile은 native
Thumb 이동거리16pxnative 처리web: translate-x-4
Hit areatrack 영역행 전체 (≥44pt)모바일은 행 전체를 Pressable로 감싸 토글

Token Mapping

TokenValue
track (checked)stone-800 (dark stone-50)
track (unchecked)stone-100 (dark stone-700)
thumb (checked)stone-50 (dark stone-800) + shadow-lg
thumb (unchecked)stone-400 (dark white 56%) + shadow-lg
focus ring2px input/focus (alphaBrand.24), offset 2
disabledopacity-50 + cursor-not-allowed
transitiontransition-colors (track) · transition-transform (thumb)

모바일(React Native)은 native widget 을 쓰며 이 표의 web 토큰과 별개입니다. 아래 Mobile 탭을 참고하세요.


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)가 아닌 다중 선택에 남용 금지

On this page