vue-componentes/src/componentes/data_hora/README.md

4.1 KiB

EliDataHora

O EliDataHora é um componente de entrada de data e hora baseado em v-text-field (Vuetify), usando o tipo nativo do HTML datetime-local.

Ele foi criado para oferecer uma solução estável e leve sem depender de componentes experimentais do Vuetify.

Objetivo

  • Permitir o usuário selecionar data + hora com UX nativa do navegador.
  • Padronizar a API em português (props/eventos) no Design System.

API

Props

Prop Tipo Padrão Descrição
modelValue string | null null Sempre em ISO 8601, aceitando UTC absoluto (Z) ou com offset (ex.: 2026-01-09T16:15:00Z, 2026-01-09T13:15:00-03:00). O componente converte para horário local antes de exibir.
modo "data" | "dataHora" "dataHora" Define se o campo permite selecionar apenas data (date) ou data+hora (datetime-local).
rotulo string "Data e hora" Label do campo.
placeholder string "" Placeholder do campo.
desabilitado boolean false Desabilita o campo.
limpavel boolean false Habilita botão de limpar (Vuetify clearable).
erro boolean false Estado de erro visual.
mensagensErro string | string[] [] Mensagens de erro.
dica string "" Hint/ajuda abaixo do campo.
dicaPersistente boolean false Mantém dica sempre visível.
densidade CampoDensidade "comfortable" Densidade (Vuetify).
variante CampoVariante "outlined" Variante (Vuetify).
min string | undefined undefined Mínimo permitido em ISO 8601 (offset ou Z).
max string | undefined undefined Máximo permitido em ISO 8601 (offset ou Z).

Observação: o atributo HTML datetime-local não inclui timezone. Este componente resolve isso convertendo:

  • entrada: ISO 8601 (UTC/offset) → exibição em horário local
  • saída: valor selecionado → ISO 8601 com offset local

Emits

Evento Payload Quando dispara
update:modelValue string | null Sempre que o valor muda (padrão do v-model). O payload é ISO 8601 com offset local.
alterar string | null Alias semântico para mudanças de valor (mesmo payload do v-model).
foco void Ao focar o campo.
desfoco void Ao sair do foco.

Slots

Este componente não define slots próprios. Você pode usar slots do v-text-field via v-bind="$attrs" caso precise (ver exemplos abaixo).

Exemplos

1) Uso básico com v-model

<template>
  <EliDataHora v-model="dataHora" />
  <div class="text-caption">Valor: {{ dataHora }}</div>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue";
import { EliDataHora } from "eli-vue";

export default defineComponent({
  components: { EliDataHora },
  setup() {
    const dataHora = ref<string | null>("2026-01-09T16:15:00Z");
    return { dataHora };
  },
});
</script>

2) Com limites (min/max) e validação visual

<template>
  <EliDataHora
    v-model="dataHora"
    rotulo="Agendar"
    :min="min"
    :max="max"
    :erro="!dataHora"
    :mensagensErro="!dataHora ? ['Obrigatório'] : []"
    limpavel
  />
</template>

Casos de borda / comportamento esperado

  • Ao limpar o campo, o componente emite null (não string vazia).
  • O navegador pode variar a UI do seletor (isso é esperado do datetime-local).
  • min/max devem ser strings em ISO 8601 (offset ou Z).
  • Em modo="data", o componente emite ISO no início do dia (00:00:00) no fuso local.

Acessibilidade

  • O v-text-field do Vuetify já oferece base de acessibilidade.
  • Sempre prefira passar rotulo significativo.

Decisões de implementação

  • Usamos datetime-local por ser amplamente suportado e não depender de APIs experimentais.
  • O componente usa dayjs para converter entradas UTC/offset para local antes de exibir e para emitir ISO 8601 com offset local.
  • Mantemos o valor como string | null para evitar conversões implícitas e permitir que cada projeto decida como persistir (UTC/local).