This commit is contained in:
Luiz Silva 2026-01-29 10:51:13 -03:00
parent de7c19be24
commit 6aedf2469f
20 changed files with 2032 additions and 1541 deletions

View file

@ -0,0 +1,176 @@
# EliEntrada (Padrão de Entradas)
Esta pasta define o **padrão EliEntrada**: um conjunto de componentes de entrada (inputs) com uma **API uniforme**.
> TL;DR
> - Toda entrada recebe **`value`** (estado) e **`opcoes`** (configuração).
> - O padrão de uso é **`v-model:value`**.
> - Mantemos compatibilidade com Vue 2 via evento **`input`**.
---
## Para humanos (uso no dia-a-dia)
### Conceito
Um componente **EliEntrada** recebe **duas propriedades**:
- `value`: o valor atual do campo (entrada e saída)
- `opcoes`: um objeto que configura o componente (rótulo, placeholder e opções específicas do tipo)
Essa padronização facilita:
- gerar formulários dinamicamente
- trocar tipos de entrada com o mínimo de refactor
- documentar e tipar de forma previsível
### Tipos e contratos
Os contratos ficam em: [`tiposEntradas.ts`](./tiposEntradas.ts)
- `PadroesEntradas`: mapa de tipos suportados (ex.: `texto`, `numero`, `dataHora`)
- `TipoEntrada`: união das chaves do mapa (ex.: `"texto" | "numero" | "dataHora"`)
### Componentes disponíveis
#### 1) `EliEntradaTexto`
**Value**: `string | null | undefined`
**Opções** (além de `rotulo`/`placeholder`):
- `limiteCaracteres?: number`
Exemplo:
```vue
<template>
<EliEntradaTexto
v-model:value="nome"
:opcoes="{ rotulo: 'Nome', placeholder: 'Digite seu nome', limiteCaracteres: 50 }"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { EliEntradaTexto } from '@/index'
const nome = ref<string | null>(null)
</script>
```
---
#### 2) `EliEntradaNumero`
**Value**: `number | null | undefined`
**Opções**:
- `precisao?: number`
- `1` => inteiro
- `0.1` => 1 casa decimal
- `0.01` => 2 casas decimais
- `prefixo?: string` (ex.: `"R$"`)
- `sufixo?: string` (ex.: `"kg"`)
Comportamento:
- Quando `precisao < 1` o componente entra em modo **fixed-point**: você digita números continuamente e ele insere a vírgula automaticamente.
- O que é exibido sempre corresponde ao `value` emitido.
Exemplos:
```vue
<EliEntradaNumero
v-model:value="quantidade"
:opcoes="{ rotulo: 'Quantidade', placeholder: 'Ex: 10', precisao: 1, sufixo: 'kg' }"
/>
<EliEntradaNumero
v-model:value="preco"
:opcoes="{ rotulo: 'Preço', placeholder: 'Digite', precisao: 0.01, prefixo: 'R$' }"
/>
```
---
#### 3) `EliEntradaDataHora`
**Value**: `string | null | undefined` (ISO 8601 com offset ou `Z`)
**Opções**:
- `modo?: "data" | "dataHora"` (default: `dataHora`)
- `min?: string` (ISO)
- `max?: string` (ISO)
- `limpavel?: boolean`
- `erro?: boolean`
- `mensagensErro?: string | string[]`
- `dica?: string`
- `dicaPersistente?: boolean`
- `densidade?: CampoDensidade`
- `variante?: CampoVariante`
Importante:
- O input nativo `datetime-local` não carrega timezone.
- O componente converte ISO (Z/offset) para **local** para exibir.
- Ao alterar, emite ISO 8601 com o **offset local**.
Exemplo:
```vue
<EliEntradaDataHora
v-model:value="agendamento"
:opcoes="{ rotulo: 'Agendar', modo: 'dataHora', min, max, limpavel: true }"
/>
```
### Compatibilidade Vue 2 / Vue 3
Padrão recomendado (Vue 3):
- `v-model:value`
Compat Vue 2:
- todos os EliEntradas também emitem `input`.
- isso permite consumir com o padrão `value + input` quando necessário.
### Playground
- Entradas: `src/playground/entradas.playground.vue`
- Data/hora: `src/playground/data_hora.playground.vue`
---
## Para IA (contratos, invariantes e padrões de evolução)
### Contratos (não quebrar)
1) **Todo EliEntrada tem**:
- prop `value`
- prop `opcoes`
- evento `update:value`
2) **Compatibilidade**:
- emitir `input` (compat Vue 2) é obrigatório
3) **Tipagem**:
- `PadroesEntradas` é a fonte única do contrato (value/opcoes)
- `TipoEntrada = keyof PadroesEntradas`
4) **Sanitização/Normalização**:
- `EliEntradaNumero` deve bloquear caracteres inválidos e manter display coerente com `value`
- `EliEntradaDataHora` deve receber/emitir ISO e converter para local apenas para exibição
### Como adicionar uma nova entrada (checklist)
1) Adicionar chave em `PadroesEntradas` em `tiposEntradas.ts`
2) Criar `EliEntradaX.vue` seguindo o padrão:
- `value` + `opcoes`
- emite `update:value`, `input`, `change`
3) Exportar no `src/componentes/EliEntrada/index.ts`
4) Registrar no `src/componentes/EliEntrada/registryEliEntradas.ts`
5) Criar/atualizar playground (`src/playground/*.playground.vue`)
6) Validar `pnpm -s run build:types` e `pnpm -s run build`
### Padrões de mudança (refactors seguros)
- Se precisar mudar o contrato, faça **migração incremental**:
- manter props/eventos antigos como fallback temporário
- atualizar playground e exemplos
- rodar `build:types` para garantir geração de `.d.ts`