Toggle Group
Single or multiple selection group built from toggle items.
npx shadcn@latest add @aavya/ui-toggle-group
One-time setup — add the @aavya registry to your components.json so branded dependencies resolve to Aavya (not stock shadcn):
"registries": { "@aavya": "https://registry-dev.aavya.com/r/{name}.json" }Or install by full URL: npx shadcn@latest add https://registry-dev.aavya.com/r/ui-toggle-group.json
| Prop | Type | Default |
|---|---|---|
| spacing? | number | 0 |
ToggleGroup forwards remaining props to ToggleGroupPrimitive.Root props.
Do
- Use single mode for mutually-exclusive options (a segmented control), multiple for independent toggles.
- Give every item an accessible label — especially icon-only toggles.
- Show a clear pressed/selected state beyond color alone.
Don’t
- Don't use a toggle group for navigation or one-shot actions — use buttons or links.
- Don't mix single and multiple semantics in one group.
- Don't ship icon-only toggles without labels.
Role
Group of toggle buttons; single mode uses radio semantics (handled by Radix).
Keyboard
Arrow keys move between items; Space/Enter toggle. (handled)
Screen reader
Each item announces its pressed state; give icon-only items an aria-label — you provide this.
Focus
A roving tabindex keeps one tab stop for the whole group. (handled)
Gotcha
Icon-only items have no text — without an aria-label they're announced as unlabelled buttons.
import { ToggleGroup } from '@/components/ui/toggle-group'
export default function Example() {
return (
<div className="p-6">
<ToggleGroup />
</div>
)
}
'use client'
import * as React from 'react'
import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group'
import { type VariantProps } from 'class-variance-authority'
import { cn } from '@/lib/utils'
import { toggleVariants } from '@/components/ui/toggle'
const ToggleGroupContext = React.createContext<
VariantProps<typeof toggleVariants> & {
spacing?: number
}
>({
size: 'default',
variant: 'default',
spacing: 0
})
function ToggleGroup({
className,
variant,
size,
spacing = 0,
children,
...props
}: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &
VariantProps<typeof toggleVariants> & {
spacing?: number
}) {
return (
<ToggleGroupPrimitive.Root
data-slot='toggle-group'
data-variant={variant}
data-size={size}
data-spacing={spacing}
style={{ '--gap': spacing } as React.CSSProperties}
className={cn(
'group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-md data-[spacing=default]:data-[variant=outline]:shadow-xs',
className
)}
{...props}
>
<ToggleGroupContext.Provider value={{ variant, size, spacing }}>{children}</ToggleGroupContext.Provider>
</ToggleGroupPrimitive.Root>
)
}
function ToggleGroupItem({
className,
children,
variant,
size,
...props
}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> & VariantP