Forms
ToggleGroup
Conjunto coordenado de Toggles — alinhamento, formatação combinada, filtros.
Overview
ToggleGroup é um conjunto de Toggles coordenados via
context — variant, size e spacing definidos no Root propagam
para todos os Items. Use type="single" para escolha exclusiva
(alinhamento, modo de visualização) ou type="multiple" para
formatações combináveis (bold + italic + underline).
A diferença em relação a RadioGroup: RadioGroup é form-bound (label-led, captura no submit). ToggleGroup é stateful UI (ícone-led, efeito imediato).
Preview
Alinhamento de texto — single, outline.
Anatomy
<ToggleGroup type="single" | "multiple" variant size spacing>
└─ <ToggleGroupItem value="x"> ← um por opção
</ToggleGroup>Quando spacing=0 (default) + variant="outline", os items se colam
em "segmented control"; com spacing>0 viram chips separados.
Usage
import { ToggleGroup, ToggleGroupItem } from "@kalvner/kds/forms/toggle-group";
export function Alignment({ value, onValueChange }) {
return (
<ToggleGroup
type="single"
value={value}
onValueChange={onValueChange}
variant="outline"
aria-label="Alinhamento"
>
<ToggleGroupItem value="left" aria-label="Esquerda">L</ToggleGroupItem>
<ToggleGroupItem value="center" aria-label="Centro">C</ToggleGroupItem>
<ToggleGroupItem value="right" aria-label="Direita">R</ToggleGroupItem>
</ToggleGroup>
);
}Props
ToggleGroup (Root)
| Prop | Tipo | Default | Descrição |
|---|---|---|---|
type | 'single' | 'multiple' | — | Modo (radio-like vs. checkbox-like). |
value / defaultValue | string | string[] | — | Valor(es) ativo(s). |
onValueChange | (v) => void | — | Callback. |
variant | 'default' | 'outline' | 'default' | Propaga aos Items. |
size | 'sm' | 'default' | 'lg' | 'default' | Propaga aos Items. |
spacing | number | 0 | Gap entre items. 0 = segmented; >0 = chips. |
disabled | boolean | false | Bloqueia toda a árvore. |
aria-label | string | — | Obrigatório (descreve o grupo). |
ToggleGroupItem
| Prop | Tipo | Default | Descrição |
|---|---|---|---|
value | string | — | Identificador único. |
disabled | boolean | false | Bloqueia este item. |
aria-label | string | — | Obrigatório quando só ícone. |
Subcomponents
ToggleGroupItem— herdavariant,sizeespacingdo Root via context. Você pode passarvariant/sizepor item para override.
Variants
Single
Exclusivo — um item ativo por vez.
Multiple
Combinável — bold + italic juntos.
States
| Estado | Comportamento |
|---|---|
Item data-state=off | Aparência neutra. |
Item data-state=on | Background accent, foreground accent-foreground. |
disabled | Toda a árvore bloqueada. |
spacing=0 + outline | Borders compartilhados (segmented control). |
Composition
Em barras de formatação, separe grupos relacionados com pequeno gap:
<div className="flex items-center gap-2">
<ToggleGroup type="multiple" aria-label="Estilo">
<ToggleGroupItem value="bold"><Bold /></ToggleGroupItem>
<ToggleGroupItem value="italic"><Italic /></ToggleGroupItem>
</ToggleGroup>
<Separator orientation="vertical" className="h-6" />
<ToggleGroup type="single" aria-label="Alinhamento">
<ToggleGroupItem value="left"><AlignLeft /></ToggleGroupItem>
<ToggleGroupItem value="center"><AlignCenter /></ToggleGroupItem>
</ToggleGroup>
</div>When to use
- Toolbar de editor (formatação, alinhamento).
- Modo de visualização (grade / lista / kanban).
- Filtros combináveis em listas.
- "Quick filters" em dashboards (Hoje / Semana / Mês — type="single").
When not to use
- Form-bound exclusivo — use RadioGroup.
- Form-bound múltiplo — use Checkbox em grupo.
- Navegação entre painéis — use Tabs.
- Mais de ~6 itens — vira sopa visual; troque por Select.
Best practices
aria-labelno Root é obrigatório — descreve o grupo ("Alinhamento", "Formatação").- Items com só ícone também precisam de
aria-labelpróprio. - Para "segmented control", mantenha
spacing=0+variant="outline". - Para chips de filtro independentes, use Toggles soltos, não ToggleGroup — chips de filtros raramente são exclusivos.
Accessibility
| Concern | Comportamento |
|---|---|
| Roles | Root é group; type="single" faz items virarem role="radio" num roving group. |
| Keyboard | ← → (↑ ↓) navegam entre items, Space/Enter alterna. |
| Focus | Roving — só um item no tab order de cada vez. |
| Label | aria-label no Root + por item (se ícone-only) — ambos obrigatórios. |
Related
- Toggle — botão isolado.
- RadioGroup — exclusivo form-bound.
- Tabs — troca de painel inteiro.