Switch
A control that allows the user to toggle between checked and not checked.
Switch is an iOS-style toggle. It is semantically equivalent to a Checkbox but visually better suited to turning a preference on or off (enable notifications, dark mode, feature flag).
Installation
$ bext ui add switch
Copy and paste the following into src/components/ui/switch.tsx.
This component is interactive. Make sure the shared island is loaded (see Islands). It reacts to data-ui="switch" hooks.
Usage
Anatomy
<Switch id="sw-id" name="…" checked ariaLabel="…" />
API Reference
Switch
| Prop | Type | Default | Description |
|---|---|---|---|
| id | string | — | id of the <button>, so that a <Label htmlFor> can point to it. |
| checked | boolean | false | Initial state. The island toggles it on click. |
| ariaLabel | string | — | aria-label of the <button>. Use it when there is no visible Label. |
| disabled | boolean | false | Disables the button: it cannot be focused or toggled, is dimmed, and posts nothing. |
| name | string | — | Form field name. Renders a hidden input that posts only while the switch is on. |
| value | string | "on" | Value posted under name when on. |
| className | string | — | Extra classes on the <button>. |
Data Attributes
Attributes you can target in custom CSS to override the style for each state.
| Attribute | On | Values | Description |
|---|---|---|---|
| data-ui="switch" | root | — | Island toggle. |
| data-state | root | "checked" | "unchecked" | Current state, updated by the island on click. |
| aria-checked | root | "true" | "false" | Same state, for assistive technologies. Updated by the island. |
| data-ui="control-input" | hidden input | disabled present or absent | Rendered when name is set. Disabled while the switch is off, so nothing posts. Emits a change event on every toggle. |
Keyboard
| Key | Action |
|---|---|
| Space / Enter | Toggles the switch (it is a <button>). |
Accessibility
Switch sets role="switch" and aria-checked on its <button>, and the island keeps aria-checked in sync. Give it a name with a <Label htmlFor> pointing at its id, or with ariaLabel.
With name, the switch posts with the surrounding form like a native checkbox: the hidden input is sent while the switch is on and left out while it is off. A disabled switch uses the native attribute, so it is announced as unavailable and skipped by Tab.
Edit this component live in the bext playground. The PRISM + signals version is the bext-native idiom: fine-grained reactivity, no virtual DOM.
On This Page