Inputs
Toggle group
A set of toggles where one or several can be pressed. With spacing 0 and the outline variant it is a segmented control.
npx prodular-ui add toggle-groupSegmented control
variant outline with spacing 0. Keep one item pressed.
"use client"
import * as React from "react"import { CalendarDaysIcon, KanbanIcon, ListIcon } from "lucide-react"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
export default function ToggleGroupSegmented() { const [view, setView] = React.useState(["board"]) const [range, setRange] = React.useState(["30d"]) return ( <div className="flex flex-col items-center gap-4"> <ToggleGroup variant="outline" spacing={0} value={view} onValueChange={(v) => v.length && setView(v)} aria-label="View" > <ToggleGroupItem value="list"> <ListIcon data-icon="inline-start" /> List </ToggleGroupItem> <ToggleGroupItem value="board"> <KanbanIcon data-icon="inline-start" /> Board </ToggleGroupItem> <ToggleGroupItem value="calendar"> <CalendarDaysIcon data-icon="inline-start" /> Calendar </ToggleGroupItem> </ToggleGroup> <ToggleGroup variant="outline" size="sm" spacing={0} value={range} onValueChange={(v) => v.length && setRange(v)} aria-label="Date range" > <ToggleGroupItem value="7d">7 days</ToggleGroupItem> <ToggleGroupItem value="30d">30 days</ToggleGroupItem> <ToggleGroupItem value="90d">90 days</ToggleGroupItem> <ToggleGroupItem value="12m">12 months</ToggleGroupItem> </ToggleGroup> </div> )}Multiple and spaced
import { AlignCenterIcon, AlignLeftIcon, AlignRightIcon, BoldIcon, ItalicIcon, StrikethroughIcon } from "lucide-react"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
export default function ToggleGroupMultiple() { return ( <div className="flex flex-wrap items-center justify-center gap-6"> <ToggleGroup multiple defaultValue={["bold"]} spacing={1} aria-label="Text style"> <ToggleGroupItem value="bold" aria-label="Bold"> <BoldIcon /> </ToggleGroupItem> <ToggleGroupItem value="italic" aria-label="Italic"> <ItalicIcon /> </ToggleGroupItem> <ToggleGroupItem value="strike" aria-label="Strikethrough"> <StrikethroughIcon /> </ToggleGroupItem> </ToggleGroup> <ToggleGroup variant="outline" defaultValue={["left"]} aria-label="Alignment"> <ToggleGroupItem value="left" aria-label="Align left"> <AlignLeftIcon /> </ToggleGroupItem> <ToggleGroupItem value="center" aria-label="Align center"> <AlignCenterIcon /> </ToggleGroupItem> <ToggleGroupItem value="right" aria-label="Align right"> <AlignRightIcon /> </ToggleGroupItem> </ToggleGroup> </div> )}Anatomy
<ToggleGroup variant="outline" spacing={0} defaultValue={["board"]}> <ToggleGroupItem value="list">List</ToggleGroupItem> <ToggleGroupItem value="board">Board</ToggleGroupItem></ToggleGroup>Guidance
Use it when
- Switching views (list, board, calendar) or ranges (7, 30, 90 days) in place.
- Formatting groups where several can be on.
Avoid
- More than five options. Use Select.
- Navigation between pages. Use Tabs or links.
Rules for AI agents
Published in llms-full.txt and the registry, so coding agents follow them when they build with this component.
- The value is always an array, even for single selection. Read value[0].
- For a segmented control use variant="outline" spacing={0} and ignore empty changes so one option stays pressed.
- Pass multiple when several items can be pressed at once.
- Give the group an aria-label and icon-only items their own aria-label.
API
ToggleGroup
| Prop | Type | Default | Description |
|---|---|---|---|
| value / defaultValue | string[] | Pressed items. | |
| onValueChange | (value: string[]) => void | Called when the pressed items change. | |
| multiple | boolean | false | Allows several pressed items. |
| spacing | number | 2 | Gap on the spacing scale. 0 joins the items. |
| variant / size | "default" | "outline" / "sm" | "default" | "lg" | Applied to every item. | |
| orientation | "horizontal" | "vertical" | "horizontal" | Direction of the items. |