Basel Standard / Docs
Toggle Group
Grouped pressed controls for mutually exclusive views or compact multi-select filters.
Toggle Group keeps related pressed controls inside one frame. Use it for view modes, density switches, and additive filters where the current state should stay visible in the toolbar rather than inside a dropdown or settings panel.
Installation
Purchase access, then open /account/install to issue a registry token.Usage
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
<ToggleGroup type="single" defaultValue="board" aria-label="Choose view">
<ToggleGroupItem value="list">List</ToggleGroupItem>
<ToggleGroupItem value="board">Board</ToggleGroupItem>
<ToggleGroupItem value="timeline">Timeline</ToggleGroupItem>
</ToggleGroup>
Why This Primitive Exists
- Use it when a small set of states should remain visible and directly selectable.
- Prefer it to separate toggles when the controls form one decision cluster.
- Avoid it when the choice needs labels, descriptions, or validation feedback that belong in a form field or radio group.
Examples
Single Selection
Use type="single" when the user should land on one active value at a time.
<ToggleGroup type="single" defaultValue="board" aria-label="Choose view">
<ToggleGroupItem value="list">List</ToggleGroupItem>
<ToggleGroupItem value="board">Board</ToggleGroupItem>
<ToggleGroupItem value="timeline">Timeline</ToggleGroupItem>
</ToggleGroup>
Multiple Selection
Switch to type="multiple" when each pressed item is an additive filter or formatting option.
Review filters
A shared frame keeps compact filter controls from scattering across the toolbar.
<ToggleGroup type="multiple" defaultValue={["owners", "sla"]} aria-label="Active filters">
<ToggleGroupItem value="owners">Owners</ToggleGroupItem>
<ToggleGroupItem value="sla">SLA</ToggleGroupItem>
<ToggleGroupItem value="blocked">Blocked</ToggleGroupItem>
</ToggleGroup>
In Context
Toggle groups belong close to the records or canvas they affect. They are strongest when the surface updates immediately after selection.
Archive controls
Toggle groups are strongest when they change the current surface immediately and do not need a full settings menu.
<div className="flex gap-3">
<ToggleGroup type="single" defaultValue="list" aria-label="View mode">
<ToggleGroupItem value="list">List</ToggleGroupItem>
<ToggleGroupItem value="board">Board</ToggleGroupItem>
<ToggleGroupItem value="split">Split</ToggleGroupItem>
</ToggleGroup>
<ToggleGroup type="single" defaultValue="compact" aria-label="Density mode">
<ToggleGroupItem value="compact">Compact</ToggleGroupItem>
<ToggleGroupItem value="balanced">Balanced</ToggleGroupItem>
</ToggleGroup>
</div>
Guidance
Separate Selection Logic From Visual Grouping
- Use one group for one decision.
- If the controls represent unrelated tasks, split them into separate groups or move them into a menu.
- If the user must see longer labels and help text, use radio-group or checkbox patterns instead.
Match The Interaction To The State Model
- Use
type="single"for mutually exclusive view modes or text alignment choices. - Use
type="multiple"for additive filters and formatting toggles. - Keep the number of items small enough that the active state remains legible at a glance.
Let The Item Variant Carry Surface Tone
ToggleGroupIteminherits the samevariantandsizeoptions asToggle.- Use the default variant in open toolbars and the
outlinevariant on denser cards or field-adjacent panels. - Keep item labels short so the group reads as one control cluster instead of a segmented sentence.
API Reference
ToggleGroup
ToggleGroup wraps @radix-ui/react-toggle-group and forwards the Radix root props directly.
| Prop | Type | Default | Notes |
|---|---|---|---|
type | "single" | "multiple" | required | Chooses exclusive or additive selection behavior. |
value | string | string[] | uncontrolled unless provided | Controlled active value state. |
defaultValue | string | string[] | undefined | Initial uncontrolled value. |
onValueChange | (value) => void | undefined | Receives a string in single mode or a string array in multiple mode. |
orientation | "horizontal" | "vertical" | "horizontal" | Switches the group to a stacked layout when needed. |
disabled | boolean | false | Disables the whole group. |
className | string | undefined | Extends the shared group wrapper classes. |
ToggleGroupItem
ToggleGroupItem wraps the Radix item and adds the repo's Toggle styling variants.
| Prop | Type | Default | Notes |
|---|---|---|---|
value | string | required | Unique value for the item. |
variant | "default" | "outline" | "default" | Shares the same surface styling options as Toggle. |
size | "sm" | "default" | "lg" | "default" | Matches the shared toggle size scale. |
disabled | boolean | false | Disables the item. |
className | string | undefined | Extends the base toggle classes. |
Exports
| Export | Type | Notes |
|---|---|---|
ToggleGroup | Radix root wrapper | Group state container. |
ToggleGroupItem | Radix item wrapper | Pressed item with repo-level size and variant options. |
Standard Radix and DOM props such as rovingFocus, loop, dir, aria-label, and asChild continue to pass through.