Toggle
A two-state button that can be either on or off.
Toggle is a two-state on/off button (bold, italic, mute…). It differs from Switch, which represents an "enable/disable this feature" preference: Toggle is a local display/formatting mode.
Installation
$ bext ui add toggle
Copy and paste the following into src/components/ui/toggle.tsx.
This component is interactive. Make sure the shared island is loaded (see Islands). It reacts to data-ui="toggle" hooks.
Usage
Anatomy
<Toggle pressed={boolean} ariaLabel="…">Content</Toggle>API Reference
Toggle
| Prop | Type | Default | Description |
|---|---|---|---|
| pressed | boolean | false | Initial pressed state. Sets data-state="on", aria-pressed="true" and the accent background. |
| ariaLabel | string | — | aria-label of the <button>. Use it when the content is an icon or a single letter. |
| disabled | boolean | false | Disables the button: it cannot be focused or pressed, and is dimmed. |
| id | string | — | id of the <button>. |
| children | ReactNode | — | Button content. It is the accessible name unless ariaLabel is set. |
| className | string | — | Extra classes on the <button>, for example "border" for an outlined look. |
Data Attributes
Attributes you can target in custom CSS to override the style for each state.
| Attribute | On | Values | Description |
|---|---|---|---|
| data-ui="toggle" | root | — | The island flips the state on click. |
| data-state | root | "on" | "off" | Current state. The pressed look is styled from it (data-[state=on]:bg-accent), so it follows every click. |
| aria-pressed | root | "true" | "false" | Same state, for assistive technologies. Updated by the island. |
Keyboard
| Key | Action |
|---|---|
| Space / Enter | Toggle on ↔ off. |
Accessibility
Toggle renders a native <button type="button"> with aria-pressed, which the island keeps in sync with data-state, so the pressed state is announced. Its accessible name is its content, or ariaLabel when set: give an icon-only toggle an ariaLabel, or a visually hidden text such as <span class="sr-only">Bold</span>. Keep the name the same in both states: the state is carried by aria-pressed, not by the label.
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