Skip to content

BaseDateInput ​

Campo de data. Usa o <input type="date"> do navegador, com o calendário nativo, e guarda o valor no formato ISO (AAAA-MM-DD). Dentro de um BaseField, se liga sozinho ao rótulo, à ajuda e ao erro, como o BaseInput.

Dia em que o fiscal esteve na obra.

Entre 01/10/2026 e 31/08/2027.

Valor do v-model: (vazio) e 2026-10-01.

Uso ​

  • Use para uma data só: vistoria, assinatura, publicação. Para início e fim, use dois campos lado a lado com um rótulo para cada.
  • O v-model é sempre AAAA-MM-DD, ou '' enquanto a data está vazia ou incompleta. Formate para dd/mm/aaaa só na hora de mostrar.
  • Data incompleta (por exemplo, só dia e mês) ou impossível (31/02) também chega ao v-model como '': o navegador não entrega o que foi digitado. Para separar "vazia" de "incompleta", use v-model:incomplete, que fica true enquanto sobra parte da data no campo. Assim dá para mostrar "Data incompleta. Informe dia, mês e ano." em vez de "Informe a data".
  • O incomplete é atualizado a cada tecla, ao mudar a data e ao sair do campo. Mostre a mensagem de data incompleta ao sair do campo ou ao enviar, não enquanto a pessoa digita.
  • Para limpar o formulário, ponha '' no v-model e false no incomplete. Isso apaga também as partes que o usuário deixou pela metade (verificado no Chromium, no WebKit e no Firefox).
  • O ano tem no máximo 4 dígitos. Sem max, o campo usa 9999-12-31 como limite; sem esse limite, o Chrome aceitaria anos de até 6 dígitos e o v-model deixaria de ser AAAA-MM-DD.
  • min e max limitam o calendário. Diga o intervalo na ajuda: o navegador não explica por que um dia está bloqueado.
  • O navegador não marca a data fora do intervalo como erro na tela. Valide ao sair do campo ou ao enviar e use invalid com um texto que diga como corrigir: "A vigência termina até 31/08/2027. Escolha uma data até lá."
  • invalid sempre vem com um texto visível. Dentro do BaseField, passe invalid-text: sem ele, o campo só fica com a borda vermelha. Fora do BaseField, mostre a mensagem perto do campo e ligue-a com aria-describedby.
  • O formato exibido segue o idioma do navegador. Em um navegador em português, aparece dd/mm/aaaa.

Anatomia ​

  1. Partes da data: dia, mês e ano, no formato do idioma do navegador (dd/mm/aaaa em português).
  2. Botão do calendário: à direita, abre o calendário do navegador.

Rótulo, ajuda e erro vêm do BaseField em volta.

Estados ​

Informe a data da vistoria.

Data no fim de semana. Confira com o fiscal.

Fora do BaseField ​

A vigência termina até 31/08/2027. Escolha uma data até lá.

Fora do BaseField, required vai direto para o <input> e o leitor de tela ouve "obrigatório". Dentro dele, basta o required do campo, que também mostra o * no rótulo.

Tamanhos ​

Cada tamanho tem a mesma altura do BaseInput correspondente, para os dois ficarem alinhados na mesma linha do formulário.

Faça e não faça ​

FaçaNão faça
Use um campo para cada data, como início e fim da vigência lado a lado.Peça as duas datas num campo de texto só.
Diga na ajuda o intervalo aceito: "Até 31/08/2027".Deixe o calendário bloquear dias sem explicar o motivo.
Mostre "Data incompleta" ao sair do campo, com v-model:incomplete.Mostre erro enquanto a pessoa ainda digita a data.

Estilo ​

Herda o campo do BaseInput. Só o que muda está abaixo.

PropriedadeToken
Fundo--tj-field-01; desabilitado e somente leitura --tj-field-disabled
Borda--tj-border-strong-01, hover --tj-border-strong-02, foco --tj-border-interactive
Data vazia--tj-text-helper nos campos dd/mm/aaaa (5,8:1 no tema claro e 7,1:1 no escuro, calculado dos tokens): é a única instrução de formato na tela
Parte da data em ediçãofundo --tj-interactive, texto --tj-text-on-color; em somente leitura, o foco padrão do navegador
Botão do calendáriohover --tj-layer-hover-01; some em somente leitura e desabilitado
Númerosfont-variant-numeric: tabular-nums, para as datas alinharem em colunas
Alturaa mesma do BaseInput em cada tamanho

