371 lines
8.4 KiB
Markdown
371 lines
8.4 KiB
Markdown
# 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.
|
|
|
|
---
|
|
|
|
## 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
|
|
```
|
|
|
|
---
|
|
|
|
## 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");
|
|
```
|
|
|
|
### 2) Importação direta (quando não quiser plugin)
|
|
|
|
```ts
|
|
import {
|
|
EliBotao,
|
|
EliBadge,
|
|
EliCartao,
|
|
EliTabela,
|
|
EliEntradaTexto,
|
|
EliEntradaNumero,
|
|
EliEntradaDataHora,
|
|
EliEntradaParagrafo,
|
|
EliEntradaSelecao,
|
|
} from "eli-vue";
|
|
```
|
|
|
|
> Observação: ainda pode ser necessário importar o CSS do pacote:
|
|
|
|
```ts
|
|
import "eli-vue/dist/eli-vue.css";
|
|
```
|
|
|
|
---
|
|
|
|
## Exemplos mínimos
|
|
|
|
### Botão
|
|
|
|
```vue
|
|
<template>
|
|
<EliBotao @click="salvar">Salvar</EliBotao>
|
|
</template>
|
|
```
|
|
|
|
### Entradas (EliEntrada*) com v-model
|
|
|
|
O `eli-vue` usa uma família de componentes `EliEntrada*` (em vez do antigo `EliInput`).
|
|
|
|
#### Texto
|
|
|
|
```vue
|
|
<template>
|
|
<EliEntradaTexto
|
|
v-model:value="nome"
|
|
:opcoes="{ rotulo: 'Nome', placeholder: 'Digite seu nome' }"
|
|
/>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent, ref } from "vue";
|
|
|
|
export default defineComponent({
|
|
setup() {
|
|
const nome = ref<string | null>("");
|
|
return { nome };
|
|
},
|
|
});
|
|
</script>
|
|
```
|
|
|
|
#### Parágrafo (textarea)
|
|
|
|
```vue
|
|
<template>
|
|
<EliEntradaParagrafo
|
|
v-model:value="descricao"
|
|
:opcoes="{ rotulo: 'Descrição', placeholder: 'Digite...', linhas: 5 }"
|
|
/>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent, ref } from "vue";
|
|
|
|
export default defineComponent({
|
|
setup() {
|
|
const descricao = ref<string | null>("");
|
|
return { descricao };
|
|
},
|
|
});
|
|
</script>
|
|
```
|
|
|
|
#### Seleção (select)
|
|
|
|
```vue
|
|
<template>
|
|
<EliEntradaSelecao
|
|
v-model:value="categoria"
|
|
:opcoes="{
|
|
rotulo: 'Categoria',
|
|
placeholder: 'Selecione...',
|
|
itens: async () => [
|
|
{ chave: 'a', rotulo: 'Categoria A' },
|
|
{ chave: 'b', rotulo: 'Categoria B' },
|
|
],
|
|
}"
|
|
/>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent, ref } from "vue";
|
|
|
|
export default defineComponent({
|
|
setup() {
|
|
const categoria = ref<string | null>(null);
|
|
return { categoria };
|
|
},
|
|
});
|
|
</script>
|
|
```
|
|
|
|
#### Texto com formato/máscara
|
|
|
|
> Regra importante: o `value` emitido é **sempre o texto formatado** (igual ao que aparece no input).
|
|
|
|
```vue
|
|
<template>
|
|
<EliEntradaTexto
|
|
v-model:value="documento"
|
|
:opcoes="{ rotulo: 'CPF/CNPJ', formato: 'cpfCnpj' }"
|
|
/>
|
|
|
|
<EliEntradaTexto
|
|
v-model:value="telefone"
|
|
:opcoes="{ rotulo: 'Telefone', formato: 'telefone' }"
|
|
/>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent, ref } from "vue";
|
|
export default defineComponent({
|
|
setup() {
|
|
const documento = ref<string | null>("");
|
|
const telefone = ref<string | null>("");
|
|
return { documento, telefone };
|
|
},
|
|
});
|
|
</script>
|
|
```
|
|
|
|
### Data e hora (entrada) com suporte a UTC/Z
|
|
|
|
```vue
|
|
<template>
|
|
<!-- Valor chega do backend em ISO 8601 (UTC/offset), e o componente exibe em horário local -->
|
|
<EliEntradaDataHora v-model:value="dataHora" :opcoes="{ rotulo: 'Agendamento' }" />
|
|
|
|
<!-- Somente data -->
|
|
<EliEntradaDataHora v-model:value="data" :opcoes="{ rotulo: 'Nascimento', modo: 'data' }" />
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent, ref } from "vue";
|
|
|
|
export default defineComponent({
|
|
setup() {
|
|
const dataHora = ref<string | null>("2026-01-09T16:15:00Z");
|
|
const data = ref<string | null>("2026-01-09T00:00:00-03:00");
|
|
return { dataHora, data };
|
|
},
|
|
});
|
|
</script>
|
|
```
|
|
|
|
---
|
|
|
|
## EliTabela (com filtro avançado)
|
|
|
|
O componente `EliTabela` suporta:
|
|
- ordenação
|
|
- paginação
|
|
- caixa de busca
|
|
- **filtro avançado (modal)**
|
|
|
|
### Contrato da tabela (resumo)
|
|
|
|
O tipo principal é `EliTabelaConsulta<T>` (genérico), exportado de `eli-vue`.
|
|
|
|
O `filtroAvancado` é uma lista de filtros pré-definidos (o usuário só escolhe quais usar e informa valores):
|
|
|
|
```ts
|
|
filtroAvancado?: {
|
|
rotulo: string
|
|
coluna: keyof T
|
|
operador: string // ex.: "like", "=", ">", "in", "isNull"
|
|
entrada: ["texto" | "numero" | "dataHora", { rotulo: string; ... }]
|
|
}[]
|
|
```
|
|
|
|
### Exemplo mínimo
|
|
|
|
```ts
|
|
import { EliTabela, celulaTabela } from "eli-vue";
|
|
import type { EliTabelaConsulta } from "eli-vue";
|
|
import type { ComponenteEntrada } from "eli-vue/dist/types/componentes/EliEntrada/tiposEntradas";
|
|
|
|
type Linha = { nome: string; documento: string; email: string };
|
|
|
|
const tabela: EliTabelaConsulta<Linha> = {
|
|
nome: "Exemplo",
|
|
mostrarCaixaDeBusca: true,
|
|
registros_por_consulta: 10,
|
|
colunas: [
|
|
{ rotulo: "Nome", celula: (l) => celulaTabela("textoSimples", { texto: l.nome }), visivel: true },
|
|
],
|
|
filtroAvancado: [
|
|
{
|
|
rotulo: "Documento",
|
|
coluna: "documento",
|
|
operador: "like",
|
|
entrada: ["texto", { rotulo: "Documento", formato: "cpfCnpj" }] as unknown as ComponenteEntrada,
|
|
},
|
|
],
|
|
consulta: async () => ({
|
|
cod: 0,
|
|
eCerto: true,
|
|
eErro: false,
|
|
mensagem: undefined,
|
|
valor: { quantidade: 0, valores: [] },
|
|
}),
|
|
};
|
|
|
|
```
|
|
|
|
---
|
|
|
|
## Células da EliTabela (celulaTabela)
|
|
|
|
O `eli-vue` expõe o helper `celulaTabela(tipo, dados)` para construir células tipadas.
|
|
|
|
Tipos disponíveis atualmente:
|
|
|
|
- `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 }`
|
|
|
|
### Exemplo: célula `tags`
|
|
|
|
```ts
|
|
import { celulaTabela } from "eli-vue";
|
|
import { BadgeCheck, Pencil } from "lucide-vue-next";
|
|
|
|
celula: (l) =>
|
|
celulaTabela("tags", {
|
|
opcoes: [
|
|
{ rotulo: "Ativo", cor: "success", icone: BadgeCheck },
|
|
{ rotulo: "Editar", cor: "primary", icone: Pencil, acao: () => editar(l) },
|
|
],
|
|
})
|
|
```
|
|
|
|
### Exemplo: célula `data`
|
|
|
|
```ts
|
|
import { celulaTabela } from "eli-vue";
|
|
|
|
celula: (l) =>
|
|
celulaTabela("data", {
|
|
valor: l.criado_em, // ISO
|
|
formato: "data", // "data" | "data_hora" | "relativo"
|
|
})
|
|
```
|
|
|
|
> Observação: em modo simulação/local, a tabela pode buscar uma lista completa e aplicar filtro/paginação localmente.
|
|
|
|
---
|
|
|
|
## 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
|
|
|
|
Confirme que o projeto importou:
|
|
|
|
- `vuetify/styles`
|
|
- `eli-vue/dist/eli-vue.css`
|
|
|
|
### 3) Ícones não aparecem
|
|
|
|
Alguns exemplos usam `<v-icon>` (MDI). O `eli-vue` **não instala** ícones automaticamente no projeto consumidor.
|
|
|
|
---
|
|
|
|
## Como a IA deve agir ao modificar um projeto consumidor
|
|
|
|
Quando for integrar `eli-vue` num projeto existente:
|
|
|
|
1) Verifique se **Vue 3** e **Vuetify 3** já estão configurados.
|
|
2) Prefira usar o **plugin** do `eli-vue` (simplifica registro).
|
|
3) Garanta o import do CSS do pacote (`eli-vue/dist/eli-vue.css`).
|
|
4) Ao ver erros de tipos, valide se o projeto está usando TypeScript e se o build está resolvendo `types` corretamente.
|
|
|
|
---
|
|
|
|
## Quando este arquivo deve ser atualizado
|
|
|
|
Atualize este `IA.md` quando houver mudanças em qualquer um destes pontos:
|
|
|
|
- caminho/nome do CSS em `dist/`
|
|
- forma de instalação e/ou peerDependencies
|
|
- forma de uso do plugin/export principal
|
|
- lista de exports públicos (novos componentes, renomes, remoções)
|
|
- mudanças de comportamento relevantes para consumo
|