Basel Standard

Basel Standard / Docs

Toggle Group

Grouped pressed controls for mutually exclusive views or compact multi-select filters.

One active value keeps the view state explicit.

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

Install
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.

One active value keeps the view state explicit.
<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

Multiple selection works when each option can remain active independently.

A shared frame keeps compact filter controls from scattering across the toolbar.

Use this mode for additive filters, not mutually exclusive views.
<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

Keep local view and density controls near the records they affect.

Toggle groups are strongest when they change the current surface immediately and do not need a full settings menu.

Archive
147 records
Coverage audit / paymentsNeeds review
Release brief / journalApproved
<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

  • ToggleGroupItem inherits the same variant and size options as Toggle.
  • Use the default variant in open toolbars and the outline variant 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.

PropTypeDefaultNotes
type"single" | "multiple"requiredChooses exclusive or additive selection behavior.
valuestring | string[]uncontrolled unless providedControlled active value state.
defaultValuestring | string[]undefinedInitial uncontrolled value.
onValueChange(value) => voidundefinedReceives 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.
disabledbooleanfalseDisables the whole group.
classNamestringundefinedExtends the shared group wrapper classes.

ToggleGroupItem

ToggleGroupItem wraps the Radix item and adds the repo's Toggle styling variants.

PropTypeDefaultNotes
valuestringrequiredUnique 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.
disabledbooleanfalseDisables the item.
classNamestringundefinedExtends the base toggle classes.

Exports

ExportTypeNotes
ToggleGroupRadix root wrapperGroup state container.
ToggleGroupItemRadix item wrapperPressed 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.