Toggle Group
A group of toggle buttons where one or multiple items can be active at a time.
import * as ToggleGroup from '@gentleduck/primitives/toggle-group'import * as ToggleGroup from '@gentleduck/primitives/toggle-group'Anatomy
<ToggleGroup.Root>
<ToggleGroup.Item />
</ToggleGroup.Root><ToggleGroup.Root>
<ToggleGroup.Item />
</ToggleGroup.Root>Example
Single selection
import * as ToggleGroup from '@gentleduck/primitives/toggle-group'
import { AlignLeft, AlignCenter, AlignRight } from 'lucide-react'
function TextAlign() {
return (
<ToggleGroup.Root type="single" defaultValue="left" className="flex gap-1">
<ToggleGroup.Item value="left" aria-label="Align left" className="rounded p-2 data-[state=on]:bg-accent">
<AlignLeft className="size-4" />
</ToggleGroup.Item>
<ToggleGroup.Item value="center" aria-label="Align center" className="rounded p-2 data-[state=on]:bg-accent">
<AlignCenter className="size-4" />
</ToggleGroup.Item>
<ToggleGroup.Item value="right" aria-label="Align right" className="rounded p-2 data-[state=on]:bg-accent">
<AlignRight className="size-4" />
</ToggleGroup.Item>
</ToggleGroup.Root>
)
}import * as ToggleGroup from '@gentleduck/primitives/toggle-group'
import { AlignLeft, AlignCenter, AlignRight } from 'lucide-react'
function TextAlign() {
return (
<ToggleGroup.Root type="single" defaultValue="left" className="flex gap-1">
<ToggleGroup.Item value="left" aria-label="Align left" className="rounded p-2 data-[state=on]:bg-accent">
<AlignLeft className="size-4" />
</ToggleGroup.Item>
<ToggleGroup.Item value="center" aria-label="Align center" className="rounded p-2 data-[state=on]:bg-accent">
<AlignCenter className="size-4" />
</ToggleGroup.Item>
<ToggleGroup.Item value="right" aria-label="Align right" className="rounded p-2 data-[state=on]:bg-accent">
<AlignRight className="size-4" />
</ToggleGroup.Item>
</ToggleGroup.Root>
)
}Multiple selection
function FormatOptions() {
return (
<ToggleGroup.Root type="multiple" className="flex gap-1">
<ToggleGroup.Item value="bold" className="rounded p-2 data-[state=on]:bg-accent">B</ToggleGroup.Item>
<ToggleGroup.Item value="italic" className="rounded p-2 data-[state=on]:bg-accent">I</ToggleGroup.Item>
<ToggleGroup.Item value="underline" className="rounded p-2 data-[state=on]:bg-accent">U</ToggleGroup.Item>
</ToggleGroup.Root>
)
}function FormatOptions() {
return (
<ToggleGroup.Root type="multiple" className="flex gap-1">
<ToggleGroup.Item value="bold" className="rounded p-2 data-[state=on]:bg-accent">B</ToggleGroup.Item>
<ToggleGroup.Item value="italic" className="rounded p-2 data-[state=on]:bg-accent">I</ToggleGroup.Item>
<ToggleGroup.Item value="underline" className="rounded p-2 data-[state=on]:bg-accent">U</ToggleGroup.Item>
</ToggleGroup.Root>
)
}API
ToggleGroup.Root
The root container. Renders a <div>. Supports two modes: single and multiple.
Single mode
| Prop | Type | Default | Description |
|---|---|---|---|
type | 'single' | -- | Only one item can be active |
value | string | -- | Controlled active value |
defaultValue | string | -- | Initial active value |
onValueChange | (value: string) => void | -- | Called when active value changes |
Multiple mode
| Prop | Type | Default | Description |
|---|---|---|---|
type | 'multiple' | -- | Multiple items can be active |
value | string[] | -- | Controlled active values |
defaultValue | string[] | -- | Initial active values |
onValueChange | (value: string[]) => void | -- | Called when active values change |
Shared props
| Prop | Type | Default | Description |
|---|---|---|---|
rovingFocus | boolean | true | Enable roving focus keyboard navigation |
disabled | boolean | false | Disables the entire group |
orientation | 'horizontal' | 'vertical' | -- | Arrow key navigation direction |
dir | 'ltr' | 'rtl' | -- | Text direction |
loop | boolean | true | Keyboard navigation wraps around |
asChild | boolean | -- | Render as child element |
Exposes data-orientation attribute.
ToggleGroup.Item
An individual toggle button within the group. Renders a <button>.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | -- | Required. Unique value for this item |
disabled | boolean | -- | Disables this item (inherits from group) |
asChild | boolean | -- | Render as child element |
Exposes aria-pressed (multiple mode), role="radio" (single mode), data-state (on | off), and data-disabled attributes.
Keyboard interactions
| Key | Action |
|---|---|
| Tab | Moves focus into the group and to the active item |
| ArrowRight | Moves focus to the next item (horizontal) |
| ArrowLeft | Moves focus to the previous item (horizontal) |
| ArrowDown | Moves focus to the next item (vertical) |
| ArrowUp | Moves focus to the previous item (vertical) |
| Home | Moves focus to the first item |
| End | Moves focus to the last item |
| Space / Enter | Toggles the focused item |