# Switch

Turns a setting on or off at once, with no Save. A track with a thumb that slides to the end when on: the control border on the sunken fill when off, the accent when on. label puts its name after it, and description a second line under the name.

## Cách dùng

### Khi nào dùng

- Turn a setting on or off where the change applies at once, such as email notifications.
- A row of settings on a settings page, each with its own switch.

### Khi nào không dùng

- A choice that waits for Save, or accepting terms. Use Checkbox.
- Picking one of several options. Use RadioGroup.

## Biến thể

### size

Track width from size-element-*, so it follows touch; the label and description step with it (12, 13, 14px, and 14px at xl). md for settings pages and props panels; sm in dense rows and toolbars, such as a table; lg and xl next to Inputs and Buttons of the same size.

Giá trị: `sm`, `md`, `lg`, `xl`. Mặc định: `md`.

## Ví dụ

### Default

```tsx
<Switch label="Dark mode" />
```

### With a description

```tsx
<Switch
  label="Email notifications"
  description="Get an email when someone mentions you."
  defaultChecked
/>
```

### Disabled

```tsx
<Switch
  label="Two-factor authentication"
  description="Required by your workspace."
  disabled
  defaultChecked
/>
```

### In a table row

sm, for dense rows and toolbars. The name is in another column, so the switch takes aria-label.

```tsx
<Switch size="sm" aria-label="Enable the deploy webhook" defaultChecked />
```

### Next to large controls

lg matches lg Inputs and Buttons; the label and description step up with it (14px). The Variants section shows every size side by side.

```tsx
<div className="flex w-full max-w-sm flex-col gap-lg">
  <Input size="lg" aria-label="Workspace name" defaultValue="Acme" />
  <Switch
    size="lg"
    label="Public workspace"
    description="Anyone with the link can view it."
  />
</div>
```

## Nên và không nên

### Nên

- Use it for a setting that takes effect at once, and apply the change in onCheckedChange.
- Name the setting in the label, and say what on does in the description.
- Use sm in dense rows and toolbars, such as a table, where the name sits in another column (aria-label). A props panel takes md, so the switch stays easy to hit on a phone.
- Match the size of the controls around it: md with md Inputs on a settings page, lg or xl with Inputs and Buttons of the same size.

### Không nên

- Don't use it in a form that waits for Save; use Checkbox.
- Don't use it to pick one of several options; use RadioGroup.
- Don't change the label when it toggles (On, Off); the thumb shows the state.

## Props

| Tên | Kiểu | Giá trị | Mặc định | Mô tả |
| --- | --- | --- | --- | --- |
| `size` | `enum` | `sm`, `md`, `lg`, `xl` | `md` | Track width from size-element-*, so it follows touch; the label and description step with it (12, 13, 14px, and 14px at xl). md for settings pages and props panels; sm in dense rows and toolbars, such as a table; lg and xl next to Inputs and Buttons of the same size. |
| `label` | `node` |  |  | The visible name, after the switch. A press on it toggles the switch. Name the setting, not the action: Email notifications. |
| `description` | `node` |  |  | A second line under the label: what turning it on does. Needs label. |
| `checked` | `boolean` |  |  | Controlled state. Pair it with onCheckedChange. |
| `defaultChecked` | `boolean` |  | `false` | On at first render, when you don't control it. |
| `onCheckedChange` | `function` |  |  | Called with true or false when the user toggles it. Apply the change here; there is no Save. |
| `disabled` | `boolean` |  | `false` | Can't be focused or toggled; the label dims too. |
| `required` | `boolean` |  | `false` | Must be on to submit the form. |
| `name` | `string` |  |  | Form name. The form submits value under this name while the switch is on. |
| `value` | `string` |  | `on` | Value submitted while the switch is on. |

## Cấu tạo

| Phần | Mô tả |
| --- | --- |
| `root` | The track: radius-full, control border on the sunken fill; on, the accent fills it to the edge. As wide as size-element-* and as tall as half of it plus the two borders, so it follows touch. Mouse: sm 28 by 16px, md 32 by 18px, lg 36 by 20px, xl 44 by 24px; touch: md 36 by 20px, lg 44 by 24px, xl 48 by 26px. |
| `thumb` | The thumb: a circle half of spacing-xs (2px) from the inner edge, the inside height minus spacing-xs: 10px (sm), 12px (md), 14px (lg) or 18px (xl) on mouse. It takes the track's icon color: secondary when off, on-accent when on. |
| `hitArea` | Transparent ::before centered on the track, never shorter than size-target-min (24px on mouse, 44px on touch). |
| `row` | With label: the row that holds the switch, then the Label and the description, gap-sm. Shared with Checkbox and RadioGroup. |
| `label` | With label: a Label after the switch, level with it on its first line. 12px at sm, 13px at md, 14px at lg and xl. |
| `description` | With description: secondary text under the label, gap-xs, the same size as the label. |

## Khả năng truy cập

Role: `switch`

| Phím | Hành động |
| --- | --- |
| `Space, Enter` | Turns the switch on or off. |
| `Tab` | Moves focus to the next control; each switch is its own tab stop. |

- Name every switch with the label prop (a press on it toggles the switch), or aria-label when the name is shown elsewhere, such as a row in a table.
- description is linked with aria-describedby and read after the name, outside the label.
- The change applies at once. A choice that waits for Save is a Checkbox.
- On and off differ by the thumb's position as well as the fill, so the state never relies on color alone.
- The thumb slides only when the user allows motion; under prefers-reduced-motion it jumps.
- On mouse the track is 16px (sm), 18px (md), 20px (lg) or 24px (xl) tall, but its hit area is never smaller than size-target-min (24px on mouse, 44px on touch). On touch md, lg and xl grow with size-element-md, -lg and -xl; sm keeps its look and relies on the hit area.
- In a right-to-left page the thumb starts at the right and slides left when on.

## Cài đặt

```bash
npx shadcn add https://werewolf-ui.vercel.app/r/switch.json
```

Lệnh này thêm luôn `styles/werewolf.css`, bộ token mà mọi component dùng, và các component khác mà nó cần. Import file đó một lần trong CSS gốc, ngay sau `@import "tailwindcss"`, với đường dẫn tính từ file CSS đó (từ `app/globals.css` là `@import "../styles/werewolf.css"`).
