Form
Toggle
A button that stays pressed or not, for a view or filter option that applies at once.
Import
import { Toggle } from "@booleanpress/ui/toggle"Usage
Name an icon-only toggle with aria-label; a toggle with text is named by its text. The name stays the same in both states: the pressed state is announced separately, so do not change the text to "Unpin" when it is pressed.
import { StarIcon } from "lucide-react"
import { Toggle } from "@booleanpress/ui/toggle"
export function StarToggle() {
return (
<Toggle variant="outline" aria-label="Star">
<StarIcon />
</Toggle>
)
}It is uncontrolled with defaultPressed, or controlled with pressed and onPressedChange. variant is default (no border) or outline; size is sm, default or lg. toggleVariants gives the same classes to another element. To switch a setting on or off, use Switch; for several related toggles, ToggleGroup; for an action that is not a state, Button.
Examples
Basic
An icon toggle named by aria-label, and a text toggle that starts pressed.
Variants and sizes
default and outline, each pressed, and the three sizes.
Controlled
pressed and onPressedChange keep the state in your code, here shown beside the toggle.
Disabled
A disabled toggle keeps its state, ignores clicks and keys, and leaves the tab order.
Accessibility
- Semantics
- A
buttonwitharia-pressed(trueorfalse) and adata-stateofonoroff. - Labels
- Icon-only toggles need
aria-label. Keep the name constant across states. - Focus
- It is in the tab order. The focus ring shows on keyboard focus, not on click.
- Known limits
- The small size is 32 px high and its minimum width is 32 px; the default is 36 px and the large 40 px. All meet WCAG 2.5.8's 24 px.
- The pressed state is shown by a fill (
--accent). An icon-only toggle in thedefaultvariant has no border, so keep it next to a label or group when the fill alone would be missed.
Keyboard
| Key | Behaviour |
|---|---|
| Space | Presses or releases the toggle. |
| Enter | Presses or releases the toggle. |
API
Toggle
Renders Radix Toggle.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. | |
defaultPressed | boolean | The state of the toggle when initially rendered. Use defaultPressed
if you do not need to control the state of the toggle. | |
onPressedChange | ((pressed: boolean) => void) | The callback that fires when the state of the toggle changes. | |
pressed | boolean | The controlled state of the toggle. |
Also exported: toggleVariants, the class names of Toggle's variants and sizes (cva), to give another element the same look.
Every part takes className, merged with its defaults by cn(), and ref, which reaches the element it renders.
Data attributes: data-slot="toggle" (Toggle).
Theming
The pressed fill is --accent with --accent-foreground; hover is --muted. The outline variant uses --input for its border.
The tokens its classes read. Change their values in your theme, and it follows.
| Token | Used for |
|---|---|
--accent | background |
--accent-foreground | text |
--destructive | border, focus ring |
--input | border |
--muted | background |
--muted-foreground | text |
--ring | border, focus ring |