Form
Switch
Turns one setting on or off, and takes effect as soon as it is flipped.
Import
import { Switch } from "@booleanpress/ui/switch"Usage
Give every switch a visible name: a Label whose htmlFor is the switch's id. Clicking the label flips it.
import { Label } from "@booleanpress/ui/label"
import { Switch } from "@booleanpress/ui/switch"
export function LogSetting() {
return (
<div className="flex items-center gap-2">
<Switch id="log-emails" defaultChecked />
<Label htmlFor="log-emails">Keep the email log</Label>
</div>
)
}It is uncontrolled with defaultChecked, or controlled with checked and onCheckedChange. size is default or sm. Use a switch for a setting that applies at once; use a Checkbox for a choice that is submitted with a form or that belongs to a list of options.
Examples
Basic
Off and on, each named by its label.
Controlled
checked and onCheckedChange keep the setting in your state, here shown beneath the switch.
Sizes
default is 32 × 18 px; sm is 24 × 14 px, for dense rows.
Disabled
A disabled switch keeps its state, ignores clicks and keys, and leaves the tab order.
Invalid
aria-invalid and aria-describedby tell assistive technology about the error; the switch draws no error border, so show the message as text.
Accessibility
- Semantics
- A
buttonwithrole="switch"andaria-checked(trueorfalse); the thumb is decorative. Inside a form, it also renders a hidden native checkbox, so the value is submitted with the form. - Labels
- Name every switch: a
LabelwithhtmlFor, oraria-labelwhen no visible text fits. Word the label for the "on" state ("Keep the email log"), because a screen reader adds "on" or "off" itself. - Focus
- It is in the tab order. The focus ring shows on keyboard focus, not on click.
- Known limits
- The default track is 18 px high and the small one 14 px. Keep the label beside the switch, so the label adds to the target and the pair meets WCAG 2.5.8's 24 px.
- Unlike the other form controls, the switch has no error border for
aria-invalid; the visible error message is the only sign for sighted people.
Keyboard
| Key | Behaviour |
|---|---|
| Space | Flips the switch. |
| Enter | Flips the switch. APG lists Enter as optional. |
API
Switch
Renders Radix Switch.Root and passes it every other prop.
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | Render the child element instead, with this part's behaviour and classes merged onto it. | |
checked | boolean | The state, when you control it. Pair it with onCheckedChange. | |
defaultChecked | boolean | The state it starts in, when it controls itself. | |
onCheckedChange | ((checked: boolean) => void) | Called with the new state when it is flipped. | |
required | boolean | The form cannot be submitted until it is on. | |
size | "default" | "sm" | default | default or sm. |
Every part takes className, merged with its defaults by cn(), and ref, which reaches the element it renders.
Data attributes: data-slot="switch" (Switch), and data-size.
Theming
The track is --primary when on and --control when off, at least 3:1 against the surface; the thumb is --background. The thumb slides toward the end of the line, so it mirrors in right-to-left.
The tokens its classes read. Change their values in your theme, and it follows.
| Token | Used for |
|---|---|
--background | background |
--control | background |
--foreground | background |
--input | background |
--primary | background |
--primary-foreground | background |
--ring | border, focus ring |