# Label

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

Rótulo de campo de formulário, em caixa alta pequena, com os estados que um rótulo precisa: obrigatório, opcional, com erro, desabilitado e com uma linha de ajuda.

- Função: Formulário e ação
- Também chamado de: rótulo, label, legenda do campo
- Mora em: `app/components/atoms/Label.tsx`
- Página: [https://phorte-design-system.vercel.app/styleguide/peca/Label](https://phorte-design-system.vercel.app/styleguide/peca/Label)
- Ficha no Storybook: [components-base-label](https://main--69b4847d498a9bd8659db9ba.chromatic.com/?path=/docs/components-base-label--docs)
- Prévia ao vivo, sozinha: [https://phorte-design-system.vercel.app/previa/Label/0](https://phorte-design-system.vercel.app/previa/Label/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 { Label } from '@/app/components/atoms/Label';

<Label>…</Label>
```

## Uso

### Variantes na ficha

1. [Padrão](https://phorte-design-system.vercel.app/previa/Label/0)
2. [Obrigatório](https://phorte-design-system.vercel.app/previa/Label/1)
3. [Opcional](https://phorte-design-system.vercel.app/previa/Label/2)
4. [Com erro](https://phorte-design-system.vercel.app/previa/Label/3)
5. [Desabilitado](https://phorte-design-system.vercel.app/previa/Label/4)
6. [Com ajuda](https://phorte-design-system.vercel.app/previa/Label/5)
7. [Num formulário](https://phorte-design-system.vercel.app/previa/Label/6)
8. [Legenda do asterisco](https://phorte-design-system.vercel.app/previa/Label/7)

Para rotular um campo quando o FormField não serve — um controle composto, ou um layout que separa rótulo e campo.

### Quando não usar

No caso comum, use o FormField: ele já traz o Label, liga o `htmlFor` e passa o estado de erro. No Checkbox, no Radio e no Toggle o rótulo já vem pela prop `label`.

### Faça

- Ligue ao campo por `htmlFor` — é o que faz o clique no rótulo focar o campo e o leitor ler o nome.
- Use `opcional` quando quase tudo for obrigatório, e `required` quando quase tudo for opcional.
- Aponte o `aria-describedby` do campo para a ajuda: passe `idDaAjuda`, ou use o id que o Label gera sozinho (E59).
- Com asterisco, ponha uma vez a `LegendaDeObrigatorio` ("* indica campo obrigatório") no topo do formulário.
- Use `as="legend"` para o título de um grupo — é o que o FormField em `fieldset` e o RadioGroup fazem.

### Evite

- Usar `estado="desabilitado"` solto, sem campo `disabled` ligado: o texto esmaecido fica abaixo de 4,5:1 e só é isento quando faz parte de um controle inativo.
- Marcar `required` e `opcional` juntos — o tipo não deixa (E59).
- Rótulo longo: ele é caixa alta de 12px (`text-rotulo`), feito para duas ou três palavras.

### Anatomia

1. **Ícone de erro** — Só com `estado="erro"`, antes do texto.
2. **Texto** — 12px (`text-rotulo`, o piso do sistema), negrito, caixa alta, espaçamento largo, entrelinha de texto.
3. **Marca** — Asterisco vermelho (`required`) ou "(opcional)" em caixa normal.
4. **Ajuda** — Linha embaixo, com ícone de informação, em `text-xs`.

### Estados

| Estado | O que muda |
| --- | --- |
| Padrão | Texto `--muted-foreground`. |
| Obrigatório | Asterisco vermelho, escondido do leitor, e "(obrigatório)" só para o leitor. |
| Opcional | "(opcional)" escrito, em cinza e caixa normal. |
| Erro | `estado="erro"`: texto vermelho de interface e ícone de alerta. |
| Desabilitado | `estado="desabilitado"`: 70% de opacidade e cursor proibido. |

### Comportamento

| Situação | O que acontece |
| --- | --- |
| Clique no rótulo | Foca o campo ligado por `htmlFor` — é um `<label>` nativo. |
| Com `ajuda` | O rótulo e a ajuda passam a vir num invólucro em coluna; a ajuda recebe o `idDaAjuda`. |

### Relacionados

- [FormField](https://phorte-design-system.vercel.app/styleguide/md/FormField.md) — Já traz o Label ligado ao campo.
- [Input](https://phorte-design-system.vercel.app/styleguide/md/Input.md) — O campo mais comum que ele rotula.

## Especificação

### Propriedades

| Prop | Tipo | Padrão | Obrigatória | Descrição |
| --- | --- | --- | --- | --- |
| `estado` | `'padrao' \| 'erro' \| 'desabilitado'` | `'padrao'` | não | Variante do `cva`. |
| `as` | `'label' \| 'legend'` | `'label'` | não | `legend` para servir de título de um `<fieldset>` (E59). |
| `ajuda` | `React.ReactNode` | — | não | Texto de apoio embaixo do rótulo. |
| `idDaAjuda` | `string` | — | não | `id` da linha de ajuda, para o `aria-describedby` do campo. Sem ele, é gerado. |

Aceita também: `React.LabelHTMLAttributes<HTMLLabelElement>, | { required?: false; opcional?: boolean } | { required: true; opcional?: never }`.

### Tokens de cor

| Token | Valor | Usado como |
| --- | --- | --- |
| `--destructive` | #BA0517 | `text-destructive` |
| `--muted-foreground` | #595959 | `text-muted-foreground` |

## Acessibilidade

### Leitor de tela

- O asterisco é `aria-hidden`; a palavra "(obrigatório)" entra no nome por um texto só para leitor de tela. A semântica de obrigatório vem do `aria-required` que o FormField põe no campo.
- O rótulo não recebe foco: é lido junto com o campo que ele nomeia.

### O que sustenta o estado

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

## Status e recursos

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

- `fdd10ff` 2026-09-29 — ESTADO: E109 concluida, roteiro final fechado; proximo o merge na main
- Histórico completo no GitHub: https://github.com/srbunnie/Pos-Phorte-Design-System/commits/main/app/components/atoms/Label.tsx
