Form
Toggle group
A row of toggles that share one choice, or several, such as a period or a set of statuses.
Import
import { ToggleGroup, ToggleGroupItem } from "@booleanpress/ui/toggle-group"Usage
type is required: "single" allows one pressed item at a time, "multiple" any number. Name the group with aria-label, and name icon-only items with aria-label too.
import { ToggleGroup, ToggleGroupItem } from "@booleanpress/ui/toggle-group"
export function Period() {
return (
<ToggleGroup type="single" variant="outline" defaultValue="7d" aria-label="Period">
<ToggleGroupItem value="24h">24 hours</ToggleGroupItem>
<ToggleGroupItem value="7d">7 days</ToggleGroupItem>
<ToggleGroupItem value="30d">30 days</ToggleGroupItem>
</ToggleGroup>
)
}With type="single", value is a string and pressing the pressed item clears it to ""; guard in onValueChange when a choice is required. With type="multiple", value is an array of strings. Both are controlled with value and onValueChange, or uncontrolled with defaultValue. variant and size are set once on the group and reach every item. spacing is the gap between items in 4 px steps: 0 (the default) joins the items into one bar; any larger number separates them. For a choice that submits with a form, use RadioGroup.
Examples
Single
One item pressed at a time, as a period filter.
Multiple
Any number of items pressed, as a set of status filters.
Spacing and size
spacing separates the items into their own buttons; size is set on the group.
Disabled
disabled on the group stops every item; on one item it stops that item and the arrow keys skip it.
Accessibility
- Semantics
- With
type="single", the group isrole="radiogroup"and each item isrole="radio"witharia-checked. Withtype="multiple", the group isrole="group"and each item is a button witharia-pressed. - Labels
- Name the group with
aria-labeloraria-labelledby. Name icon-only items witharia-label. - Focus
- The group is one tab stop: Tab goes to the pressed item, or to the first when none is pressed, and the other items are skipped. The arrow keys move focus without changing the value.
- Known limits
- With
type="single", an item reads as a radio, yet pressing it again clears the group: unlike a radio group, "nothing chosen" is reachable. - Each item is 32 to 40 px high, depending on
size, and at least as wide as its text.
- With
Keyboard
| Key | Behaviour |
|---|---|
| Tab | Moves focus into the group, to the pressed item, or to the first item when none is pressed. A second Tab leaves the group. |
| ArrowRightArrowDown | Moves focus to the next item, wrapping from the last to the first. In right-to-left, ArrowLeft moves forward instead of ArrowRight. It does not change the value. |
| ArrowLeftArrowUp | Moves focus to the previous item, wrapping from the first to the last. In right-to-left, ArrowRight moves back instead of ArrowLeft. It does not change the value. |
| Home | Moves focus to the first item. |
| End | Moves focus to the last item. |
| SpaceEnter | Presses the focused item. In a single group it releases the pressed item first; pressing the pressed item clears the group. |
API
ToggleGroup
Renders Radix ToggleGroup.Root and passes it every other prop.
| Prop | Type | Default | Description |
|---|---|---|---|
typerequired | "single" | "multiple" | "single" allows one pressed item; "multiple" allows any number. Required. | |
asChild | boolean | Render the child element instead, with this part's behaviour and classes merged onto it. | |
defaultValue | string | string[] | The value of the item that is pressed when initially rendered. Use
defaultValue if you do not need to control the state of a toggle group.
The value of the items that are pressed when initially rendered. Use
defaultValue if you do not need to control the state of a toggle group. | |
dir | "ltr" | "rtl" | Reading direction for the arrow keys. Defaults to the provider's. | |
disabled | boolean | Whether the group is disabled from user interaction. | |
loop | boolean | Whether the arrow keys wrap around at the ends. Defaults to true. | |
onValueChange | ((value: string) => void) | ((value: string[]) => void) | The callback that fires when the value of the toggle group changes. The callback that fires when the state of the toggle group changes. | |
orientation | "horizontal" | "vertical" | horizontal or vertical, for the arrow keys. It does not change the layout. | |
rovingFocus | boolean | Whether the group should maintain roving focus of its buttons. | |
spacing | number | 0 | The gap between items in 4 px steps. 0 joins them into one bar. |
value | string | string[] | The controlled stateful value of the item that is pressed. The controlled stateful value of the items that are pressed. |
ToggleGroupItem
Renders Radix ToggleGroup.Item 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. | |
value | string | string[] | The controlled stateful value of the item that is pressed. The controlled stateful value of the items that are pressed. |
Every part takes className, merged with its defaults by cn(), and ref, which reaches the element it renders.
Data attributes: data-slot="toggle-group" (ToggleGroup), data-slot="toggle-group-item" (ToggleGroupItem), and data-variant, data-size, data-spacing.
Theming
Items share the toggle's tokens: --accent when pressed, --muted on hover, --input for the outline border. With spacing={0} the outer corners are rounded and the inner ones square, mirrored in right-to-left.
The tokens its classes read. Change their values in your theme, and it follows.
| Token | Used for |
|---|