# IA.md — Guia para IAs (consumidoras) do pacote `eli-vue` Este arquivo existe para **IAs e automações** que precisam **importar e usar** o pacote `eli-vue` em projetos Vue 3. > Fonte da verdade das regras internas do repositório: **`.agent`**. > Este `IA.md` é focado no **uso do pacote como dependência** (projeto consumidor). --- ## O que é o `eli-vue` Biblioteca (Design System) de componentes para **Vue 3** com **TypeScript** e integração com **Vuetify 3**. ### Premissas importantes - O `eli-vue` **não cria** nem configura Vuetify no seu projeto. - `vue` e `vuetify` são **peerDependencies**: o projeto consumidor precisa ter ambos instalados. - O pacote utiliza internamente **lucide-vue-next** para ícones. --- ## Instalação (projeto consumidor) > Preferência do repo: `pnpm`. ```bash pnpm add eli-vue ``` Se o projeto ainda não tiver as peer dependencies, instale também: ```bash pnpm add vue vuetify lucide-vue-next ``` > Nota: `lucide-vue-next` é recomendado para passar ícones compatíveis aos componentes (como `EliTabela`). --- ## Uso recomendado ### 1) Registro global via plugin (recomendado) ```ts import { createApp } from "vue"; import App from "./App.vue"; // Vuetify import "vuetify/styles"; import { createVuetify } from "vuetify"; // eli-vue import EliVue from "eli-vue"; import "eli-vue/dist/eli-vue.css"; const vuetify = createVuetify({}); createApp(App) .use(vuetify) .use(EliVue) .mount("#app"); ``` > **IMPORTANTE**: O import do CSS (`import "eli-vue/dist/eli-vue.css";`) é **obrigatório**. > O pacote utiliza **namespacing estático (BEM)** e não estilos scoped, portanto o arquivo CSS contém toda a estilização necessária. ### 2) Importação direta (quando não quiser plugin) ```ts import { EliBotao, EliBadge, EliCartao, EliTabela, EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora, EliEntradaParagrafo, EliEntradaSelecao, } from "eli-vue"; // OBRIGATÓRIO: Importar o CSS global import "eli-vue/dist/eli-vue.css"; ``` --- ## Tipagem e Helpers O pacote exporta tipos e funções utilitárias essenciais para o desenvolvimento com TypeScript. ```ts import { // Componentes EliTabela, // Helpers celulaTabela, // Tipos tipoEliTabelaConsulta, tipoEliColuna, tipoEliTabelaAcao, CartaoStatus // Tipos compartilhados } from "eli-vue"; ``` --- ## Exemplos mínimos ### Botão ```vue ``` ### Entradas (EliEntrada*) com v-model O `eli-vue` usa uma família de componentes `EliEntrada*` (em vez do antigo `EliInput`). #### Texto ```vue ``` #### Parágrafo (textarea) ```vue ``` #### Seleção (select) ```vue ``` #### Texto com formato/máscara > Regra importante: o `value` emitido é **sempre o texto formatado** (igual ao que aparece no input). ```vue ``` ### Data e hora (entrada) com suporte a UTC/Z ```vue ``` --- ## Outros Componentes ### EliBadge (Indicador) Badge aprimorado que suporta raios predefinidos ("suave" | "pill"). ```vue ``` ### EliCartao Cartão padronizado para representar itens de domínio (ex: propostas) com status coloridos automaticamente. > **Importante**: O status deve ser um dos valores do tipo `CartaoStatus` ("novo" | "rascunho" | "vendido" | "cancelado"). ```vue ``` --- ## EliTabela (Tabela Avançada) O componente `EliTabela` suporta ordenação, paginação, busca e **filtro avançado**. Para type-safety, recomenda-se definir a estrutura da consulta usando `tipoEliTabelaConsulta`. ### Barra de Busca e Filtros O `EliTabela` oferece duas formas principais de filtrar dados: 1. **Busca Textual Simples**: Uma caixa de busca global. 2. **Filtro Avançado**: Um modal para composição de filtros específicos por coluna. #### 1. Busca Textual Simples Para habilitar, defina `mostrarCaixaDeBusca: true`. O termo digitado será passado para a função `consulta` no parâmetro `texto_busca`. ```ts mostrarCaixaDeBusca: true, consulta: async ({ texto_busca }) => { // Use 'texto_busca' para filtrar no backend (ex: ILIKE %texto%) } ``` #### 2. Filtro Avançado Permite que o usuário crie filtros complexos (ex: "Data > X" E "Status = Y"). Você define os campos disponíveis em `filtroAvancado`. Cada definição de filtro precisa de: - `rotulo`: Nome exibido ao usuário. - `coluna`: Chave do dado (`keyof T`) a ser filtrada. - `operador`: Operação padrão (ex: `like`, `=`, `>`, `<`, `>=`, `<=`, `!=`, `in`, `between`). - `entrada`: Definição do componente de entrada (`EliEntrada*`) usado para capturar o valor. > **Dica de Tipagem**: O campo `entrada` espera uma tupla `[Tipo, Opcoes]`. Devido à complexidade do TypeScript, pode ser necessário usar `as any` ou castar para `ComponenteEntrada`. ```ts filtroAvancado: [ { rotulo: "Nome do Cliente", coluna: "nome", // chave em T operador: "like", // Configuração do input (igual ao usar EliEntradaTexto) entrada: ["texto", { rotulo: "Digite o nome", placeholder: "Ex: João" }] as any, }, { rotulo: "Data de Criação", coluna: "criado_em", operador: ">=", // Configuração do input (EliEntradaDataHora) entrada: ["dataHora", { rotulo: "A partir de", modo: "data" }] as any, }, { rotulo: "Status", coluna: "status", operador: "=", // Configuração do input com seleção entrada: ["selecao", { rotulo: "Selecione", itens: () => [ { chave: "ativo", rotulo: "Ativo" }, { chave: "inativo", rotulo: "Inativo" } ] }] as any } ] ``` ### Processando a Consulta A função `consulta` recebe um objeto com todos os parâmetros necessários para buscar os dados corretamente. ```ts consulta: async (params) => { const { offSet, // Paginação: pular N registros limit, // Paginação: limite por página texto_busca, // Busca simples (string | undefined) coluna_ordem, // Ordenação: qual coluna direcao_ordem, // Ordenação: "asc" | "desc" filtros // Array de filtros aplicados pelo usuário } = params; // Exemplo de estrutura de 'filtros': // [ // { coluna: "nome", operador: "like", valor: "Ana" }, // { coluna: "criado_em", operador: ">=", valor: "2024-01-01" } // ] console.log("Buscando dados...", params); // ... chamada à API ... return { cod: 0, eCerto: true, eErro: false, mensagem: undefined, valor: { // Retorne SEMPRE o total real de registros para a paginação funcionar quantidade: 100, valores: [ /* ... array de T ... */ ] }, }; }, ``` ### Exemplo Completo Tipado ```ts import { defineComponent } from "vue"; import { EliTabela, celulaTabela } from "eli-vue"; import type { tipoEliTabelaConsulta } from "eli-vue"; // Tipos auxiliares (opcionais, mas úteis) import { BadgeCheck, Pencil } from "lucide-vue-next"; // 1. Defina o tipo da linha type Usuario = { id: number; nome: string; documento: string; email: string; ativo: boolean; criado_em: string; }; // 2. Defina a configuração da tabela const tabelaUsuarios: tipoEliTabelaConsulta = { nome: "Usuarios", mostrarCaixaDeBusca: true, registros_por_consulta: 10, // Colunas Visuais colunas: [ { rotulo: "Nome", celula: (row) => celulaTabela("textoSimples", { texto: row.nome }), visivel: true, coluna_ordem: "nome" // Habilita ordenação por esta coluna }, { rotulo: "Status", visivel: true, celula: (row) => celulaTabela("tags", { opcoes: [ row.ativo ? { rotulo: "Ativo", cor: "success", icone: BadgeCheck } : { rotulo: "Inativo", cor: "error" } ] }) }, { rotulo: "Criado em", visivel: true, celula: (row) => celulaTabela("data", { valor: row.criado_em, formato: "data_hora" }) } ], // Ações de linha (botões à direita) acoesLinha: [ { rotulo: "Editar", icone: Pencil, cor: "primary", acao: (row) => console.log("Editar", row.id) } ], // Definição dos Filtros Avançados disponíveis filtroAvancado: [ { rotulo: "Documento", coluna: "documento", operador: "like", entrada: ["texto", { rotulo: "Documento", formato: "cpfCnpj" }] as any, }, { rotulo: "Criado em (Início)", coluna: "criado_em", operador: ">=", entrada: ["dataHora", { rotulo: "A partir de", modo: "data" }] as any } ], // Função de consulta consulta: async (params) => { // Aqui você conectaria com sua API, passando params.filtros, params.texto_busca, etc. console.log("Filtros aplicados:", params.filtros); return { cod: 0, eCerto: true, eErro: false, mensagem: undefined, valor: { quantidade: 1, valores: [ { id: 1, nome: "Luiz", documento: "123", email: "a@a.com", ativo: true, criado_em: "2024-01-01" } ] }, }; }, }; ``` ### Tipos de Células (`celulaTabela`) Helper: `celulaTabela(tipo, dados)` - `textoSimples`: `{ texto: string; acao?: () => void }` - `textoTruncado`: `{ texto: string; acao?: () => void }` - `numero`: `{ numero: number; prefixo?: string; sufixo?: string; acao?: () => void }` - `tags`: `{ opcoes: { rotulo: string; cor?: string; icone?: LucideIcon; acao?: () => void }[] }` - `data`: `{ valor: string; formato: "data" | "data_hora" | "relativo"; acao?: () => void }` --- ## Troubleshooting (para IAs) ### 1) “Failed to resolve component” Provável causa: componente não foi registrado. - Se estiver usando plugin: confirme `app.use(EliVue)` - Se estiver importando direto: registre localmente no componente ### 2) Estilos não aplicam ou componentes "quebrados" **Causa provável**: O CSS do pacote não foi importado. O `eli-vue` removeu o uso de `