An on/off control that takes effect at once: a native checkbox with the switch role.
Example
import { Switch } from "@elements/ui/switch";
import { Label } from "@elements/ui/label";
<Label><Switch checked={settings.airplane} /> Airplane mode</Label>
<Switch checked={settings.wifi} size="sm" attrs={{ "aria-label": "Wi-Fi" }} />
Parts
| Part |
What it is |
.switch |
The wrapper: track and thumb stacked in one cell. |
.switch-input |
The native <input type="checkbox" role="switch">, drawn as the track. |
.switch-thumb |
The knob. It moves by transform; nothing resizes. |
Attributes
| Attribute |
Type |
Default |
Description |
checked |
boolean (two-way) |
false |
On or off. Bind it to state; a click writes back. |
value |
string |
"on" |
Submitted with name while on. |
name |
string |
"" |
Form field name. |
size |
"sm" | "md" |
"md" |
Track size. |
uncheckedValue |
string | undefined |
undefined |
Submitted under name while off. By default an off switch submits nothing. |
readOnly |
boolean |
false |
Focusable and announced, but a click, Space, Enter or a label press does not change it. |
disabled |
boolean |
false |
Native disabled. |
required |
boolean |
false |
The form will not submit while off. |
invalid |
boolean |
false |
aria-invalid and a danger outline. |
class |
string |
"" |
Extra classes on the wrapper. |
attrs |
Record<string, string | number | boolean | undefined> |
{} |
Attributes for the <input>: id, aria-label, aria-describedby, data-*. |
onCheckedChange |
(checked: boolean, details: ChangeDetails) => void |
() => {} |
The user changed it, or a form reset restored it (not called for changes made in code). It runs before the change with details second (reason, event, cancel(), isCanceled); details.cancel() keeps the state. |
Keyboard
| Keys |
Action |
Space |
Toggles the switch. |
Enter |
Toggles the switch. |
Data attributes
| Attribute |
Values |
On |
Description |
data-state |
"checked" | "unchecked" |
wrapper, input, thumb |
|
data-checked, data-unchecked |
present for the current state |
wrapper, input, thumb |
The same state as data-state, as presence attributes. |
data-size |
"sm" | "md" |
wrapper |
|
data-disabled |
present while disabled |
wrapper, thumb |
|
data-readonly |
present while readOnly |
wrapper, input, thumb |
|
data-required |
present while required |
wrapper, thumb |
|
data-invalid |
present while invalid |
input |
|
Accessibility
- role="switch" on a native checkbox: assistive tech announces on and off from its checked state.
- Keep the label the same in both states; the switch carries the state (APG).
- Name it with a
<Label>, aria-label in attrs, or a <Field>. A group of switches goes in a FieldSet with a legend.
- Space and Enter toggle it; focus shows the theme ring.
See also