bx

Switch

A control that allows the user to toggle between checked and not checked.

tsx
<div className="flex items-center gap-2">
  <Switch id="airplane" />
  <Label htmlFor="airplane">Airplane mode</Label>
</div>

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

Terminal
$ bext ui add switch

Usage

tsx
import { Switch, Label } from "@bext-stack/ui/primitives"

<div className="flex items-center gap-2">
  <Switch id="airplane" />
  <Label htmlFor="airplane">Airplane mode</Label>
</div>

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.

Try it live
Open in play

Edit this component live in the bext playground. The PRISM + signals version is the bext-native idiom: fine-grained reactivity, no virtual DOM.

src/app/page.tsx 2 files · signals · runs in your browser
Pure PRISM + real bext signals: fine-grained, no re-render.