Prisma
Live Preview
Notifications — On
Dark Mode — Off
Disabled (on)

--- description: Hướng dẫn Agent tự động tạo UI Component Switch/Toggle dựa trên Design Tokens, có ngữ nghĩa chuẩn Material 3 & iOS HIG

Switch Component Generation Skill

Skill này hướng dẫn bạn (AI Agent) tạo component Switch / Toggle — điều khiển bật/tắt có hiệu lực tức thì.

1. Mục tiêu (Objective)

Tạo component Switch hoàn chỉnh, thể hiện rõ trạng thái on/off, có animation mượt mà, hỗ trợ Dark Mode và tích hợp 100% Design Tokens.

2. AI Context & Intent (Ngữ cảnh cho AI)

Khi nào dùng Switch?

  • Bật/tắt setting có hiệu lực TỨC THÌ (không cần nhấn Save)
  • Trạng thái nhị phân rõ ràng: on/off, enable/disable, show/hide

⚠️ Phân biệt Switch vs Checkbox (QUAN TRỌNG)

Tiêu chí Switch Checkbox
Hiệu lực TỨC THÌ (instant) SAU KHI submit form
Ngữ cảnh Settings, toggles Forms, agreements
Metaphor Công tắc đèn Danh sách đánh dấu
Ví dụ Dark mode, Notifications "Tôi đồng ý", chọn features
Tương đồng Switch (Material 3 & iOS) Checkbox (Material 3)

Decision Tree cho AI

text
User cần toggle on/off?
├─ Có hiệu lực tức thì (settings) → Switch
├─ Trong form, cần submit → Checkbox
├─ Chọn 1 từ 2+ options → Radio
└─ Chọn nhiều → Checkbox Group

3. Ngữ nghĩa & Phân loại (Semantics)

3.1. Switch States

State Track Thumb Mô tả
Off base.muted color-base.white Tắt, mờ
On base.primary color-base.white Bật, highlight
Disabled Off base.muted (faded) color-base.white (faded) Không tương tác
Disabled On base.primary (faded) color-base.white (faded) Khoá ở trạng thái bật

🎯 Best Practice: Thumb LUÔN trắng (#ffffff) ở mọi state — theo chuẩn iOS HIG, Material Design 3, shadcn/ui, Ant Design, và Carbon IBM.

3.2. Size Variants

  • sm: Compact, dùng trong dense lists, tables.
  • md: Default, dùng trong settings pages.
  • lg: Prominent, dùng khi cần emphasis.

3.5. Slot Map (Figma ↔ Code)

📎 Source: slot-manifest.jsonswitch · Layer: item

Figma Slot data-slot CSS Class Required Accepts
Root switch .switch
Thumb switch-thumb
Label switch-label text

4. Token Mapping

📦 Token values: Xem ATOMIC-MAPPING.md — single source of truth cho tất cả actual token values.

Token Type Value Mô tả
track-width.sm number {min-width.9} Small track width
track-width.md number {min-width.11} Default track width
track-width.lg number 52 Large track width
track-height.sm number {min-width.5} Small track height
track-height.md number {min-width.6} Default track height
track-height.lg number {min-width.7} Large track height
thumb-size.sm number {min-width.4} Small thumb size
thumb-size.md number {min-width.5} Default thumb size
thumb-size.lg number {min-width.6} Large thumb size
radius number {border-radius.full} chip shape
label-gap number {spacing.2} Gap giữa switch và label
color.track-off color {base.muted} Track bg khi off
color.track-on color {base.primary} Track bg khi on
color.thumb color {color-base.white} Thumb color — luôn trắng (iOS/MD3/shadcn standard)
color.hover color {state-layer.hover} Hover state layer
color.focus-ring color {focus.ring-color} Focus ring — ref shared/focus
color.bg color {base.background} Default background
color.fg color {base.foreground} Default foreground
thumb-shadow shadow {shadow.xs} Subtle thumb drop shadow
disabled-opacity number {opacity.50} Disabled opacity
transition string {duration.normal-1} {easing.standard} Thumb slide animation
padding number {item.padding-default} Internal padding

5. Props & API

typescript
interface SwitchProps {
  /** Checked state */
  checked?: boolean;
  /** Default checked (uncontrolled) */
  defaultChecked?: boolean;
  /** Label — hiển thị bên phải switch */
  label?: string;
  /** Description — text phụ dưới label */
  description?: string;
  /** Size */
  size?: 'sm' | 'md' | 'lg';
  /** Disabled */
  disabled?: boolean;
  /** On change callback */
  onChange?: (checked: boolean) => void;
}

6. Accessibility (a11y)

  • Role: Dùng <button role="switch"> hoặc <input type="checkbox" role="switch">.
  • State: aria-checked="true" / "false" (KHÔNG dùng aria-pressed).
  • Label: Liên kết qua aria-labelledby hoặc aria-label.
  • Keyboard: Space / Enter toggle.
  • Focus: :focus-visible outline rõ ràng.
  • Screen reader: Announce "on" / "off" khi toggle.

7. Best Practices & Rules

  • Instant effect: Switch PHẢI có hiệu lực ngay khi toggle — nếu cần save, dùng Checkbox.
  • Label position: Label mặc định bên phải switch (LTR). Support RTL nếu cần.
  • Animation: Thumb slide smooth (200ms ease), KHÔNG snap ngay.
  • Không dùng text "ON/OFF" trên track — sử dụng màu sắc đủ rõ ràng.
  • Không Hardcode: Mọi giá trị từ Token.

8. Example Usage

jsx
{/* Basic */}
<Switch label="Chế độ tối" checked={isDark} onChange={setIsDark} />

{/* With description */}
<Switch
  label="Thông báo"
  description="Nhận thông báo qua email khi có giao dịch mới"
  size="md"
/>

{/* Disabled */}
<Switch label="Tính năng Beta" disabled checked />