Toggle
A two-state pressable button — renders as a <button> with aria-pressed and data-state="on"|"off". Use it standalone, or drop several inside ToggleGroup.Root (single or multiple selection) for a segmented control or formatting pill bar. Distinct from Switch, which is a settings on/off control.
Features
Example
The quick brown fox jumps over the lazy dog.
Anatomy
import { Toggle, ToggleGroup } from '@wire-ui/react'
// Standalone
<Toggle defaultPressed aria-label="Toggle italic">
<i>I</i>
</Toggle>
// Grouped (multiple selection)
<ToggleGroup.Root type="multiple" defaultValue={['bold']} aria-label="Text formatting">
<Toggle value="bold" aria-label="Bold"><b>B</b></Toggle>
<Toggle value="italic" aria-label="Italic"><i>I</i></Toggle>
<Toggle value="underline" aria-label="Underline">U</Toggle>
</ToggleGroup.Root>Styling
Toggle exposes data-state ("on" / "off") plus the standard interactive-state attributes from useInteractiveState. Use these to style the pressed appearance and focus ring.
<Toggle className="
text-black
data-[state=on]:bg-black data-[state=on]:text-white
data-[disabled]:opacity-40 data-[disabled]:cursor-not-allowed
data-[focus-visible]:ring-2 data-[focus-visible]:ring-black
">
<b>B</b>
</Toggle>ToggleGroup.Root exposes data-orientation so a single group can flip between row and column layouts:
<ToggleGroup.Root className="
inline-flex gap-1
data-[orientation=vertical]:flex-col
data-[disabled]:opacity-50
" />Using data attributes
Toggle sets data-state ("on" / "off") and data-disabled. ToggleGroup.Root sets data-orientation and data-disabled.
/* Pressed toggle */
[data-state="on"] { background: #000; color: #fff; }
[data-state="off"] { /* default */ }
/* Disabled */
[data-disabled] { opacity: 0.4; cursor: not-allowed; }
/* Vertical group */
[data-orientation="vertical"] { flex-direction: column; }Toggle props
| Prop | Type | Default | Description |
|---|---|---|---|
pressed | boolean | — | Controlled pressed state (standalone use) |
defaultPressed | boolean | false | Initial pressed state (uncontrolled, standalone use) |
onPressedChange | (pressed: boolean) => void | — | Called when the pressed state changes (standalone use) |
value | string | — | Identity within a ToggleGroup.Root. When set inside a group, the group owns the pressed state |
disabled | boolean | false | Disables this toggle |
Also accepts all native <button> attributes (except value and onChange).
ToggleGroup.Root props (single)
| Prop | Type | Default | Description |
|---|---|---|---|
type | 'single' | required | One toggle active at a time |
value | string | null | — | Controlled selected value (null when none) |
defaultValue | string | null | — | Initial selected value (uncontrolled) |
onChange | (value: string | null) => void | — | Called when the selection changes |
disabled | boolean | false | Disable the whole group |
orientation | 'horizontal' | 'vertical' | 'horizontal' | Layout + arrow-key axis |
loop | boolean | true | Wrap arrow-key focus from last → first |
rovingFocus | boolean | true | Manage focus as a single tab stop with arrow-key navigation |
ToggleGroup.Root props (multiple)
| Prop | Type | Default | Description |
|---|---|---|---|
type | 'multiple' | required | Any number of toggles active |
value | string[] | — | Controlled selected values |
defaultValue | string[] | [] | Initial selected values (uncontrolled) |
onChange | (value: string[]) => void | — | Called when the selection changes |
disabled | boolean | false | Disable the whole group |
orientation | 'horizontal' | 'vertical' | 'horizontal' | Layout + arrow-key axis |
loop | boolean | true | Wrap arrow-key focus from last → first |
rovingFocus | boolean | true | Manage focus as a single tab stop with arrow-key navigation |
Data attributes
| Attribute | Element | Values |
|---|---|---|
data-state | Toggle | "on" / "off" |
data-disabled | Toggle, ToggleGroup.Root | Present when disabled |
data-orientation | ToggleGroup.Root | "horizontal" / "vertical" |
data-hover / data-active / data-focus-visible | Toggle | Standard interactive states |
Accessibility
- Each Toggle renders as
<button>witharia-pressedreflecting the current state. ToggleGroup.Rootsetsrole="group"andaria-orientation.- Inside a group with
rovingFocus, the group is a single tab stop: only the active item is tabbable (tabindex={0}), the rest aretabindex={-1}, and arrow keys move focus. Disabled toggles are skipped.
Keyboard Interactions
| Key | Description |
|---|---|
| Space / Enter | Toggles the focused button on/off. |
| ArrowRight / ArrowDown | Move focus to the next toggle in the group (axis depends on orientation). |
| ArrowLeft / ArrowUp | Move focus to the previous toggle in the group. |
| Home | Focus the first toggle in the group. |
| End | Focus the last toggle in the group. |
| Tab | Moves focus to the group (single tab stop), then out of it. |