Installation
$Terminal
npx shadcn@latest add https://sdk-components.thesqd.com/r/switch.jsonUsage
Pair with a `Label` (via `htmlFor` / `id`) so screen readers announce the toggle.
TSImport
import { Switch } from "@/components/ui/switch";TSExample
import { Switch } from "@/components/ui/switch";
export function Example() {
return <Switch label="Airplane mode" defaultChecked />;
}Composition
Anatomy of the Switch primitive.
Switch (single component — pass everything as props)
├── label={<ReactNode>} (auto-emits a <Label htmlFor={id}>)
├── caption={<ReactNode>} (helper text — switches to start-aligned)
├── variant="default" | "row" | "full" | "card"
│ default → label right of the switch (compact form layout)
│ row → label left, switch right with settings-list spacing (divide-y stacks)
│ full → label left, switch right, full-width plain row (no padding)
│ card → bordered card with optional media, label/caption, switch on the right
├── media={<ReactNode>} (image/icon — only rendered for variant="card")
├── size="default" | "sm"
└── ...rest (checked / defaultChecked / onCheckedChange / disabled / id / className)
Without label/caption, Switch renders bare — pair with your own <Label>
when you need a custom layout (theme switcher, icon flanks, etc).Sizes
Small, medium (default), and large variants.
States
Checked, unchecked, and disabled states.
Theme switcher
Sun/moon icons flank a switch; each icon click forces the corresponding state.
Switch card
Bordered card with icon, title, description, and trailing switch. Border tints to primary when enabled.
Switch card (switch on left)
Same card layout, but the switch sits on the left before the media + label.
Full-width row
`variant="full"` — label-left, switch-right, full-width with no extra padding. Use when you want a single row outside a `divide-y` settings stack.
Get product updates and weekly summaries.
In a settings list
Common form pattern with label + description stacked opposite the toggle.
Get product updates and weekly summaries.
Launches, events, and the occasional deal.
Try features before they're generally available.
API Reference
Props exposed by the Switch primitive.
Switch
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | — | Auto-emits a <Label htmlFor={id}> beside the switch. Omit for a bare switch. |
caption | ReactNode | — | Helper text. Layout depends on `variant`. |
variant | "default" | "row" | "full" | "card" | "default" | `default` puts the label right of the switch; `row` is justify-between with settings-list spacing; `full` is the same layout but full-width with no padding; `card` is a bordered card with optional media. |
media | ReactNode | — | Image/icon shown alongside the label — `variant="card"` only. |
size | "sm" | "default" | "default" | Compact 14×24 vs default 24×40 track. |
checked | boolean | — | Controlled checked state. |
defaultChecked | boolean | — | Uncontrolled initial state. |
onCheckedChange | (checked: boolean) => void | — | Fires when the checked state changes. |
disabled | boolean | — | Disable the toggle and dim its colors. |
className | string | — | Override or extend the resolved track classes. |