6.3 KiB
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) eopcoes(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
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:
<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?: number1=> inteiro0.1=> 1 casa decimal0.01=> 2 casas decimais
prefixo?: string(ex.:"R$")sufixo?: string(ex.:"kg")
Comportamento:
- Quando
precisao < 1o componente entra em modo fixed-point: você digita números continuamente e ele insere a vírgula automaticamente. - O que é exibido sempre corresponde ao
valueemitido.
Exemplos:
<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?: booleanerro?: booleanmensagensErro?: string | string[]dica?: stringdicaPersistente?: booleandensidade?: CampoDensidadevariante?: CampoVariante
Importante:
- O input nativo
datetime-localnão carrega timezone. - O componente converte ISO (Z/offset) para local para exibir.
- Ao alterar, emite ISO 8601 com o offset local.
Exemplo:
<EliEntradaDataHora
v-model:value="agendamento"
:opcoes="{ rotulo: 'Agendar', modo: 'dataHora', min, max, limpavel: true }"
/>
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?: numberlimpavel?: booleanerro?: booleanmensagensErro?: string | string[]dica?: stringdicaPersistente?: booleandensidade?: CampoDensidadevariante?: CampoVariante
Exemplo:
<EliEntradaParagrafo
v-model:value="descricao"
:opcoes="{
rotulo: 'Descrição',
placeholder: 'Digite uma descrição mais longa...',
linhas: 5,
limiteCaracteres: 300,
limpavel: true,
}"
/>
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?: booleanerro?: booleanmensagensErro?: string | string[]dica?: stringdicaPersistente?: booleandensidade?: CampoDensidadevariante?: CampoVariante
Comportamento:
- Ao montar, o componente chama
opcoes.itens(). - Enquanto carrega, o select fica em
loadinge desabilitado.
Exemplo:
<EliEntradaSelecao
v-model:value="categoria"
:opcoes="{
rotulo: 'Categoria',
placeholder: 'Selecione...',
limpavel: true,
itens: async () => {
await new Promise((r) => setTimeout(r, 300));
return [
{ chave: 'a', rotulo: 'Categoria A' },
{ chave: 'b', rotulo: 'Categoria B' },
];
},
}"
/>
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 + inputquando 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)
-
Todo EliEntrada tem:
- prop
value - prop
opcoes - evento
update:value
- prop
-
Compatibilidade:
- emitir
input(compat Vue 2) é obrigatório
- emitir
-
Tipagem:
PadroesEntradasé a fonte única do contrato (value/opcoes)TipoEntrada = keyof PadroesEntradas
-
Sanitização/Normalização:
EliEntradaNumerodeve bloquear caracteres inválidos e manter display coerente comvalueEliEntradaDataHoradeve receber/emitir ISO e converter para local apenas para exibição
Como adicionar uma nova entrada (checklist)
- Adicionar chave em
PadroesEntradasemtiposEntradas.ts - Criar
EliEntradaX.vueseguindo o padrão:value+opcoes- emite
update:value,input,change
- Exportar no
src/componentes/EliEntrada/index.ts - Registrar no
src/componentes/EliEntrada/registryEliEntradas.ts - Criar/atualizar playground (
src/playground/*.playground.vue) - Validar
pnpm -s run build:typesepnpm -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:typespara garantir geração de.d.ts