Components

Toggle Group

A React toggle group with Liquid Glass selected states, single or multiple selection, and two orientations.

ToggleGroup groups related toggle buttons on one glass surface. Use it for view switchers and formatting controls with single or multiple selection.

Basic example

The view switcher below uses the real Toggle Group. The pressed item receives the glass selected state and updates the text underneath.

Options are passed through the items array; each item's value maps to the group value.

Give the group an accessible name with aria-label or aria-labelledby. Items that render only an icon need their own aria-label.

Current view: Grid

Sizes

Supports xs / sm / md / lg / xl, defaulting to md.

xs
sm
md
lg
xl

Selection mode

Use multiple to allow more than one pressed item; the default is single selection.

single
multiple

Orientation

Use orientation="vertical" for a vertical group:

Controlled usage

value and onValueChange let external state fully control the selection. The example below stays controlled after clearing:

Selected: bold

Disabled

Set disabled on the group to disable every item, or on a single item to disable only that option.

One item disabled
Whole group disabled

Accessibility

ToggleGroup renders a group whose items are toggle buttons with aria-pressed. Name the group with aria-label or aria-labelledby; icon-only items need their own name.

Arrow keys move focus within the group, Home and End jump to the ends, and Space or Enter toggles the focused item. In single-selection mode, the group value is the single source of truth; control it when the selection must not be cleared. See the accessibility guide for keyboard details.

API reference

ToggleGroup

PropTypeDefaultDescription
valuereadonly string[]—Controlled pressed values.
defaultValuereadonly string[][]Initial pressed values when uncontrolled.
onValueChange(value: string[], details) => void—Called when the pressed values change.
multiplebooleanfalseAllows multiple pressed items.
orientation"horizontal" | "vertical""horizontal"Layout and keyboard orientation.
loopFocusbooleantrueLoops keyboard focus back to the first item after the last one.
disabledbooleanfalseDisables every item.
size"xs" | "sm" | "md" | "lg" | "xl""md"Controls item height, padding, text, and icons.
itemsreadonly ToggleGroupItemProps[]—Options rendered by the group.
aria-labelstring—Accessible name for the group.
aria-labelledbystring—Names the group from another element.
renderReactElement | ((props, state) => ReactElement)—Replaces the group element.
refRef<HTMLDivElement>—Ref forwarded to the group element.
classNamestring—Tailwind classes merged into the group root.
styleCSSProperties—Inline styles merged into the same element as className.
ui{ root?: ClassValue; glass?: ClassValue; rim?: ClassValue; item?: ClassValue; content?: ClassValue; icon?: ClassValue; label?: ClassValue }—Tailwind classes for internal slots, keyed by data-slot.

ToggleGroupItemProps

PropTypeDefaultDescription
valuestring—Required value used by the group.
labelReactNode—Visible content inside the item.
iconReactNode—Decorative icon rendered before the label.
onPressedChange(pressed, details) => void—Called when this item's pressed state changes.
disabledbooleanfalseDisables the item.
aria-labelstring—Accessible name for icon-only items.
aria-labelledbystring—Names an icon-only item from another element.
nativeButtonbooleantrueWhether the item renders a native <button>.
renderReactElement | ((props, state) => ReactElement)—Replaces the item element.
refRef<HTMLButtonElement>—Ref forwarded to the item element.
classNamestring—Tailwind classes merged into the item root.
styleCSSProperties—Inline styles merged into the same element as className.
ui{ item?: ClassValue; content?: ClassValue; icon?: ClassValue; label?: ClassValue }—Tailwind classes for this item's internal slots, keyed by data-slot.

Items do not accept pressed or defaultPressed; the group value / defaultValue is the single source of truth for selection. Root ui is merged into every item first, then the item's ui, then the item's className.

AttributeDescription
data-disabledPresent when the group or an item is disabled.
data-orientationIndicates the orientation (horizontal or vertical).
data-multiplePresent when the group allows multiple pressed items.
data-pressedPresent on a pressed item.
data-slotMarks internal parts (root, glass, rim, item, content, icon, label).

Theming

The component uses the shared glass material. Tune shared --ui-glass-* tokens on a parent, use className for layout, and use ui for internal slots keyed by data-slot. Component-specific values live in src/theme/toggle-group.ts. See the theming guide for token layers and presets.

  • Toggle — For a single pressed button.
  • Tabs — For switching between content panels.
  • Radio Group — For a form choice among exclusive options.