Search for a command to run...
A two-state toggle. Use for instant on/off changes (notifications enabled, dark mode); for staged changes, use `Checkbox`.
Forwards every Radix Switch.Root prop. The most relevant ones:
| Prop | Type | Default | Description |
|---|---|---|---|
size | "default" | "sm" | "default" | Track + thumb dimensions. Matches Button/Input sizing for inline-row alignment. |
checked | boolean | — | Controlled state. Pair with onCheckedChange. |
defaultChecked | boolean | false | Uncontrolled initial state. |
onCheckedChange | (checked: boolean) => void | — | Fired when the user toggles. Apply the new state to your data immediately — no save button. |
disabled | boolean | false | Standard HTML disabled. Removes pointer events and dims the switch. |
aria-invalid | boolean | false | Renders the destructive ring around the track for validation feedback. Rare on switches, but supported. |
aria-label | string | — | Required when the switch has no visible adjacent label. Screen readers announce this. |
Use a switch for instant on/off — the change applies the moment the user toggles, no save button.
Pair every switch with a label and (when useful) a description. Compose with Field +
FieldContent + FieldTitle + FieldDescription for the canonical row layout.
Include aria-label when the switch sits alone with no adjacent text — e.g. an inline toggle in
a toolbar.
Group related switches inside a FieldGroup with FieldSeparator between rows so the list
reads as one settings unit.
Use a switch for actions that need confirmation or have side effects ("Delete account", "Submit
form"). Those are Button jobs.
Use a switch for staged changes that only apply after a Save click. That's Checkbox territory
— the affordance is wrong otherwise.
Use a switch for multi-option choices. RadioGroup (one of N) or ToggleGroup (filter pills)
are the right primitives.
Set disabled without an explanation. If the switch can't toggle right now, pair it with a
tooltip or inline reason — silence is frustrating.