Ir ao conteúdo
SEED engenhariaDesign System

Componentes

13. Date picker

estávelseed-componentes.md v1.43 · §13seção 15 de 9813-date-picker-estavel-validado-pelo-rafael-em.md · MD5 a2a6780c

Título completo no canon: 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. ✅
BancadaSEED DS v2 — Bloco 2 · Preview v0.13 (13/13)abrir em página própria ↗

Também cita o §13: banco-credencial, banco-edicao-linha, banco-texto-rico, tela-chat.

Esc