# Radio

> Componentes / Formulário e ação · Estado: **Em andamento** — Implementado e utilizável, mas ainda sem a validação completa de acessibilidade.

Opçã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`
- Página: [https://phorte-design-system.vercel.app/styleguide/peca/Radio](https://phorte-design-system.vercel.app/styleguide/peca/Radio)
- Ficha no Storybook: [components-base-radio](https://main--69b4847d498a9bd8659db9ba.chromatic.com/?path=/docs/components-base-radio--docs)
- Prévia ao vivo, sozinha: [https://phorte-design-system.vercel.app/previa/Radio/0](https://phorte-design-system.vercel.app/previa/Radio/0)
- Todas as peças: [https://phorte-design-system.vercel.app/llms.txt](https://phorte-design-system.vercel.app/llms.txt)

## Como usar no código

```tsx
import { Radio } from '@/app/components/atoms/Radio';

<Radio />
```

## Uso

### Variantes na ficha

1. [Padrão](https://phorte-design-system.vercel.app/previa/Radio/0)
2. [Marcado](https://phorte-design-system.vercel.app/previa/Radio/1)
3. [Desabilitado](https://phorte-design-system.vercel.app/previa/Radio/2)
4. [Com descrição](https://phorte-design-system.vercel.app/previa/Radio/3)
5. [Grupo](https://phorte-design-system.vercel.app/previa/Radio/4)
6. [Grupo com erro](https://phorte-design-system.vercel.app/previa/Radio/5)

Quando a pessoa escolhe **uma** entre poucas opções (até cinco ou seis) e vale a pena ver todas ao mesmo tempo.

### 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.

### Faça

- Agrupe no `RadioGroup` (E59): ele monta o `<fieldset>` com `<legend>`, gera um `name` só e guarda a escolha (`value` ou `defaultValue`).
- Deixe uma opção marcada quando houver um padrão razoável.
- Use `descricao` para 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-none` apaga o foco do navegador, e o anel de hoje é próprio.
- Montar o grupo à mão com o mesmo `name` em grupos diferentes da página — viram um grupo só. O RadioGroup gera o nome.

### 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

1. **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.
2. **Rótulo** — Texto `text-sm`; a linha inteira é o `<label>`.
3. **Descrição** — Linha embaixo, alinhada ao texto do rótulo, ligada por `aria-describedby`.

### Estados

| 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

- [Checkbox](https://phorte-design-system.vercel.app/styleguide/md/Checkbox.md) — Para várias escolhas independentes.
- [Select](https://phorte-design-system.vercel.app/styleguide/md/Select.md) — Para muitas opções.
- [FilterGroup](https://phorte-design-system.vercel.app/styleguide/md/FilterGroup.md) — Escolha única que filtra na hora.

## Especificação

### Propriedades

| 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

| Token | Valor | Usado como |
| --- | --- | --- |
| `--primary` | #D42B2B | `bg-primary`, `border-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` |

## Acessibilidade

### 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

- A `descricao` fica fora do `<label>` e é ligada por `aria-describedby`: dentro, entraria no nome e seria lida a cada foco.

### O que sustenta o estado

Usa os padrões: formulario. Falta ouvir com leitor de tela: formulario.

## Status e recursos

| Tipo | Recurso | Status |
| --- | --- | --- |
| Código | `app/components/atoms/Radio.tsx` | Disponível |
| Ficha | https://main--69b4847d498a9bd8659db9ba.chromatic.com/?path=/docs/components-base-radio--docs | 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

- `0298af8` 2026-09-30 — E147: fechamento da Entrega 11 — REPORT.md, verificação cross-agent e o gate estático estrito
- Histórico completo no GitHub: https://github.com/srbunnie/Pos-Phorte-Design-System/commits/main/app/components/atoms/Radio.tsx
