Switch
<Switch> is a binary toggle for persistent settings that apply immediately — dark mode, notifications, integrations on/off. The state change is the action; there’s no Save button.
When to use
- A persistent setting where flipping the toggle is the action.
- Per-row settings in a list (notifications per channel, integrations enabled).
Don’t use Switch for: form fields that submit later (Checkbox), choices in a wizard, or transient UI state that has a different correct primitive (filters, view modes, …).
Default
<Label className="flex items-center gap-3"> <Switch defaultChecked /> Dark mode</Label>Sizes
<Switch size="sm" /><Switch /> {/* default */}API
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | — | Controlled state. Pair with onCheckedChange. |
defaultChecked | boolean | — | Initial state for uncontrolled mode. |
onCheckedChange | (checked: boolean) => void | — | Fires on every change. |
size | "sm" | "default" | "default" | Form-row vs. inline-toolbar density. |
disabled | boolean | false | Native disabled. |
name | string | — | Form-submission name. |
value | string | "on" | Form-submission value when checked. |
Design guidelines
✓ Do
- Use Switch for "this thing turns on/off, right now" — settings, integrations, feature flags.
- Pair with a Label. The label describes what turns on.
- Show success / failure feedback inline (Sonner toast) when the state change is async and could fail.
✗ Don't
- Use Switch in a form that has a Submit button. That's a Checkbox.
- Pair Switch with explicit "On" / "Off" text. The state is visible.
- Use Switch where two options are equal-weight. That's SegmentedControl or RadioGroup.
Accessibility
- Composes Radix Switch —
role="switch",aria-checked, keyboard Space. - Pair with a Label (wrapping or htmlFor).
- For async toggles that may fail, set
aria-busy="true"on the row while waiting and revert visually on error.
Related
Checkbox— Form-style binary that submits with the form.ToggleRow— Switch composed with label + description in a list-row layout.SegmentedControl— Two-to-five visible-at-once choices.