Switch
Immediate on/off toggle for a setting. Applies the change on click — no Save button needed. Base Switch primitive plus a SwitchField compound that wires label + description in one component.
Anatomy
Weekly summary and critical alerts.
- 1Label
Describes what the switch controls. Placed on the left. Clicking the label also toggles the switch.
- 2Description
Optional muted line below the label. Short context — what happens when the switch is on.
- 3Switch
The pill toggle. Placed on the right, aligned with other rows in the settings group.
Primitive
The base Switch is just the pill. Use it when you need a custom layout (e.g. a switch inside a table row or a card header).
<div className="flex items-center gap-3">
<Switch id="notifs" defaultChecked />
<Label htmlFor="notifs">Enable notifications</Label>
</div><Switch /> {/* Off */}
<Switch defaultChecked /> {/* On */}
<Switch disabled /> {/* Off disabled */}
<Switch disabled defaultChecked /> {/* On disabled */}SwitchField
Compound with optional label and description. Same pattern as CheckboxField and RadioField. Label sits on the left, switch on the right — the canonical Settings row.
<SwitchField
id="feature-flag"
label="Enable early access features"
containerClassName="w-full max-w-sm"
/>Only requests from listed IPs can reach the Dashboard.
<SwitchField
id="ip-allowlist"
defaultChecked
label="IP allowlist"
description="Only requests from listed IPs can reach the Dashboard."
containerClassName="w-full max-w-sm"
/>Weekly summary and critical alerts.
Only for account activity.
Not available on your plan.
<div className="grid gap-4 w-full max-w-sm">
<SwitchField
label="Email notifications"
defaultChecked
description="Weekly summary and critical alerts."
/>
<SwitchField
label="Push notifications"
description="Only for account activity."
/>
<SwitchField
label="SMS notifications"
disabled
description="Not available on your plan."
/>
</div>Recipes
Ready-to-copy compositions covering the most common Yuno usages of this atom.
SwitchField with label + description explaining the flag effect.
Only requests from listed IPs can reach the Dashboard.
<SwitchField
defaultChecked
label="IP allowlist"
description="Only requests from listed IPs can reach the Dashboard."
containerClassName="w-full max-w-sm"
/>Vertical stack of SwitchField rows sharing the same alignment. Standard Settings pattern.
Weekly summary and critical alerts.
Only for account activity.
Not available on your plan.
<div className="grid gap-4 w-full max-w-sm">
<SwitchField label="Email notifications" defaultChecked
description="Weekly summary and critical alerts." />
<SwitchField label="Push notifications"
description="Only for account activity." />
<SwitchField label="SMS notifications" disabled
description="Not available on your plan." />
</div>Base Switch primitive placed in a card header (right side) to enable/disable the card contents.
<div className="flex items-center justify-between rounded-lg border bg-card p-5 w-full max-w-sm">
<div>
<div className="text-sm font-semibold text-foreground">Fraud shield</div>
<div className="text-xs text-muted-foreground">Adds an extra 3D Secure step to risky payments.</div>
</div>
<Switch defaultChecked aria-label="Toggle Fraud shield" />
</div>Import
Copy this import line at the top of the file where you compose this atom.
import { Switch, SwitchField } from "@/components/ui/switch";
import { Label } from "@/components/ui/label";Props
Everything else from the underlying HTML or Radix primitive is forwarded via ...props.
| Prop | Type | Default | Description |
|---|---|---|---|
| checked / defaultChecked | boolean | — | Controlled or uncontrolled on state. Controlled requires onCheckedChange. |
| onCheckedChange | (checked: boolean) => void | — | Fires when the user toggles the switch. |
| disabled | boolean | false | Dims the switch and blocks interaction. |
| id | string | — | Associates the switch with a Label via htmlFor. SwitchField auto-generates one via useId if omitted. |
| aria-label | string | — | Required when no visible label is paired (e.g. Switch inside a table row). |
| SwitchField.label | React.ReactNode | — | Visible label on the left. Clicking it toggles the switch. |
| SwitchField.description | React.ReactNode | — | Optional muted line below the label describing the effect. |
| SwitchField.containerClassName | string | — | Merged with the outer flex container. Use w-* utilities to set row width. |
When to use
- Settings that apply immediately (notifications, feature flags).
- Persistent boolean state visible at a glance.
- One-off toggles inside a card, row or dialog.
When not to use
- Field inside a form that requires a Save button — use Checkbox.
- Multi-select — use a Checkbox group.
- Mutually exclusive choice — use RadioGroup.
Usage
- Provide instant feedback (toast, inline confirmation) when toggling.
- Prefer SwitchField for settings rows — the label click behavior is wired for you.
- Place the label on the left, the switch on the right, aligned with other rows.
- Use aria-label if there's no visible label.
- Don't require an extra Save to persist a Switch change.
- Don't use Switch for irreversible destructive changes without confirmation.
- Don't put critical warnings in the description — use a Callout below the group.
Related
Cross-links to atoms and patterns you may reach for next.
- CheckboxFor form fields that need a Save button, or multi-select.
- Radio groupFor mutually exclusive single choice.
- ToggleFor a button that acts like a toggle (e.g. bold in a rich text editor).