Radio
Em andamentoOpção de escolha única dentro de um grupo: marcar uma desmarca as outras. Tem rótulo e uma linha de descrição opcional, fora do nome.
- Função
- Formulário e ação
- Também chamado de
- botão de opção, radio, escolha única
- Mora em
- app/components/atoms/Radio.tsx
- Última mudança
- 2026-09-30
Prévia
A peça ao vivo, vinda da ficha, na largura escolhida. Em larguras fixas, ela roda num quadro do tamanho de uma tela de verdade.
Na largura da página: 0px
Variantes na ficha
Lidas da ficha no build, na ordem do palco. Cada uma abre sozinha, sem o styleguide em volta — é o endereço que o palco carrega.
Quando usar
Quando a pessoa escolhe **uma** entre poucas opções (até cinco ou seis) e vale a pena ver todas ao mesmo tempo.
Faça
- Agrupe no
RadioGroup(E59): ele monta o<fieldset>com<legend>, gera umnamesó e guarda a escolha (valueoudefaultValue). - Deixe uma opção marcada quando houver um padrão razoável.
- Use
descricaopara explicar a opção sem alongar o rótulo.
Evite
- Uma opção sozinha: sem outra, não há como desmarcar. Para sim/não isolado, Checkbox.
- Trocar a aparência sem redesenhar o foco: o
appearance-noneapaga o foco do navegador, e o anel de hoje é próprio. - Montar o grupo à mão com o mesmo
nameem grupos diferentes da página — viram um grupo só. O RadioGroup gera o nome.
Quando não usar. Para várias escolhas independentes, use o Checkbox. Para muitas opções, o Select. Para filtrar uma lista na hora, o FilterGroup.
Nota de uso
appearance-none apaga o foco que o navegador desenha, e por isso este componente ficou sem foco visível nenhum até a E08a. O anel de hoje é próprio. Se você trocar a aparência, redesenhe o foco junto. O rótulo é text-sm em caixa normal, como no Checkbox — era 10px em caixa alta, e é a própria resposta. descricao fica fora do nome e é ligada por aria-describedby. Agrupe com <fieldset> e <legend>.
Anatomia
As partes, na ordem em que o olho — e o teclado — passam.
- Círculo — 20px, borda de 2px; marcado, a borda e o centro em `--primary`, com 3px de `--card` entre eles — um ponto de 10px desenhado no próprio controle (E121), sempre concêntrico em qualquer zoom.
- Rótulo — Texto `text-sm`; a linha inteira é o `<label>`.
- Descrição — Linha embaixo, alinhada ao texto do rótulo, ligada por `aria-describedby`.
Estados
Os estados que a peça tem no código, e o que muda em cada um.
| Estado | O que muda |
|---|---|
| Desmarcado | Círculo vazio, borda --border-interactive. |
| Marcado | Borda --primary e ponto central de 10px. |
| Foco | Anel ring-ring de 2px, só no teclado. |
| Erro | aria-invalid: borda vermelha. |
| Desabilitado | Linha do controle a 50% e cursor proibido; a descrição não esmaece. |
Comportamento
| Situação | O que acontece |
|---|---|
| Marcar uma opção | Desmarca as outras do mesmo name — comportamento nativo. |
| Clique no texto | Marca — o rótulo é o <label> do controle. |
Relacionados
Como usar no código
A importação e o menor uso, lidos do arquivo. O … marca as props obrigatórias.
import { Radio } from '@/app/components/atoms/Radio';
<Radio />Propriedades
Lidas do código da peça no build — não escritas à mão.
| Prop | Tipo | Padrão | Obrigatória | Descrição |
|---|---|---|---|---|
label | React.ReactNode | — | não | — |
descricao | React.ReactNode | — | não | Linha de apoio embaixo do rótulo, ligada ao controle por aria-describedby. |
Aceita também: Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'>.
Medidas
| Parte | Valor | Classe |
|---|---|---|
| Círculo | 20 × 20px | size-5 |
| Ponto marcado | 10px | size-2.5 |
| Linha (alvo de toque) | 44px de altura | min-h-alvo-toque |
Tokens de cor
Os tokens semânticos que o código da peça usa, com o valor de hoje em app/globals.css.
| Token | Valor | Usado como |
|---|---|---|
--primary | #D42B2B | bg-primaryborder-primary |
--border-interactive | #8C8C8C | border-border-interactive |
--card | #FFFFFF | bg-card |
--destructive | #BA0517 | border-destructive |
--foreground | #1A1A1A | text-ink |
--muted-foreground | #595959 | text-muted-foreground |
Teclado
| Tecla | Faz |
|---|---|
| Tab | Entra no grupo pela opção marcada (ou pela primeira, se nenhuma) e sai dele no próximo Tab: o grupo inteiro é uma parada — medido. |
| ↓→ | Vai para a próxima opção **e a marca**; da última volta à primeira — medido. |
| ↑← | Vai para a opção anterior e a marca; da primeira vai à última. |
| Espaço | Marca a opção em foco, quando ela ainda não está marcada. |
Leitor de tela
O que é anunciado, e por quê.
- A
descricaofica fora do<label>e é ligada poraria-describedby: dentro, entraria no nome e seria lida a cada foco.
O que sustenta o estado
Esta peça usa formulario. O estado dela é o de quem já foi ouvido com leitor de tela nesses padrões — e não uma passada sobre esta peça em específico.
Falta ouvir: formulario — ver docs/a11y-screen-reader-checklist.md.
Status e recursos
| Tipo | Recurso | Status |
|---|---|---|
| Código | app/components/atoms/Radio.tsx | Disponível |
| Ficha | Storybook (abre em outra aba) | Disponível |
| Teste de acessibilidade | axe em npm run test | No gate de todo commit |
| Leitor de tela | Passada da E33 | Falta ouvir |
| Design | Figma | Desativado até a Fase 2 |
Histórico
Os últimos commits que tocaram o arquivo, lidos do git no build.
0298af82026-09-30E147: fechamento da Entrega 11 — REPORT.md, verificação cross-agent e o gate estático estrito
O histórico completo está no GitHub (abre em outra aba).