# 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
```
---
#### 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
```
---
#### 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
```
---
#### 4) `EliEntradaParagrafo`
Entrada de texto multi-linha (equivalente a um **textarea**).
**Value**: `string | null | undefined`
**Opções** (além de `rotulo`/`placeholder`):
- `linhas?: number` (default: `4`)
- `limiteCaracteres?: number`
- `limpavel?: boolean`
- `erro?: boolean`
- `mensagensErro?: string | string[]`
- `dica?: string`
- `dicaPersistente?: boolean`
- `densidade?: CampoDensidade`
- `variante?: CampoVariante`
Exemplo:
```vue
```
---
#### 5) `EliEntradaSelecao`
Entrada de seleção (select) com carregamento de itens via função.
**Value**: `string | null | undefined` (chave do item selecionado)
**Opções** (além de `rotulo`/`placeholder`):
- `itens: () => {chave: string; rotulo: string}[] | Promise<{chave: string; rotulo: string}[]>`
- `limpavel?: boolean`
- `erro?: boolean`
- `mensagensErro?: string | string[]`
- `dica?: string`
- `dicaPersistente?: boolean`
- `densidade?: CampoDensidade`
- `variante?: CampoVariante`
Comportamento:
- Ao montar, o componente chama `opcoes.itens()`.
- Enquanto carrega, o select fica em `loading` e desabilitado.
Exemplo:
```vue
```
### 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`