# 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
Salvar
```
### 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
mdi-bell
```
### 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
Cliente: ACME Corp
Criado há 2 dias
Ver detalhes
```
---
## 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 `