# 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`