Skip to main content

toggle group

A set of two-state buttons that can be toggled on or off.

Philosophy

When multiple toggles share context, they become a group. ToggleGroup manages mutual exclusivity (single mode) or multi-selection, keeping the state logic out of your components. Built on @gentleduck/primitives/toggle-group with roving focus keyboard navigation — arrow keys move between items, Space/Enter toggles them.

How It's Built

Loading diagram...

Installation


npx @gentleduck/cli add toggle-group

npx @gentleduck/cli add toggle-group

Usage

import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'
<ToggleGroup type="single">
  <ToggleGroupItem value="a">A</ToggleGroupItem>
  <ToggleGroupItem value="b">B</ToggleGroupItem>
  <ToggleGroupItem value="c">C</ToggleGroupItem>
</ToggleGroup>
<ToggleGroup type="single">
  <ToggleGroupItem value="a">A</ToggleGroupItem>
  <ToggleGroupItem value="b">B</ToggleGroupItem>
  <ToggleGroupItem value="c">C</ToggleGroupItem>
</ToggleGroup>

Examples

Default

Outline

Single

Small

Large

Disabled

Keyboard Navigation

KeyDescription
TabMoves focus into the toggle group (focuses the active or first item)
ArrowRightMoves focus to the next item
ArrowLeftMoves focus to the previous item
ArrowDownMoves focus to the next item
ArrowUpMoves focus to the previous item
HomeMoves focus to the first item
EndMoves focus to the last item
Space / EnterToggles the focused item

API Reference

ToggleGroup

PropTypeDefaultDescription
type'single' | 'multiple'(required)Determines selection behavior. 'single' allows one toggle at a time; 'multiple' allows multiple
valuestring | string[]--Controlled selected value(s)
defaultValuestring | string[]--Uncontrolled initial selected value(s)
onValueChange(value: string | string[]) => void--Callback invoked when the value changes
variant'default' | 'outline''default'Visual style variant for the toggles (passed to items via context)
size'default' | 'sm' | 'lg''default'Size variant for the toggles (passed to items via context)
disabledbooleanfalseDisables all items in the group
rovingFocusbooleantrueWhether to use roving focus for keyboard navigation
loopbooleantrueWhether keyboard navigation should loop at boundaries
orientation'horizontal' | 'vertical'--The orientation of the group for arrow key navigation
dir'ltr' | 'rtl'--Text direction. Resolved by primitives useDirection (dir prop -> DirectionProvider -> 'ltr').
classNamestring--Additional CSS class names to apply
childrenReact.ReactNode--ToggleGroupItem elements to render inside the group
refReact.Ref<HTMLDivElement>--Ref forwarded to the underlying div element

ToggleGroupItem

PropTypeDefaultDescription
valuestring(required)The unique value identifying this toggle item
variant'default' | 'outline'--Visual style variant for this item (overrides group context)
size'default' | 'sm' | 'lg'--Size variant for this item (overrides group context)
disabledbooleanfalseDisables this specific item
classNamestring--Additional CSS class names to apply
childrenReact.ReactNode--Content rendered inside the toggle item
refReact.Ref<HTMLButtonElement>--Ref forwarded to the underlying button element

Data Attributes

AttributeValuesDescription
data-state"on" | "off"The pressed state of the item
data-disabledPresent when disabledWhether the item is disabled

RTL Support

Set dir="rtl" on ToggleGroup for a local override, or set DirectionProvider once at app/root level for global direction.