108 lines
4.1 KiB
Markdown
108 lines
4.1 KiB
Markdown
# 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
|
|
|
|
```vue
|
|
<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
|
|
|
|
```vue
|
|
<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).
|