Toggle group
A set of toggles that act together: pick one (a segmented control) or several (formatting). Arrow keys move between items; Radix handles roving focus. Source: src/components/ui/toggle-group.tsx.
Segmented control
spacing={0} joins the items into one tint track; the chosen item lifts onto the background with a small shadow. Ignore the empty value so one option is always chosen.
Showing runs from the last 7 days.
Single
type="single" with separate items: a choice of view or alignment in a toolbar. Radix exposes it as a radio group (aria-checked).
Weekly summary
Multiple
type="multiple": each item toggles independently and value is an array. Each item reports aria-pressed.
value: ["bold"]
Variants and spacing
Separate items (spacing 2) with the default or outline look, or one joined track (spacing 0).
Sizes
Toggle's three heights, applied to every item.
Disabled
Disable the whole group, or one item that isn't available right now.
Known gaps: there is no invalid style on the group, and orientation="vertical" changes arrow-key direction but the stacking class targets a data-vertical attribute the component never sets, so lay out a vertical group yourself (className="flex-col").
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| type | "single" | "multiple" | required | single: value is a string (empty when cleared). multiple: value is a string[]. |
| value / defaultValue | string | string[] | — | Matches type. |
| onValueChange | (value) => void | — | Single groups receive "" when the active item is clicked again. |
| spacing | number | 2 | Gap between items in spacing units (×4px). 0 joins them into one tint track with a raised active item. |
| variant | "default" | "outline" | — | Passed to every item (Toggle variants). |
| size | "sm" | "default" | "lg" | — | Passed to every item. A joined group (spacing 0) fixes items at 28px. |
| orientation | "horizontal" | "vertical" | "horizontal" | Sets arrow-key direction. See the note on vertical layout below. |
| disabled | boolean | false | On the group or on a single ToggleGroupItem. |
| ToggleGroupItem | Radix ToggleGroup.Item props + variant, size | — | value is required. Group-level variant and size win over the item's. className merges last. |
Best practices
When to use
- Two to five options that should all stay visible: a time range, a view mode, alignment.
- More options, or labels that don't fit: a Select.
- Switching between panels of content: Tabs, not a toggle group.
Behavior
- For single groups, guard onValueChange so clicking the active item doesn't clear the choice.
- Changing the selection should update the view straight away; no Apply button.
- Keep labels short and similar in length so the track doesn't look lopsided.
Accessibility
- Give the group an aria-label (Time range, Text alignment). Icon-only items each need one too.
- Tab enters the group once; arrow keys move between items.
- Joined items are 28px tall; keep them for pointer-dense toolbars and filters.
Content
- Parallel, short labels: 24h / 7 days / 30 days. Use the same unit style across items.