Switch
A toggle switch built on Base UI
Installation
pnpm dlx shadcn@latest add https://prototyper-ui.com/r/switch.jsonnpx shadcn@latest add https://prototyper-ui.com/r/switch.jsonyarn dlx shadcn@latest add https://prototyper-ui.com/r/switch.jsonbunx --bun shadcn@latest add https://prototyper-ui.com/r/switch.jsonThis will add the following files to your project:
components/ui/switch.tsx
Usage
import {
Switch,
SwitchTrack,
SwitchThumb,
} from "@/components/ui/switch"
<Switch>
<SwitchTrack>
<SwitchThumb />
</SwitchTrack>
Airplane Mode
</Switch>Anatomy
<Switch>
<SwitchTrack>
<SwitchThumb>
<SwitchIcon /> {/* optional */}
</SwitchThumb>
</SwitchTrack>
{/* label text */}
</Switch>| Sub-component | data-slot | Purpose | Required |
|---|---|---|---|
Switch | switch | Root component with label and switch control | Yes |
SwitchTrack | switch-track | The sliding track background | Yes |
SwitchThumb | switch-thumb | The draggable thumb indicator | Yes |
SwitchIcon | switch-icon | Optional icon wrapper inside the thumb | No |
Examples
Sizes
With Icon
Label Left
Disabled
Read Only
Styling
Data Slots
Use data-slot attributes to target specific parts of the switch:
| Slot name | Element |
|---|---|
switch | Root wrapper (label + track) |
switch-track | The sliding track background |
switch-thumb | The circular thumb indicator |
Customization Examples
/* Make the switch track wider */
[data-slot="switch-track"] {
@apply w-12 h-6;
}
/* Custom checked track color */
[data-slot="switch"] [data-slot="switch-track"] {
@apply group-data-checked:bg-green-600;
}{/* Override styles via className */}
<Switch className="gap-4">Wide gap label</Switch>API Reference
Switch
Root component that manages on/off state and renders a track with thumb.
Prop
Type
All Base UI Switch.Root props are forwarded via ...props.
SwitchTrack
The sliding track background container that holds the thumb.
Prop
Type
All standard HTML div props are supported via ...props.
SwitchThumb
The circular thumb indicator that slides inside the track.
Prop
Type
All Base UI Switch.Thumb props are forwarded via ...props.
SwitchIcon
Optional icon wrapper for displaying icons inside the thumb.
Prop
Type
All standard HTML span props are supported via ...props. The component automatically hides from screen readers with aria-hidden="true".
Accessibility
Keyboard Interactions
| Key | Action |
|---|---|
Space | Toggles the switch on/off |
Tab | Moves focus to / away from the switch |
ARIA Attributes
- Renders with
role="switch"via Base UI. aria-checkedis set totrueorfalsebased on the switch state.aria-disabledis set when the switch is disabled.aria-readonlyis set when the switch is read-only.- Screen readers announce the label and the on/off state.
Stream UI
This component is available in @prototyperai/stream-ui.
Catalog Definition
import { z } from "zod"
import { defineComponent } from "@prototyperai/stream-ui/catalog"
export default defineComponent({
description: "A toggle switch for on/off states",
props: z.object({
label: z.string().optional().describe("Label displayed next to the switch"),
checked: z.boolean().optional().describe("Whether the switch is on"),
disabled: z.boolean().optional().describe("Whether the switch is disabled"),
size: z
.enum(["sm", "md", "lg"])
.optional()
.describe("Switch size variant"),
}),
events: ["change"],
example: { label: "Enable notifications", checked: false, size: "md" },
})Example Spec
{
"root": "notifSwitch",
"elements": {
"notifSwitch": {
"type": "Switch",
"props": {
"label": "Enable notifications",
"checked": false,
"size": "md"
},
"$bindState": { "path": "/notificationsEnabled", "event": "change" }
}
}
}Learn more in the Stream UI documentation.