Forms
RadioGroup
Grupo de opções mutuamente exclusivas — uma única seleção, sempre visível.
Overview
RadioGroup é o RadioGroup.Root do Radix. O componente raiz mantém
o valor selecionado e cada RadioGroupItem representa uma opção.
Apenas um item pode estar ativo em qualquer momento.
A regra prática: use RadioGroup quando você tem 5 ou menos opções
e ver todas ajuda a decidir (planos, modos de envio, formatos). Para
listas mais longas — países, fusos, categorias com 20+ — prefira
Select, que reserva pouco espaço vertical.
Preview
RadioGroup com duas opções.
Anatomy
<RadioGroup defaultValue="...">
<RadioGroupItem value="opt-a" id="opt-a" />
<Label htmlFor="opt-a">Texto da opção</Label>
...
</RadioGroup>Subcomponents
| Componente | Descrição |
|---|---|
RadioGroup | Raiz que mantém valor + onChange. |
RadioGroupItem | Cada opção individual. |
Usage
import { RadioGroup, RadioGroupItem } from "@kalvner/kds/forms/radio-group";
import { Label } from "@kalvner/kds/forms/label";
export function PlanField() {
return (
<RadioGroup defaultValue="month">
<div className="flex items-center gap-2">
<RadioGroupItem value="month" id="month" />
<Label htmlFor="month">Mensal</Label>
</div>
<div className="flex items-center gap-2">
<RadioGroupItem value="year" id="year" />
<Label htmlFor="year">Anual</Label>
</div>
</RadioGroup>
);
}Props
RadioGroup
| Prop | Tipo | Default | Descrição |
|---|---|---|---|
value | string | — | Valor selecionado (controlado). |
defaultValue | string | — | Valor inicial (não controlado). |
onValueChange | (v: string) => void | — | Callback de mudança. |
disabled | boolean | false | Desabilita todos os items. |
required | boolean | false | Pelo menos um item deve ser selecionado. |
name | string | — | Nome do form, para FormData. |
RadioGroupItem
| Prop | Tipo | Default | Descrição |
|---|---|---|---|
value | string | — | Valor único do item. |
disabled | boolean | false | Desabilita só este item. |
id | string | — | Vincula ao Label. |
Variants
Inline labels
Padrão simples — bola + texto.
With descriptions
Cada opção com helper text.
States
Disabled
Todos os items dim.
Error
aria-invalid em cada Item.
Composition
Plan picker
Cards inteiros clicáveis com borda primary quando selecionado.
When to use
- Escolha exclusiva entre 2–5 opções.
- Quando ver todas as opções de uma vez ajuda a decidir.
- Em pricing, modos de envio, formatos, configurações curtas.
When not to use
- Para listas longas (>5–7 opções) — prefira
Select. - Para múltipla seleção — use
Checkbox. - Para alternar uma flag — use
Switch. - Para grids visuais (escolha de tema, avatar) — Custom card grid
com
aria-pressedé mais apropriado que radio.
Best practices
- Sempre tenha um valor padrão. Um RadioGroup vazio força o usuário a clicar para "começar" — escolha o default mais comum ou o mais barato.
- Labels curtas. Cabeçalho da opção em uma linha; descrição vai como helper, não no Label principal.
- Consistência vertical. Todas as opções com a mesma altura ou clicáveis em toda a área. Mistura confunde.
Accessibility
| Concern | Comportamento |
|---|---|
| Roles | Radix gera role="radiogroup" + role="radio" em cada item. |
| Keyboard | Tab entra no grupo; setas (↑↓ ou ←→) navegam entre opções; Space seleciona. |
| Roving tabindex | Apenas o item ativo (ou o primeiro em grupo vazio) é tabbable. Padrão Radix. |
| Group label | Use <fieldset><legend> para legendas semânticas, ou aria-labelledby apontando para um título externo. |
| Erro | aria-invalid em cada item + mensagem via aria-describedby. |