Textarea
Em andamentoCampo de texto de várias linhas — mensagem, justificativa, observação —, sobre o mesmo contrato visual do Input e do Select: borda de controle, foco em 2px e o vermelho só no erro.
- Função
- Formulário e ação
- Também chamado de
- área de texto, campo de mensagem, caixa de texto grande, textarea
- Mora em
- app/components/atoms/Textarea.tsx
- Última mudança
- 2026-09-29
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
Para resposta que pode passar de uma linha: a mensagem do "Fale conosco", a justificativa de um pedido de bolsa, uma observação.
Faça
- Use dentro de um FormField: o rótulo, a dica, o
contadore o erro vêm dele. - Dê
rowspelo tamanho que se espera da resposta (quatro por padrão). - Deixe a pessoa esticar na vertical (
redimensionar="vertical", o padrão). - Peça um tamanho com o
contadordo FormField (E152):{ maximo: 280 },{ minimo: 50 }ou os dois. Sematual, ele conta sozinho. Valide no envio comerroDeTamanho(app/lib/contagem-de-caracteres.ts), que diz o mesmo número. - Num formulário aberto ao público, ligue a proteção contra spam no formulário (E153):
useProtecaoContraSpamdá o campo-isca e o tempo mínimo, e os sinais vão com o envio para o serviço decidir. Nada para a pessoa resolver.
Evite
- Usar o
placeholdercomo instrução: ele some ao digitar. A instrução vai na dica do FormField. - Limitar com
maxLength: o texto colado é cortado sem aviso. Use ocontadorcommaximo— o texto continua entrando, o contador diz quanto passou e o envio recusa. - Mostrar o mínimo como erro enquanto a pessoa digita: abaixo do mínimo o contador informa, em cinza; o erro é do envio.
- Proteger com CAPTCHA, teste de lógica ou bloqueio de colar: é barreira cognitiva (SC 3.3.8), e quem paga é a pessoa, não o robô.
- Redimensionar na horizontal: quebra o layout — o componente não oferece.
Quando não usar. Para dado de uma linha (nome, e-mail, CPF), use o Input. Para escolher entre opções conhecidas, o Select ou o Radio.
Anatomia
As partes, na ordem em que o olho — e o teclado — passam.
- Caixa — Borda `--border-interactive`, cantos do campo (`rounded-campo`), `px-4 py-3`, entrelinha folgada.
- Alça — A do navegador, no canto de baixo, só na vertical.
Estados
Os estados que a peça tem no código, e o que muda em cada um.
| Estado | O que muda |
|---|---|
| Padrão | Borda de controle de 1px. |
| Foco | Borda --border-focus de 2px (sombra interna), só no teclado e no clique — pelo CSS, como o Select. |
| Erro | error ou aria-invalid do FormField: borda --destructive, e aria-invalid="true". |
| Desabilitado | A 50%, cursor proibido, fora do Tab. |
| Somente leitura | Borda tracejada e fundo --muted; continua no Tab e copiável. |
| Com contador | Embaixo do campo, pelo FormField: "N de 280 caracteres" (máximo), "faltam N para o mínimo de 50" (mínimo), ou os dois (E152). |
| Abaixo do mínimo | O contador em cinza, dizendo quanto falta. Não é erro: o campo não fica vermelho. |
| Acima do limite | O contador em vermelho, com o ícone e "N caracteres acima do limite". O texto continua entrando. |
Comportamento
| Situação | O que acontece |
|---|---|
| Enter | Quebra a linha — não envia o formulário. Conferido no teste da ficha. |
| Digitando com contador | O contador muda a cada tecla; quem usa leitor de tela ouve quanto falta ou sobra 1s depois de parar de digitar, e não a cada tecla (padrão do GOV.UK). Conferido no teste da ficha. |
| Dentro do FormField | Recebe id, aria-describedby (dica, contador, erro) e aria-invalid do campo, sem repetir nada. |
Relacionados
Como usar no código
A importação e o menor uso, lidos do arquivo. O … marca as props obrigatórias.
import { Textarea } from '@/app/components/atoms/Textarea';
<Textarea />Propriedades
Lidas do código da peça no build — não escritas à mão.
| Prop | Tipo | Padrão | Obrigatória | Descrição |
|---|---|---|---|---|
redimensionar | 'vertical' | 'nenhum' | 'vertical' | não | Variante do cva. |
error | boolean | — | não | Pinta a borda de erro e emite aria-invalid, como o Input e o Select. |
Aceita também: React.TextareaHTMLAttributes<HTMLTextAreaElement>.
Medidas
| Parte | Valor | Classe |
|---|---|---|
| Altura mínima | 96px, e quatro linhas por padrão | min-h-24 · rows={4} |
| Preenchimento | 16 × 12px | px-espaco-4 py-espaco-3 |
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 |
|---|---|---|
--muted | #F4F6F9 | bg-muted |
Teclado
| Tecla | Faz |
|---|---|
| Tab | Leva o foco ao campo; o próximo Tab sai dele. Conferido no teste da ficha. |
| Enter | Quebra a linha (não envia o formulário) — conferido no teste da ficha. |
Leitor de tela
O que é anunciado, e por quê.
- O nome vem do rótulo do FormField (ou do
aria-label); o erro e a dica chegam poraria-describedby— conferido no teste da ficha. - O erro é borda e
aria-invalid, da mesma fonte: o vermelho nunca sozinho. - O contador é parte da descrição do campo (lido ao chegar nele); o restante é anunciado numa região viva educada, só quando a pessoa para de digitar — conferido no teste da ficha.
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/Textarea.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.
fdd10ff2026-09-29ESTADO: E109 concluida, roteiro final fechado; proximo o merge na main
O histórico completo está no GitHub (abre em outra aba).