Toggle Group

A set of toggles where one or multiple can be pressed. Inherits Toggle's variant/size via context. Useful for alignment/formatting toolbars.

Single-select (text alignment)

Multi-select (formatting marks)

Sizes

Installation

pnpm
pnpm dlx @hex-core/cli add toggle-group

Formatting group

Multiple-select toggle group for text formatting

tsx
<ToggleGroup type="multiple">
  <ToggleGroupItem value="bold" aria-label="Bold">B</ToggleGroupItem>
  <ToggleGroupItem value="italic" aria-label="Italic">I</ToggleGroupItem>
  <ToggleGroupItem value="underline" aria-label="Underline">U</ToggleGroupItem>
</ToggleGroup>

Single-selection toolbar (controlled)

Editor-style alignment toolbar with icons and controlled state — pairs ToggleGroup with your editor model

tsx
const ALIGNMENTS = ["left", "center", "right"] as const;
type Align = (typeof ALIGNMENTS)[number];
const isAlign = (v: string): v is Align =>
  (ALIGNMENTS as readonly string[]).includes(v);

function AlignmentToolbar() {
  const [align, setAlign] = React.useState<Align>("left");
  return (
    <ToggleGroup
      type="single"
      value={align}
      onValueChange={(value) => {
        if (isAlign(value)) setAlign(value);
      }}
      variant="outline"
    >
      <ToggleGroupItem value="left" aria-label="Align left">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><line x1="21" y1="6" x2="3" y2="6" /><line x1="15" y1="12" x2="3" y2="12" /><line x1="17" y1="18" x2="3" y2="18" /></svg>
      </ToggleGroupItem>
      <ToggleGroupItem value="center" aria-label="Align center">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><line x1="21" y1="6" x2="3" y2="6" /><line x1="18" y1="12" x2="6" y2="12" /><line x1="19" y1="18" x2="5" y2="18" /></svg>
      </ToggleGroupItem>
      <ToggleGroupItem value="right" aria-label="Align right">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><line x1="21" y1="6" x2="3" y2="6" /><line x1="21" y1="12" x2="9" y2="12" /><line x1="21" y1="18" x2="7" y2="18" /></svg>
      </ToggleGroupItem>
    </ToggleGroup>
  );
}

API Reference

PropTypeDefaultDescription
typerequired
"single" | "multiple"Single allows one pressed at a time, multiple allows many
value
objectControlled pressed value(s). string when type='single', string[] when type='multiple'
defaultValue
objectDefault pressed value(s). string when type='single', string[] when type='multiple'
onValueChange
functionCallback on value change
variant
"default" | "outline"defaultInherited by all ToggleGroupItems
size
"default" | "sm" | "lg"defaultInherited by all ToggleGroupItems
disabled
booleanfalseDisable all items

AI Guidance

When to use

Use for toolbar toggles where users pick one of many (type='single') or multiple (type='multiple'): text alignment, formatting (bold/italic/underline), view modes.

When not to use

Don't use for form radio fields (use RadioGroup). Don't use for standalone two-state buttons (use Toggle). Don't use for navigation (use Tabs).

Common mistakes

  • Forgetting the type prop (required)
  • Missing aria-label on icon-only items
  • Using for form submission without name prop

Accessibility

Radix implements the WAI-ARIA toolbar pattern with roving focus. Arrow keys move focus, Space/Enter toggles. Each icon-only item needs aria-label.

Related components

Token budget: 500