Toggle Group
Toggles and segmented controls with a lit pill that slides to the selection.
Installs motion.
This week
286 deploys
+14% on last week
Release notes go out with the 2.4 build on Thursday. Flag anything that should wait for 2.5.
Installation
npx shadcn@latest add https://neonkit.heyaadi.com/r/toggle-group.jsonUsage
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
<ToggleGroup aria-label="Range" defaultValue="week">
<ToggleGroupItem value="day">Day</ToggleGroupItem>
<ToggleGroupItem value="week">Week</ToggleGroupItem>
<ToggleGroupItem value="month">Month</ToggleGroupItem>
</ToggleGroup>Examples
Toggle
A single on/off button with aria-pressed, in the default and outline variants.
Variants
Segmented for switching views, outline for attached settings, ghost for toolbars.
Vertical
orientation="vertical" stacks the items and moves the arrow keys to Up and Down.
Sizes
32, 40 and 48px tall, so a segmented control lines up with inputs and buttons.
API reference
ToggleGroup
Renders a div and accepts every native div attribute. Give it an aria-label or aria-labelledby.
| Prop | Type | Default |
|---|---|---|
type | "single"Single acts as a radio group; multiple is a toolbar of pressed buttons. | "single" |
value | stringControlled value. An array when type is multiple. | None |
defaultValue | stringInitial value when uncontrolled. | None |
onValueChange | (value: string) => voidCalled with the new value. Single never deselects, like a radio group. | None |
variant | "segmented"Track with a sliding pill, attached cells with a lit edge, or bare items. | "segmented" |
size | "sm"Overall height: 32, 40 or 48px. | "md" |
orientation | "horizontal"Layout direction and which arrow keys move between items. | "horizontal" |
disabled | booleanDisables every item. | false |
name | stringSubmits the selected value, one entry per value for multiple, with a surrounding form. A form reset puts back the starting selection. | None |
color | NeonColorPalette name or hex. Falls back to --neon-accent, then cyan. | inherited |
ToggleGroupItem
Renders a button. Icon-only items need an aria-label.
| Prop | Type | Default |
|---|---|---|
value | stringUnique value within the group. | None |
disabled | booleanSkipped by the arrow keys and can't be pressed. | false |
Toggle
A standalone pressable button. Accepts every native button attribute.
| Prop | Type | Default |
|---|---|---|
pressed | booleanControlled state. | None |
defaultPressed | booleanInitial state when uncontrolled. | false |
onPressedChange | (pressed: boolean) => voidCalled when it's pressed or released. | None |
variant | "default"Bare or bordered. | "default" |
size | "sm"32, 40 or 48px tall; icon-only toggles are square. | "md" |
color | NeonColorPalette name or hex. Falls back to --neon-accent, then cyan. | inherited |
Accessibility
- Items in a row get an invisible target at least 44px tall, so the 24px small segments are still easy to tap.
- Single groups are a radiogroup of radio items with aria-checked; multiple groups are a toolbar of buttons with aria-pressed.
- The group is one Tab stop. Arrow keys move between items and wrap, Home and End jump to the ends, and disabled items are skipped.
- In a single group, moving with the arrows also selects, as in a native radio group. In a toolbar the arrows only move focus; Space or Enter presses.
- A radio group answers both arrow pairs; a toolbar only the pair along its orientation.
- The sliding pill and the power-on flicker are turned off under prefers-reduced-motion.