From eee275877d46a861d162d1a567e83287414092c8 Mon Sep 17 00:00:00 2001 From: Luiz Silva Date: Mon, 16 Feb 2026 10:38:38 -0300 Subject: [PATCH] =?UTF-8?q?melhoria=20de=20documenta=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IA.md | 595 ------------------------------------ README.md | 849 ++++++++++++++++++++------------------------------- package.json | 2 +- 3 files changed, 326 insertions(+), 1120 deletions(-) delete mode 100644 IA.md diff --git a/IA.md b/IA.md deleted file mode 100644 index f071d22..0000000 --- a/IA.md +++ /dev/null @@ -1,595 +0,0 @@ -# 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"; -// eli-vue -import EliVue from "eli-vue"; - -const vuetify = createVuetify({}); - -createApp(App) - .use(vuetify) - .use(EliVue) - .mount("#app"); -``` - -> **Nota**: O CSS é **injetado automaticamente** no bundle JavaScript. Não é necessário importar arquivos `.css` manualmente. - - -### 2) Importação direta (quando não quiser plugin) - -```ts -import { - EliBotao, - EliBadge, - EliCartao, - EliTabela, - EliEntradaTexto, - EliEntradaNumero, - EliEntradaDataHora, - EliEntradaParagrafo, - EliEntradaSelecao, -} from "eli-vue"; -``` - ---- - -## 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 - } -] -``` - -### Botões de Ação da Tabela (`acoesTabela`) - -Além das ações por linha, você pode adicionar botões de ação globais à tabela. - -```ts -acoesTabela: [ - { - rotulo: "Novo Usuário", - icone: Plus, - posicao: "superior", // Ao lado da busca - acao: () => console.log("Criar novo") - }, - { - rotulo: "Exportar Relatório", - icone: Download, - posicao: "inferior", // No rodapé, alinhado à esquerda - acao: () => console.log("Exportar") - } -] -``` - -- **`posicao: 'superior'`**: Exibidos à direita da caixa de busca. -- **`posicao: 'inferior'`**: Exibidos no rodapé da tabela, **alinhados à esquerda** (enquanto a paginação fica à direita). - - **Estilo**: Por padrão, botões inferiores possuem fundo branco, **borda verde** (`outline`) e texto verde. Caso uma `cor` personalizada seja informada, ela será usada para a borda e texto. - -### 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 não foi injetado corretamente pelo JavaScript. - -O `eli-vue` injeta o CSS automaticamente via JS. Verifique se o bundle está sendo carregado corretamente e se não há bloqueios de Content Security Policy (CSP) para injeção de estilos ` + + Salvar + ``` -## Como rodar localmente +--- -### Playground +### 4. EliCartao & EliBadge -```bash -pnpm dev -``` +**EliCartao** +Cartão padronizado para itens de domínio. +- **Props**: `titulo`, `status` (tipo `CartaoStatus`: "novo" | "rascunho" | "vendido" | "cancelado"), `variant`. +- **Slots**: `default` (conteúdo), `acoes` (ações de rodapé). -O playground (`src/playground`) valida visualmente variações e interações. +**EliBadge** +Badge aprimorado com raios. +- **Props**: `badge` (conteúdo), `color`, `radius` ("suave" | "pill"). -### Build da lib + geração de tipos +--- -```bash -pnpm run build -``` +## 🔧 Solução de Problemas e Dicas -Gera `dist/` (artefatos de build) e `dist/types` (declarações `.d.ts`). +### 1. "Failed to resolve component" +- Certifique-se de que `app.use(EliVue)` foi chamado no `main.ts`. +- Se importar diretamente, garanta importações padrão: `import { EliTabela } from 'eli-vue'`. -> Observação importante: este repositório roda `npm version patch --no-git-tag-version` no `prebuild`. -> Ou seja, ao rodar `pnpm run build` a versão do `package.json` é incrementada automaticamente. +### 2. Problemas de Estilo +- **Injeção de CSS**: O `eli-vue` injeta CSS automaticamente. Verifique sua CSP (Política de Segurança de Conteúdo) se os estilos estiverem bloqueados. +- **Vuetify**: Certifique-se de que o Vuetify 3 está corretamente instalado e os estilos (`vuetify/styles`) estão importados no seu arquivo de entrada principal. -## Guia rápido para IAs (antes de codar) +### 3. Erros de TypeScript no `celulaTabela` +- Garanta que o segundo argumento corresponda ao esquema específico do tipo de célula. +- Exemplo: `celulaTabela("textoSimples", { texto: ... })` funciona, mas `celulaTabela("textoSimples", { numero: ... })` falhará. -1) **Leia** `.agent` e este README. -2) **Busque padrões** antes de criar API nova (props/emits/slots). -3) **Não use `any`**. -4) **Centralize tipos** em `src/tipos/`. -5) Ao mudar API/comportamento: - - atualize o `README.md` do componente - - atualize ou crie um `*.playground.vue` -6) Rode `pnpm run build` antes de finalizar. +### 4. Ícones não aparecem +- Passe o **objeto do componente** (ex: importado de `lucide-vue-next`), não o nome em string. +- Exemplo: `icone: Pencil` (Correto) vs `icone: "pencil"` (Incorreto). -## Como criar/alterar um componente (checklist) - -1. Criar pasta em `src/componentes//` -2. Criar `EliNomeDoComponente.vue` com `defineComponent` + comentários úteis -3. Criar `index.ts` com re-export (ex.: `export { default as EliX } from './EliX.vue'`) -4. Criar `README.md` do componente (API, exemplos, casos de borda, A11y) -5. Criar playground em `src/playground/.playground.vue` (mín. 3 variações) -6. Exportar no `src/index.ts` - -### Critérios de aceite (qualidade) - -- `pnpm run build` passa (inclui `vue-tsc`) -- zero `any` -- `defineComponent` em todos os componentes -- README do componente atualizado quando API mudar -- playground demonstrando variações + interação - -## Roadmap de melhorias (a aplicar) - -### Curto prazo (qualidade / consistência) -- [ ] Padronizar comentários úteis em todos os componentes (explicar decisões e estados) -- [ ] Tipar `emits` com validação de payload (quando houver) -- [ ] Consolidar nomenclatura de props/eventos em português (avaliar breaking changes) - -### Médio prazo (DX + segurança) -- [ ] Adicionar ESLint + Prettier e regras (incluindo proibição de `any`) -- [ ] Adicionar testes unitários com Vitest + @vue/test-utils -- [ ] Criar pipeline de CI rodando `pnpm run build` - -### Longo prazo (docs e maturidade) -- [ ] Documentação visual (Storybook ou VitePress) -- [ ] Tokens de design (cores/spacing) e guideline de acessibilidade +### 5. Valores do `EliEntrada` +- `EliEntradaTexto` com `formato='cpfCnpj'` emite a string **formatada** (ex: "123.456.789-00"). +- `EliEntradaNumero` emite um `number` ou `null`. +- `EliEntradaDataHora` trabalha com **Strings ISO** (ex: "2023-01-01T00:00:00Z"). A exibição é localizada, mas o valor do modelo é sempre ISO. diff --git a/package.json b/package.json index 550d754..369a1e3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eli-vue", - "version": "0.1.97", + "version": "0.1.98", "private": false, "main": "./dist/eli-vue.umd.js", "module": "./dist/eli-vue.es.js",