---
fonte: 01-canonicos/seed-componentes.md
versao_da_fonte: v1.43
secao: 13
titulo: "Date picker — `estável` · validado pelo Rafael em 2026-08-03 (preview v0.13 + suite de 63 testes)"
sequencia: 15 de 98
bytes_do_corpo: 4456
md5_do_corpo: a2a6780c507b2651e2502a12f52ec42b
gerado_por: 06-validacao/geradores/gen-camada-ia.py
nota: fatia GERADA — o corpo abaixo é byte a byte o trecho do canônico; edite o canônico, nunca esta fatia. Canônico inteiro em https://ds.seed.eng.br/01-canonicos/seed-componentes.md
---
## 13. Date picker — `estável` · validado pelo Rafael em 2026-08-03 (preview v0.13 + suite de 63 testes)

> **Base (3 rodadas):** R1 — GOV.UK/NHS/NSW date input (memoráveis digitadas; NUNCA auto-advance; ano 4 dígitos), CMS (single-input flexível formata no blur), Scottish (calendar = progressive enhancement). R2 — shadcn Calendar/react-day-picker (locale pt-BR, range 2 meses, presets — ReUI), GitLab (digitar OU escolher, sempre). R3 — NN/g date input (picker frustra data distante: "165 cliques até 1990"), Baymard touch keyboards, icapps (picker inadequado p/ nascimento), Smashing birthday. M1–M6 conferidas no consolidado.

### 13.1 A régua por natureza da data (M1 — resolve o conflito 3-campos × máscara × picker)

| Natureza | Interface | Porquê |
|---|---|---|
| **Memorável/conhecida** (nascimento, emissão de documento) | Campo ÚNICO mascarado `dd/mm/aaaa` (registry B5), entrada flexível ("1/8/26" → "01/08/2026" no blur — herda E6) | A pessoa JÁ SABE a data: digitar vence qualquer navegação (NN/g/icapps); CMS valida o single-input |
| **A escolher** (agendar visita técnica; futuro <1 ano; dia da semana importa) | Input digitável + botão calendário (progressive enhancement) | Scottish/GitLab: os DOIS caminhos sempre; o calendário responde "que dia cai?" |
| **Faixa** (relatórios ERP "de/até") | Range picker 2 meses + presets ("Últimos 30 dias", "Este mês") + campos digitáveis | ReUI/NN/g Expedia; presets matam a navegação repetitiva |

**Alternativa descartada com contexto (M2):** os 3 campos separados do GOV.UK resolvem a ambiguidade dd/mm × mm/dd do mundo anglófono — o dd/mm/aaaa universal brasileiro não tem essa ambiguidade na mesma escala, e a máscara B5 já testou. Plano B documentado: se pesquisa com usuários SEED mostrar erro de formato, os 3 campos entram (com type=text inputmode=numeric — E1 vale lá também).

### 13.2 Decisões M3–M6

| # | Decisão | Porquê | Descartado |
|---|---|---|---|
| M3 | Digitar NUNCA deixa de funcionar; o calendário jamais é o único caminho; grid com teclado APG completo (setas dia/semana, PageUp mês, Shift+PageUp ano) | GitLab/NHS/Scottish/APG dialog | Picker-only (prende quem digita rápido) |
| M4 | Calendário: react-day-picker (shadcn Calendar) locale pt-BR, semana começando domingo (BR), min/max, datas desabilitadas COM explicação no describedby | A11y de fábrica + a stack Lovable | Calendário próprio |
| M5 | Mobile: bottom-sheet (herda D7/H3); site simples pode usar `type="date"` nativo (princípio G2 — o picker do OS é excelente no toque) | GitLab GlFormDate | Grid desktop espremido no toque |
| M6 | Defaults: agendamento abre no mês ATUAL; nascimento NUNCA tem default; `autocomplete="bday"` quando aplicável (WCAG 1.3.5) | NN/g | "Hoje" pré-preenchido em nascimento |

### 13.2b Regra da máscara flexível (bug pego pelo Rafael na validação do preview, 2026-08-02)

A máscara de data ACEITA o separador digitado pelo usuário ("/", e tolerante a "." e "-") como delimitador de segmento — é isso que torna "1/8/26" possível: a barra declara "dia de um dígito, próximo segmento". Máscara que só aceita dígitos corridos e injeta barras por posição fixa QUEBRA a promessa da entrada flexível (o usuário fica preso a 01082026). Regras: segmentos limitados a 2/2/4; barra automática só entra ao DIGITAR (nunca ao apagar — senão o backspace briga com a máscara); completude (zeros e século) acontece no blur, nunca durante a digitação. Esta regra vale para TODA máscara segmentada do registry B5 (data, telefone com DDD digitado com espaço, etc.): separador digitado = intenção do usuário, sempre respeitado.

### 13.3 Microcopy

Ajuda com exemplo REAL: "Por exemplo: 15/03/2026" (NHS; nunca "dd/mm/aaaa" cru como placeholder — some ao digitar). Erros específicos: inexistente ("31/02 não existe — confira o dia"), fora da faixa ("Escolha uma data a partir de hoje"), formato ("Digite a data como 15/03/2026").

### 13.4 Os 7 testes

1. Grid: dia selecionado fundo turquesa-600 4.54:1; hoje = anel, não cor sozinha. 2. Selecionado = fundo + aria-selected; desabilitado = riscado + aria-disabled com motivo. 3. Grayscale: hoje (anel) × selecionado (fundo). 4. Par hoje × selecionado a 1s. 5. Um campo = uma data (range = dois valores NOMEADOS de/até). 6. Valor no input sempre. 7. Bottom-sheet, células 44px. ✅

