4.1 KiB
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-localnã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/maxdevem ser strings em ISO 8601 (offset ouZ).- Em
modo="data", o componente emite ISO no início do dia (00:00:00) no fuso local.
Acessibilidade
- O
v-text-fielddo Vuetify já oferece base de acessibilidade. - Sempre prefira passar
rotulosignificativo.
Decisões de implementação
- Usamos
datetime-localpor ser amplamente suportado e não depender de APIs experimentais. - O componente usa
dayjspara converter entradas UTC/offset para local antes de exibir e para emitir ISO 8601 com offset local. - Mantemos o valor como
string | nullpara evitar conversões implícitas e permitir que cada projeto decida como persistir (UTC/local).