No tema escuro, o color-scheme: dark dos tokens troca o ícone e o calendário do navegador.

A cor da data vazia vale em todos os navegadores. O destaque da parte em edição e o botão do calendário só têm esse acabamento no Chrome, no Edge e no Safari; no Firefox ficam com o visual nativo.

Código ​

vue
<BaseField label="Fim da vigência" :invalid="showError" invalid-text="A vigência termina até 31/08/2027. Escolha uma data até lá." required>
  <BaseDateInput v-model="endDate" v-model:incomplete="endIncomplete" :min="startDate" max="2027-08-31" />
</BaseField>

Propriedades ​

Propriedade Tipo Padrão Descrição
size'sm' | 'md' | 'lg''md'Altura
minstring—Primeira data aceita, em ISO
maxstring—Última data aceita, em ISO; o padrão limita o ano a 4 dígitos. Padrão: '9999-12-31'
disabledbooleanfalseDesabilita o campo
readonlybooleanfalseMostra a data sem permitir mudança
invalidbooleanfalseMarca o erro; dentro de um BaseField, vale também o do campo
requiredbooleanfalseObrigatório no formulário; dentro de um BaseField, vale também o do campo
autocompletestring—Por exemplo bday para data de nascimento
v-modelstring''Data em ISO AAAA-MM-DD; '' quando vazia ou incompleta
v-model:incompletebooleanfalsetrue enquanto a data está pela metade ou é impossível; false vindo do pai apaga o que sobrou

Eventos:

  • update:modelValue: a cada data válida no campo, digitada ou escolhida, e com '' quando a data é apagada ou fica incompleta. Enquanto o ano é digitado, o Chrome já entrega uma data válida a cada tecla: 0002-10-20, 0020-10-20, 0202-10-20 e só então 2026-10-20. Por isso, valide intervalo e regra de negócio (data fora da vigência, fim de semana) ao sair do campo ou ao enviar, não num watch do v-model; senão o erro pisca e a mensagem lida pelo leitor de tela muda no meio da digitação.
  • update:incomplete: quando a data passa a estar ou deixa de estar pela metade.

Fora de um BaseField, passe aria-label: o atributo vai direto para o <input>. Dentro de um BaseField, o id do campo prevalece, para o rótulo continuar ligado, e um aria-describedby seu é somado ao da ajuda ou do erro, sem substituí-lo.

Acessibilidade ​

  • Usa o controle de data nativo; cada parte (dia, mês, ano) é anunciada como um campo giratório (spinbutton) e segue o teclado desse padrão do APG.
  • Teclado, verificado com Playwright no Chromium, no WebKit e no Firefox: as setas para cima e para baixo mudam a parte em foco, a seta para a direita passa para a parte seguinte, Tab também passa para a parte seguinte, e Backspace apaga a parte. No Chromium, os números digitam a parte e já passam para a seguinte. A abertura do calendário pelo teclado não foi verificada; dá para preencher tudo sem ele.
  • O rótulo é um <label for> ligado ao campo. Ajuda, erro e aviso ficam em aria-describedby.
  • Com erro, o campo recebe aria-invalid="true". A cor nunca é o único sinal desde que haja texto: o BaseField mostra ícone e texto quando recebe invalid-text, e fora dele a mensagem ligada por aria-describedby cumpre esse papel. invalid sem texto deixa só a cor, então não use assim.
  • O foco aparece com o anel --tj-ring de 3 px.
  • O botão do calendário só muda o fundo no hover, sem animação quando o sistema pede prefers-reduced-motion.
  • Testado com axe em todos os estados e tamanhos, dentro do BaseField (inclusive com rótulo oculto, campo opcional, data incompleta e invalid sem texto) e fora dele com aria-label, obrigatório e com a mensagem ligada por aria-describedby. O axe roda sem a regra de contraste, porque o jsdom não desenha a página; o contraste da data vazia foi calculado a partir dos tokens.

Teclado:

TeclaO que faz
TabPassa para a parte seguinte da data.
↑ e ↓Mudam a parte em foco.
→Passa para a parte seguinte.
BackspaceApaga a parte em foco.
NúmerosDigitam a parte. No Chromium, já passam para a seguinte.