This commit is contained in:
Luiz Silva 2026-01-29 18:31:52 -03:00
parent 8c5a31ef30
commit a693081023
34 changed files with 14887 additions and 1146 deletions

95
IA.md
View file

@ -69,6 +69,8 @@ import {
EliEntradaTexto,
EliEntradaNumero,
EliEntradaDataHora,
EliEntradaParagrafo,
EliEntradaSelecao,
} from "eli-vue";
```
@ -116,6 +118,57 @@ export default defineComponent({
</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).
@ -226,6 +279,48 @@ const tabela: EliTabelaConsulta<Linha> = {
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.

View file

@ -53,6 +53,8 @@ src/
EliTabela.vue
index.ts
README.md
celulas/
README.md
tipos/
botao.ts
indicador.ts
@ -141,6 +143,8 @@ import {
EliEntradaTexto,
EliEntradaNumero,
EliEntradaDataHora,
EliEntradaParagrafo,
EliEntradaSelecao,
} from "eli-vue";
```
@ -238,6 +242,54 @@ export default defineComponent({
</script>
```
### EliTabela — célula `tags`
Você pode renderizar múltiplas tags/chips numa célula usando `celulaTabela("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) },
],
})
```
### EliTabela — célula `numero` com prefixo/sufixo
Para representar **moeda** ou **unidade de medida**, a célula `numero` aceita `prefixo` e `sufixo`:
```ts
import { celulaTabela } from "eli-vue";
// moeda
celula: (l) => celulaTabela("numero", { numero: l.total, prefixo: "R$" })
// unidade
celula: (l) => celulaTabela("numero", { numero: l.peso, sufixo: "kg" })
```
### EliTabela — célula `data`
Para exibir datas (ISO 8601) com diferentes formatos, use a célula `data`:
```ts
import { celulaTabela } from "eli-vue";
// somente data
celula: (l) => celulaTabela("data", { valor: l.criado_em, formato: "data" })
// data e hora
celula: (l) => celulaTabela("data", { valor: l.criado_em, formato: "data_hora" })
// relativo (dayjs)
celula: (l) => celulaTabela("data", { valor: l.atualizado_em, formato: "relativo" })
```
## Troubleshooting (problemas comuns)
### 1) "Failed to resolve component" / componente não registrado

2
dist/eli-vue.css vendored

File diff suppressed because one or more lines are too long

2451
dist/eli-vue.es.js vendored

File diff suppressed because it is too large Load diff

32
dist/eli-vue.umd.js vendored

File diff suppressed because one or more lines are too long

View file

@ -191,8 +191,8 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
onChange?: ((_v: string | null) => any) | undefined;
onFocus?: (() => any) | undefined;
onBlur?: (() => any) | undefined;
onAlterar?: ((_v: string | null) => any) | undefined;
"onUpdate:modelValue"?: ((_v: string | null) => any) | undefined;
onAlterar?: ((_v: string | null) => any) | undefined;
onFoco?: (() => any) | undefined;
onDesfoco?: (() => any) | undefined;
}>, {
@ -223,8 +223,8 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
};
value: string | null | undefined;
placeholder: string;
rotulo: string;
modelValue: string | null;
rotulo: string;
desabilitado: boolean;
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
declare const _default: typeof __VLS_export;

View file

@ -1,5 +1,7 @@
import EliEntradaTexto from "./EliEntradaTexto.vue";
import EliEntradaNumero from "./EliEntradaNumero.vue";
import EliEntradaDataHora from "./EliEntradaDataHora.vue";
export { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora };
import EliEntradaParagrafo from "./EliEntradaParagrafo.vue";
import EliEntradaSelecao from "./EliEntradaSelecao.vue";
export { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora, EliEntradaParagrafo, EliEntradaSelecao };
export type { PadroesEntradas, TipoEntrada } from "./tiposEntradas";

File diff suppressed because one or more lines are too long

View file

@ -84,6 +84,53 @@ export type PadroesEntradas = {
/** Variante do v-text-field (Vuetify). */
variante?: import("../../tipos").CampoVariante;
}>;
paragrafo: tipoPadraoEntrada<string | null | undefined, {
/** Quantidade de linhas visíveis no textarea (Vuetify `rows`). */
linhas?: number;
/** Limite máximo de caracteres permitidos (se definido). */
limiteCaracteres?: number;
/** Se true, mostra ícone para limpar o valor (Vuetify clearable). */
limpavel?: boolean;
/** Estado de erro (visual). */
erro?: boolean;
/** Mensagens de erro. */
mensagensErro?: string | string[];
/** Texto de apoio. */
dica?: string;
/** Mantém a dica sempre visível. */
dicaPersistente?: boolean;
/** Densidade do campo (Vuetify). */
densidade?: import("../../tipos").CampoDensidade;
/** Variante do v-text-field (Vuetify). */
variante?: import("../../tipos").CampoVariante;
}>;
selecao: tipoPadraoEntrada<string | null | undefined, {
/**
* Carrega os itens da seleção (sincrono ou async).
* - Cada item precisa ter uma chave estável (value) e um rótulo (title).
*/
itens: () => {
chave: string;
rotulo: string;
}[] | Promise<{
chave: string;
rotulo: string;
}[]>;
/** Se true, mostra ícone para limpar o valor (Vuetify clearable). */
limpavel?: boolean;
/** Estado de erro (visual). */
erro?: boolean;
/** Mensagens de erro. */
mensagensErro?: string | string[];
/** Texto de apoio. */
dica?: string;
/** Mantém a dica sempre visível. */
dicaPersistente?: boolean;
/** Densidade do campo (Vuetify). */
densidade?: import("../../tipos").CampoDensidade;
/** Variante do v-text-field (Vuetify). */
variante?: import("../../tipos").CampoVariante;
}>;
};
/**
* União dos tipos de entrada suportados.

View file

@ -453,6 +453,37 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
acao?: () => void;
} | {
numero: number;
prefixo?: string;
sufixo?: string;
acao?: () => void;
} | {
opcoes: {
rotulo: string;
cor
/**
* EliTabela
* Componente de tabela consultável com busca, paginação, ordenação e ações por linha.
*/
/** Dependências do Vue (Composition API) */
?: string;
icone
/**
* EliTabela
* Componente de tabela consultável com busca, paginação, ordenação e ações por linha.
*/
/** Dependências do Vue (Composition API) */
?: import("lucide-vue-next").LucideIcon;
acao
/**
* EliTabela
* Componente de tabela consultável com busca, paginação, ordenação e ações por linha.
*/
/** Dependências do Vue (Composition API) */
?: () => void;
}[];
} | {
valor: string;
formato: "data" | "data_hora" | "relativo";
acao?: () => void;
}>;
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
@ -495,6 +526,37 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
acao?: () => void;
} | {
numero: number;
prefixo?: string;
sufixo?: string;
acao?: () => void;
} | {
opcoes: {
rotulo: string;
cor
/**
* EliTabela
* Componente de tabela consultável com busca, paginação, ordenação e ações por linha.
*/
/** Dependências do Vue (Composition API) */
?: string;
icone
/**
* EliTabela
* Componente de tabela consultável com busca, paginação, ordenação e ações por linha.
*/
/** Dependências do Vue (Composition API) */
?: import("lucide-vue-next").LucideIcon;
acao
/**
* EliTabela
* Componente de tabela consultável com busca, paginação, ordenação e ações por linha.
*/
/** Dependências do Vue (Composition API) */
?: () => void;
}[];
} | {
valor: string;
formato: "data" | "data_hora" | "relativo";
acao?: () => void;
}>;
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
@ -710,6 +772,35 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
sufixo?: string | undefined;
prefixo?: string | undefined;
precisao?: number | undefined;
}] | readonly ["paragrafo", {
rotulo: string;
placeholder?: string | undefined;
linhas?: number | undefined;
limiteCaracteres?: number | undefined;
limpavel?: boolean | undefined;
erro?: boolean | undefined;
mensagensErro?: string | string[] | undefined;
dica?: string | undefined;
dicaPersistente?: boolean | undefined;
densidade?: import("../../tipos/entrada.js").CampoDensidade | undefined;
variante?: import("../../tipos/entrada.js").CampoVariante | undefined;
}] | readonly ["selecao", {
rotulo: string;
placeholder?: string | undefined;
itens: () => {
chave: string;
rotulo: string;
}[] | Promise<{
chave: string;
rotulo: string;
}[]>;
limpavel?: boolean | undefined;
erro?: boolean | undefined;
mensagensErro?: string | string[] | undefined;
dica?: string | undefined;
dicaPersistente?: boolean | undefined;
densidade?: import("../../tipos/entrada.js").CampoDensidade | undefined;
variante?: import("../../tipos/entrada.js").CampoVariante | undefined;
}];
operador: string;
valor: any;
@ -744,6 +835,35 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
sufixo?: string | undefined;
prefixo?: string | undefined;
precisao?: number | undefined;
}] | readonly ["paragrafo", {
rotulo: string;
placeholder?: string | undefined;
linhas?: number | undefined;
limiteCaracteres?: number | undefined;
limpavel?: boolean | undefined;
erro?: boolean | undefined;
mensagensErro?: string | string[] | undefined;
dica?: string | undefined;
dicaPersistente?: boolean | undefined;
densidade?: import("../../tipos/entrada.js").CampoDensidade | undefined;
variante?: import("../../tipos/entrada.js").CampoVariante | undefined;
}] | readonly ["selecao", {
rotulo: string;
placeholder?: string | undefined;
itens: () => {
chave: string;
rotulo: string;
}[] | Promise<{
chave: string;
rotulo: string;
}[]>;
limpavel?: boolean | undefined;
erro?: boolean | undefined;
mensagensErro?: string | string[] | undefined;
dica?: string | undefined;
dicaPersistente?: boolean | undefined;
densidade?: import("../../tipos/entrada.js").CampoDensidade | undefined;
variante?: import("../../tipos/entrada.js").CampoVariante | undefined;
}];
operador: string;
valor: any;
@ -1064,8 +1184,8 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
onChange?: ((_v: string | null) => any) | undefined;
onFocus?: (() => any) | undefined;
onBlur?: (() => any) | undefined;
onAlterar?: ((_v: string | null) => any) | undefined;
"onUpdate:modelValue"?: ((_v: string | null) => any) | undefined;
onAlterar?: ((_v: string | null) => any) | undefined;
onFoco?: (() => any) | undefined;
onDesfoco?: (() => any) | undefined;
}>, {
@ -1096,8 +1216,8 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
};
value: string | null | undefined;
placeholder: string;
rotulo: string;
modelValue: string | null;
rotulo: string;
desabilitado: boolean;
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
opcoesEntrada: (entrada: import("../EliEntrada/tiposEntradas.js").ComponenteEntrada) => any;

View file

@ -101,6 +101,19 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
acao?: () => void;
} | {
numero: number;
prefixo?: string;
sufixo?: string;
acao?: () => void;
} | {
opcoes: {
rotulo: string;
cor?: string;
icone?: import("lucide-vue-next").LucideIcon;
acao?: () => void;
}[];
} | {
valor: string;
formato: "data" | "data_hora" | "relativo";
acao?: () => void;
}>;
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
@ -143,6 +156,19 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
acao?: () => void;
} | {
numero: number;
prefixo?: string;
sufixo?: string;
acao?: () => void;
} | {
opcoes: {
rotulo: string;
cor?: string;
icone?: import("lucide-vue-next").LucideIcon;
acao?: () => void;
}[];
} | {
valor: string;
formato: "data" | "data_hora" | "relativo";
acao?: () => void;
}>;
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{

View file

@ -34,6 +34,19 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
acao?: () => void;
} | {
numero: number;
prefixo?: string;
sufixo?: string;
acao?: () => void;
} | {
opcoes: {
rotulo: string;
cor?: string;
icone?: import("lucide-vue-next").LucideIcon;
acao?: () => void;
}[];
} | {
valor: string;
formato: "data" | "data_hora" | "relativo";
acao?: () => void;
}>;
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{

View file

@ -49,6 +49,35 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
sufixo?: string | undefined;
prefixo?: string | undefined;
precisao?: number | undefined;
}] | readonly ["paragrafo", {
rotulo: string;
placeholder?: string | undefined;
linhas?: number | undefined;
limiteCaracteres?: number | undefined;
limpavel?: boolean | undefined;
erro?: boolean | undefined;
mensagensErro?: string | string[] | undefined;
dica?: string | undefined;
dicaPersistente?: boolean | undefined;
densidade?: import("../../tipos").CampoDensidade | undefined;
variante?: import("../../tipos").CampoVariante | undefined;
}] | readonly ["selecao", {
rotulo: string;
placeholder?: string | undefined;
itens: () => {
chave: string;
rotulo: string;
}[] | Promise<{
chave: string;
rotulo: string;
}[]>;
limpavel?: boolean | undefined;
erro?: boolean | undefined;
mensagensErro?: string | string[] | undefined;
dica?: string | undefined;
dicaPersistente?: boolean | undefined;
densidade?: import("../../tipos").CampoDensidade | undefined;
variante?: import("../../tipos").CampoVariante | undefined;
}];
operador: string;
valor: any;
@ -78,6 +107,35 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
sufixo?: string | undefined;
prefixo?: string | undefined;
precisao?: number | undefined;
}] | readonly ["paragrafo", {
rotulo: string;
placeholder?: string | undefined;
linhas?: number | undefined;
limiteCaracteres?: number | undefined;
limpavel?: boolean | undefined;
erro?: boolean | undefined;
mensagensErro?: string | string[] | undefined;
dica?: string | undefined;
dicaPersistente?: boolean | undefined;
densidade?: import("../../tipos").CampoDensidade | undefined;
variante?: import("../../tipos").CampoVariante | undefined;
}] | readonly ["selecao", {
rotulo: string;
placeholder?: string | undefined;
itens: () => {
chave: string;
rotulo: string;
}[] | Promise<{
chave: string;
rotulo: string;
}[]>;
limpavel?: boolean | undefined;
erro?: boolean | undefined;
mensagensErro?: string | string[] | undefined;
dica?: string | undefined;
dicaPersistente?: boolean | undefined;
densidade?: import("../../tipos").CampoDensidade | undefined;
variante?: import("../../tipos").CampoVariante | undefined;
}];
operador: string;
valor: any;
@ -398,8 +456,8 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
onChange?: ((_v: string | null) => any) | undefined;
onFocus?: (() => any) | undefined;
onBlur?: (() => any) | undefined;
onAlterar?: ((_v: string | null) => any) | undefined;
"onUpdate:modelValue"?: ((_v: string | null) => any) | undefined;
onAlterar?: ((_v: string | null) => any) | undefined;
onFoco?: (() => any) | undefined;
onDesfoco?: (() => any) | undefined;
}>, {
@ -430,8 +488,8 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
};
value: string | null | undefined;
placeholder: string;
rotulo: string;
modelValue: string | null;
rotulo: string;
desabilitado: boolean;
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
opcoesEntrada: (entrada: ComponenteEntrada) => any;

View file

@ -16,6 +16,19 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
acao?: () => void;
} | {
numero: number;
prefixo?: string;
sufixo?: string;
acao?: () => void;
} | {
opcoes: {
rotulo: string;
cor?: string;
icone?: import("lucide-vue-next").LucideIcon;
acao?: () => void;
}[];
} | {
valor: string;
formato: "data" | "data_hora" | "relativo";
acao?: () => void;
}>;
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{

View file

@ -7,8 +7,11 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
}>, {
dados: {
numero: number;
prefixo?: string;
sufixo?: string;
acao?: () => void;
} | undefined;
textoNumero: import("vue").ComputedRef<string>;
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
dados: {
type: PropType<TiposTabelaCelulas["numero"]>;

View file

@ -34,11 +34,711 @@ export declare const registryTabelaCelulas: {
}>, {
dados: {
numero: number;
prefixo?: string;
sufixo?: string;
acao?: () => void;
} | undefined;
textoNumero: import("vue").ComputedRef<string>;
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
dados: {
type: import("vue").PropType<import("./tiposTabelaCelulas").TiposTabelaCelulas["numero"]>;
};
}>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
readonly tags: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
dados: {
type: import("vue").PropType<import("./tiposTabelaCelulas").TiposTabelaCelulas["tags"]>;
required: false;
};
}>, {
dados: {
opcoes: {
rotulo: string;
cor?: string;
icone?: import("lucide-vue-next").LucideIcon;
acao?: () => void;
}[];
} | undefined;
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
dados: {
type: import("vue").PropType<import("./tiposTabelaCelulas").TiposTabelaCelulas["tags"]>;
required: false;
};
}>> & Readonly<{}>, {}, {}, {
VChip: {
new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<{
style: string | false | import("vue").StyleValue[] | import("vue").CSSProperties | null;
density: import("vuetify/lib/composables/density.mjs").Density;
tile: boolean;
tag: string | import("vuetify/lib/types.mjs").JSXComponent;
variant: "elevated" | "flat" | "outlined" | "plain" | "text" | "tonal";
disabled: boolean;
size: string | number;
replace: boolean;
exact: boolean;
closable: boolean;
closeIcon: import("vuetify/lib/composables/icons.mjs").IconValue;
closeLabel: string;
draggable: boolean;
filter: boolean;
filterIcon: import("vuetify/lib/composables/icons.mjs").IconValue;
label: boolean;
pill: boolean;
ripple: boolean | {
class?: string | undefined;
keys?: string[] | undefined;
};
modelValue: boolean;
} & {
theme?: string | undefined;
class?: any;
border?: string | number | boolean | undefined;
elevation?: string | number | undefined;
rounded?: string | number | boolean | undefined;
color?: string | undefined;
value?: any;
selectedClass?: string | undefined;
href?: string | undefined;
to?: string | import("vue-router").RouteLocationAsPathGeneric | import("vue-router").RouteLocationAsRelativeGeneric | undefined;
activeClass?: string | undefined;
appendAvatar?: string | undefined;
appendIcon?: import("vuetify/lib/composables/icons.mjs").IconValue | undefined;
baseColor?: string | undefined;
link?: boolean | undefined;
prependAvatar?: string | undefined;
prependIcon?: import("vuetify/lib/composables/icons.mjs").IconValue | undefined;
text?: string | number | boolean | undefined;
onClick?: ((args_0: MouseEvent) => void) | undefined;
onClickOnce?: ((args_0: MouseEvent) => void) | undefined;
} & {
$children?: {
default?: ((arg: {
isSelected: boolean | undefined;
selectedClass: boolean | (string | undefined)[] | undefined;
select: ((value: boolean) => void) | undefined;
toggle: (() => void) | undefined;
value: unknown;
disabled: boolean;
}) => import("vue").VNodeChild) | undefined;
label?: (() => import("vue").VNodeChild) | undefined;
prepend?: (() => import("vue").VNodeChild) | undefined;
append?: (() => import("vue").VNodeChild) | undefined;
close?: (() => import("vue").VNodeChild) | undefined;
filter?: (() => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean | undefined;
} | ((arg: {
isSelected: boolean | undefined;
selectedClass: boolean | (string | undefined)[] | undefined;
select: ((value: boolean) => void) | undefined;
toggle: (() => void) | undefined;
value: unknown;
disabled: boolean;
}) => import("vue").VNodeChild) | import("vue").VNodeChild;
"v-slots"?: {
default?: false | ((arg: {
isSelected: boolean | undefined;
selectedClass: boolean | (string | undefined)[] | undefined;
select: ((value: boolean) => void) | undefined;
toggle: (() => void) | undefined;
value: unknown;
disabled: boolean;
}) => import("vue").VNodeChild) | undefined;
label?: false | (() => import("vue").VNodeChild) | undefined;
prepend?: false | (() => import("vue").VNodeChild) | undefined;
append?: false | (() => import("vue").VNodeChild) | undefined;
close?: false | (() => import("vue").VNodeChild) | undefined;
filter?: false | (() => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:append"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:close"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:default"?: false | ((arg: {
isSelected: boolean | undefined;
selectedClass: boolean | (string | undefined)[] | undefined;
select: ((value: boolean) => void) | undefined;
toggle: (() => void) | undefined;
value: unknown;
disabled: boolean;
}) => import("vue").VNodeChild) | undefined;
"v-slot:filter"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:label"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:prepend"?: false | (() => import("vue").VNodeChild) | undefined;
} & {
onClick?: ((e: KeyboardEvent | MouseEvent) => any) | undefined;
"onClick:close"?: ((e: MouseEvent) => any) | undefined;
"onGroup:selected"?: ((val: {
value: boolean;
}) => any) | undefined;
"onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
}, () => false | JSX.Element, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
"click:close": (e: MouseEvent) => true;
"update:modelValue": (value: boolean) => true;
"group:selected": (val: {
value: boolean;
}) => true;
click: (e: KeyboardEvent | MouseEvent) => true;
}, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, {
style: import("vue").StyleValue;
density: import("vuetify/lib/composables/density.mjs").Density;
rounded: string | number | boolean;
tile: boolean;
tag: string | import("vuetify/lib/types.mjs").JSXComponent;
variant: "elevated" | "flat" | "outlined" | "plain" | "text" | "tonal";
disabled: boolean;
size: string | number;
replace: boolean;
exact: boolean;
closable: boolean;
closeIcon: import("vuetify/lib/composables/icons.mjs").IconValue;
closeLabel: string;
draggable: boolean;
filter: boolean;
filterIcon: import("vuetify/lib/composables/icons.mjs").IconValue;
label: boolean;
link: boolean;
pill: boolean;
ripple: boolean | {
class?: string | undefined;
keys?: string[] | undefined;
} | undefined;
text: string | number | boolean;
modelValue: boolean;
}, true, {}, import("vue").SlotsType<Partial<{
default: (arg: {
isSelected: boolean | undefined;
selectedClass: boolean | (string | undefined)[] | undefined;
select: ((value: boolean) => void) | undefined;
toggle: (() => void) | undefined;
value: unknown;
disabled: boolean;
}) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
label: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
prepend: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
append: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
close: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
filter: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
}>>, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
P: {};
B: {};
D: {};
C: {};
M: {};
Defaults: {};
}, {
style: string | false | import("vue").StyleValue[] | import("vue").CSSProperties | null;
density: import("vuetify/lib/composables/density.mjs").Density;
tile: boolean;
tag: string | import("vuetify/lib/types.mjs").JSXComponent;
variant: "elevated" | "flat" | "outlined" | "plain" | "text" | "tonal";
disabled: boolean;
size: string | number;
replace: boolean;
exact: boolean;
closable: boolean;
closeIcon: import("vuetify/lib/composables/icons.mjs").IconValue;
closeLabel: string;
draggable: boolean;
filter: boolean;
filterIcon: import("vuetify/lib/composables/icons.mjs").IconValue;
label: boolean;
pill: boolean;
ripple: boolean | {
class?: string | undefined;
keys?: string[] | undefined;
};
modelValue: boolean;
} & {
theme?: string | undefined;
class?: any;
border?: string | number | boolean | undefined;
elevation?: string | number | undefined;
rounded?: string | number | boolean | undefined;
color?: string | undefined;
value?: any;
selectedClass?: string | undefined;
href?: string | undefined;
to?: string | import("vue-router").RouteLocationAsPathGeneric | import("vue-router").RouteLocationAsRelativeGeneric | undefined;
activeClass?: string | undefined;
appendAvatar?: string | undefined;
appendIcon?: import("vuetify/lib/composables/icons.mjs").IconValue | undefined;
baseColor?: string | undefined;
link?: boolean | undefined;
prependAvatar?: string | undefined;
prependIcon?: import("vuetify/lib/composables/icons.mjs").IconValue | undefined;
text?: string | number | boolean | undefined;
onClick?: ((args_0: MouseEvent) => void) | undefined;
onClickOnce?: ((args_0: MouseEvent) => void) | undefined;
} & {
$children?: {
default?: ((arg: {
isSelected: boolean | undefined;
selectedClass: boolean | (string | undefined)[] | undefined;
select: ((value: boolean) => void) | undefined;
toggle: (() => void) | undefined;
value: unknown;
disabled: boolean;
}) => import("vue").VNodeChild) | undefined;
label?: (() => import("vue").VNodeChild) | undefined;
prepend?: (() => import("vue").VNodeChild) | undefined;
append?: (() => import("vue").VNodeChild) | undefined;
close?: (() => import("vue").VNodeChild) | undefined;
filter?: (() => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean | undefined;
} | ((arg: {
isSelected: boolean | undefined;
selectedClass: boolean | (string | undefined)[] | undefined;
select: ((value: boolean) => void) | undefined;
toggle: (() => void) | undefined;
value: unknown;
disabled: boolean;
}) => import("vue").VNodeChild) | import("vue").VNodeChild;
"v-slots"?: {
default?: false | ((arg: {
isSelected: boolean | undefined;
selectedClass: boolean | (string | undefined)[] | undefined;
select: ((value: boolean) => void) | undefined;
toggle: (() => void) | undefined;
value: unknown;
disabled: boolean;
}) => import("vue").VNodeChild) | undefined;
label?: false | (() => import("vue").VNodeChild) | undefined;
prepend?: false | (() => import("vue").VNodeChild) | undefined;
append?: false | (() => import("vue").VNodeChild) | undefined;
close?: false | (() => import("vue").VNodeChild) | undefined;
filter?: false | (() => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:append"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:close"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:default"?: false | ((arg: {
isSelected: boolean | undefined;
selectedClass: boolean | (string | undefined)[] | undefined;
select: ((value: boolean) => void) | undefined;
toggle: (() => void) | undefined;
value: unknown;
disabled: boolean;
}) => import("vue").VNodeChild) | undefined;
"v-slot:filter"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:label"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:prepend"?: false | (() => import("vue").VNodeChild) | undefined;
} & {
onClick?: ((e: KeyboardEvent | MouseEvent) => any) | undefined;
"onClick:close"?: ((e: MouseEvent) => any) | undefined;
"onGroup:selected"?: ((val: {
value: boolean;
}) => any) | undefined;
"onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
}, () => false | JSX.Element, {}, {}, {}, {
style: import("vue").StyleValue;
density: import("vuetify/lib/composables/density.mjs").Density;
rounded: string | number | boolean;
tile: boolean;
tag: string | import("vuetify/lib/types.mjs").JSXComponent;
variant: "elevated" | "flat" | "outlined" | "plain" | "text" | "tonal";
disabled: boolean;
size: string | number;
replace: boolean;
exact: boolean;
closable: boolean;
closeIcon: import("vuetify/lib/composables/icons.mjs").IconValue;
closeLabel: string;
draggable: boolean;
filter: boolean;
filterIcon: import("vuetify/lib/composables/icons.mjs").IconValue;
label: boolean;
link: boolean;
pill: boolean;
ripple: boolean | {
class?: string | undefined;
keys?: string[] | undefined;
} | undefined;
text: string | number | boolean;
modelValue: boolean;
}>;
__isFragment?: undefined;
__isTeleport?: undefined;
__isSuspense?: undefined;
} & import("vue").ComponentOptionsBase<{
style: string | false | import("vue").StyleValue[] | import("vue").CSSProperties | null;
density: import("vuetify/lib/composables/density.mjs").Density;
tile: boolean;
tag: string | import("vuetify/lib/types.mjs").JSXComponent;
variant: "elevated" | "flat" | "outlined" | "plain" | "text" | "tonal";
disabled: boolean;
size: string | number;
replace: boolean;
exact: boolean;
closable: boolean;
closeIcon: import("vuetify/lib/composables/icons.mjs").IconValue;
closeLabel: string;
draggable: boolean;
filter: boolean;
filterIcon: import("vuetify/lib/composables/icons.mjs").IconValue;
label: boolean;
pill: boolean;
ripple: boolean | {
class?: string | undefined;
keys?: string[] | undefined;
};
modelValue: boolean;
} & {
theme?: string | undefined;
class?: any;
border?: string | number | boolean | undefined;
elevation?: string | number | undefined;
rounded?: string | number | boolean | undefined;
color?: string | undefined;
value?: any;
selectedClass?: string | undefined;
href?: string | undefined;
to?: string | import("vue-router").RouteLocationAsPathGeneric | import("vue-router").RouteLocationAsRelativeGeneric | undefined;
activeClass?: string | undefined;
appendAvatar?: string | undefined;
appendIcon?: import("vuetify/lib/composables/icons.mjs").IconValue | undefined;
baseColor?: string | undefined;
link?: boolean | undefined;
prependAvatar?: string | undefined;
prependIcon?: import("vuetify/lib/composables/icons.mjs").IconValue | undefined;
text?: string | number | boolean | undefined;
onClick?: ((args_0: MouseEvent) => void) | undefined;
onClickOnce?: ((args_0: MouseEvent) => void) | undefined;
} & {
$children?: {
default?: ((arg: {
isSelected: boolean | undefined;
selectedClass: boolean | (string | undefined)[] | undefined;
select: ((value: boolean) => void) | undefined;
toggle: (() => void) | undefined;
value: unknown;
disabled: boolean;
}) => import("vue").VNodeChild) | undefined;
label?: (() => import("vue").VNodeChild) | undefined;
prepend?: (() => import("vue").VNodeChild) | undefined;
append?: (() => import("vue").VNodeChild) | undefined;
close?: (() => import("vue").VNodeChild) | undefined;
filter?: (() => import("vue").VNodeChild) | undefined;
} | {
$stable?: boolean | undefined;
} | ((arg: {
isSelected: boolean | undefined;
selectedClass: boolean | (string | undefined)[] | undefined;
select: ((value: boolean) => void) | undefined;
toggle: (() => void) | undefined;
value: unknown;
disabled: boolean;
}) => import("vue").VNodeChild) | import("vue").VNodeChild;
"v-slots"?: {
default?: false | ((arg: {
isSelected: boolean | undefined;
selectedClass: boolean | (string | undefined)[] | undefined;
select: ((value: boolean) => void) | undefined;
toggle: (() => void) | undefined;
value: unknown;
disabled: boolean;
}) => import("vue").VNodeChild) | undefined;
label?: false | (() => import("vue").VNodeChild) | undefined;
prepend?: false | (() => import("vue").VNodeChild) | undefined;
append?: false | (() => import("vue").VNodeChild) | undefined;
close?: false | (() => import("vue").VNodeChild) | undefined;
filter?: false | (() => import("vue").VNodeChild) | undefined;
} | undefined;
} & {
"v-slot:append"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:close"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:default"?: false | ((arg: {
isSelected: boolean | undefined;
selectedClass: boolean | (string | undefined)[] | undefined;
select: ((value: boolean) => void) | undefined;
toggle: (() => void) | undefined;
value: unknown;
disabled: boolean;
}) => import("vue").VNodeChild) | undefined;
"v-slot:filter"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:label"?: false | (() => import("vue").VNodeChild) | undefined;
"v-slot:prepend"?: false | (() => import("vue").VNodeChild) | undefined;
} & {
onClick?: ((e: KeyboardEvent | MouseEvent) => any) | undefined;
"onClick:close"?: ((e: MouseEvent) => any) | undefined;
"onGroup:selected"?: ((val: {
value: boolean;
}) => any) | undefined;
"onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
}, () => false | JSX.Element, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
"click:close": (e: MouseEvent) => true;
"update:modelValue": (value: boolean) => true;
"group:selected": (val: {
value: boolean;
}) => true;
click: (e: KeyboardEvent | MouseEvent) => true;
}, string, {
style: import("vue").StyleValue;
density: import("vuetify/lib/composables/density.mjs").Density;
rounded: string | number | boolean;
tile: boolean;
tag: string | import("vuetify/lib/types.mjs").JSXComponent;
variant: "elevated" | "flat" | "outlined" | "plain" | "text" | "tonal";
disabled: boolean;
size: string | number;
replace: boolean;
exact: boolean;
closable: boolean;
closeIcon: import("vuetify/lib/composables/icons.mjs").IconValue;
closeLabel: string;
draggable: boolean;
filter: boolean;
filterIcon: import("vuetify/lib/composables/icons.mjs").IconValue;
label: boolean;
link: boolean;
pill: boolean;
ripple: boolean | {
class?: string | undefined;
keys?: string[] | undefined;
} | undefined;
text: string | number | boolean;
modelValue: boolean;
}, {}, string, import("vue").SlotsType<Partial<{
default: (arg: {
isSelected: boolean | undefined;
selectedClass: boolean | (string | undefined)[] | undefined;
select: ((value: boolean) => void) | undefined;
toggle: (() => void) | undefined;
value: unknown;
disabled: boolean;
}) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
label: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
prepend: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
append: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
close: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
filter: () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}>[];
}>>, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & import("vuetify/lib/util/defineComponent.mjs").FilterPropsOptions<{
theme: StringConstructor;
class: import("vue").PropType<any>;
style: {
type: import("vue").PropType<import("vue").StyleValue>;
default: null;
};
border: (BooleanConstructor | NumberConstructor | StringConstructor)[];
density: {
type: import("vue").PropType<import("vuetify/lib/composables/density.mjs").Density>;
default: string;
validator: (v: any) => boolean;
};
elevation: {
type: (NumberConstructor | StringConstructor)[];
validator(v: any): boolean;
};
rounded: {
type: (BooleanConstructor | NumberConstructor | StringConstructor)[];
default: undefined;
};
tile: BooleanConstructor;
tag: Omit<{
type: import("vue").PropType<string | import("vuetify/lib/types.mjs").JSXComponent>;
default: string;
}, "default" | "type"> & {
type: import("vue").PropType<string | import("vuetify/lib/types.mjs").JSXComponent>;
default: NonNullable<string | import("vuetify/lib/types.mjs").JSXComponent>;
};
color: StringConstructor;
variant: Omit<{
type: import("vue").PropType<"elevated" | "flat" | "outlined" | "plain" | "text" | "tonal">;
default: string;
validator: (v: any) => boolean;
}, "default" | "type"> & {
type: import("vue").PropType<"elevated" | "flat" | "outlined" | "plain" | "text" | "tonal">;
default: NonNullable<"elevated" | "flat" | "outlined" | "plain" | "text" | "tonal">;
};
value: null;
disabled: BooleanConstructor;
selectedClass: StringConstructor;
size: {
type: (NumberConstructor | StringConstructor)[];
default: string;
};
href: StringConstructor;
replace: BooleanConstructor;
to: import("vue").PropType<string | import("vue-router").RouteLocationAsPathGeneric | import("vue-router").RouteLocationAsRelativeGeneric>;
exact: BooleanConstructor;
activeClass: StringConstructor;
appendAvatar: StringConstructor;
appendIcon: import("vue").PropType<import("vuetify/lib/composables/icons.mjs").IconValue>;
baseColor: StringConstructor;
closable: BooleanConstructor;
closeIcon: {
type: import("vue").PropType<import("vuetify/lib/composables/icons.mjs").IconValue>;
default: string;
};
closeLabel: {
type: StringConstructor;
default: string;
};
draggable: BooleanConstructor;
filter: BooleanConstructor;
filterIcon: {
type: import("vue").PropType<import("vuetify/lib/composables/icons.mjs").IconValue>;
default: string;
};
label: BooleanConstructor;
link: {
type: BooleanConstructor;
default: undefined;
};
pill: BooleanConstructor;
prependAvatar: StringConstructor;
prependIcon: import("vue").PropType<import("vuetify/lib/composables/icons.mjs").IconValue>;
ripple: {
type: import("vue").PropType<boolean | {
class?: string | undefined;
keys?: string[] | undefined;
} | undefined>;
default: boolean;
};
text: {
type: (BooleanConstructor | NumberConstructor | StringConstructor)[];
default: undefined;
};
modelValue: {
type: BooleanConstructor;
default: boolean;
};
onClick: import("vue").PropType<(args_0: MouseEvent) => void>;
onClickOnce: import("vue").PropType<(args_0: MouseEvent) => void>;
}, import("vue").ExtractPropTypes<{
theme: StringConstructor;
class: import("vue").PropType<any>;
style: {
type: import("vue").PropType<import("vue").StyleValue>;
default: null;
};
border: (BooleanConstructor | NumberConstructor | StringConstructor)[];
density: {
type: import("vue").PropType<import("vuetify/lib/composables/density.mjs").Density>;
default: string;
validator: (v: any) => boolean;
};
elevation: {
type: (NumberConstructor | StringConstructor)[];
validator(v: any): boolean;
};
rounded: {
type: (BooleanConstructor | NumberConstructor | StringConstructor)[];
default: undefined;
};
tile: BooleanConstructor;
tag: Omit<{
type: import("vue").PropType<string | import("vuetify/lib/types.mjs").JSXComponent>;
default: string;
}, "default" | "type"> & {
type: import("vue").PropType<string | import("vuetify/lib/types.mjs").JSXComponent>;
default: NonNullable<string | import("vuetify/lib/types.mjs").JSXComponent>;
};
color: StringConstructor;
variant: Omit<{
type: import("vue").PropType<"elevated" | "flat" | "outlined" | "plain" | "text" | "tonal">;
default: string;
validator: (v: any) => boolean;
}, "default" | "type"> & {
type: import("vue").PropType<"elevated" | "flat" | "outlined" | "plain" | "text" | "tonal">;
default: NonNullable<"elevated" | "flat" | "outlined" | "plain" | "text" | "tonal">;
};
value: null;
disabled: BooleanConstructor;
selectedClass: StringConstructor;
size: {
type: (NumberConstructor | StringConstructor)[];
default: string;
};
href: StringConstructor;
replace: BooleanConstructor;
to: import("vue").PropType<string | import("vue-router").RouteLocationAsPathGeneric | import("vue-router").RouteLocationAsRelativeGeneric>;
exact: BooleanConstructor;
activeClass: StringConstructor;
appendAvatar: StringConstructor;
appendIcon: import("vue").PropType<import("vuetify/lib/composables/icons.mjs").IconValue>;
baseColor: StringConstructor;
closable: BooleanConstructor;
closeIcon: {
type: import("vue").PropType<import("vuetify/lib/composables/icons.mjs").IconValue>;
default: string;
};
closeLabel: {
type: StringConstructor;
default: string;
};
draggable: BooleanConstructor;
filter: BooleanConstructor;
filterIcon: {
type: import("vue").PropType<import("vuetify/lib/composables/icons.mjs").IconValue>;
default: string;
};
label: BooleanConstructor;
link: {
type: BooleanConstructor;
default: undefined;
};
pill: BooleanConstructor;
prependAvatar: StringConstructor;
prependIcon: import("vue").PropType<import("vuetify/lib/composables/icons.mjs").IconValue>;
ripple: {
type: import("vue").PropType<boolean | {
class?: string | undefined;
keys?: string[] | undefined;
} | undefined>;
default: boolean;
};
text: {
type: (BooleanConstructor | NumberConstructor | StringConstructor)[];
default: undefined;
};
modelValue: {
type: BooleanConstructor;
default: boolean;
};
onClick: import("vue").PropType<(args_0: MouseEvent) => void>;
onClickOnce: import("vue").PropType<(args_0: MouseEvent) => void>;
}>>;
}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
readonly data: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
dados: {
type: import("vue").PropType<import("./tiposTabelaCelulas").TiposTabelaCelulas["data"]>;
required: false;
};
}>, {
dados: {
valor: string;
formato: "data" | "data_hora" | "relativo";
acao?: () => void;
} | undefined;
textoData: import("vue").ComputedRef<string>;
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
dados: {
type: import("vue").PropType<import("./tiposTabelaCelulas").TiposTabelaCelulas["data"]>;
required: false;
};
}>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
};

View file

@ -1,6 +1,7 @@
/**
* Tipagem dos dados de entrada dos componentes de celulas
*/
import type { LucideIcon } from "lucide-vue-next";
export type TiposTabelaCelulas = {
textoSimples: {
texto: string;
@ -12,6 +13,30 @@ export type TiposTabelaCelulas = {
};
numero: {
numero: number;
/** Texto opcional exibido antes do número (ex.: "R$", "≈"). */
prefixo?: string;
/** Texto opcional exibido depois do número (ex.: "kg", "%"). */
sufixo?: string;
acao?: () => void;
};
tags: {
opcoes: {
/** Texto exibido dentro da tag. */
rotulo: string;
/** Cor do chip (segue as cores do Vuetify, ex.: "primary", "success", "error"). */
cor?: string;
/** Ícone (Lucide) opcional exibido antes do rótulo. */
icone?: LucideIcon;
/** Ação opcional da tag. Quando existir, o chip vira clicável. */
acao?: () => void;
}[];
};
data: {
/** Valor em ISO 8601 (ex.: "2026-01-09T16:15:00Z"). */
valor: string;
/** Define o formato de exibição. */
formato: "data" | "data_hora" | "relativo";
/** Ação opcional ao clicar no valor. */
acao?: () => void;
};
};

View file

@ -5,12 +5,12 @@ import { EliBotao } from "./componentes/botao";
import { EliBadge } from "./componentes/indicador";
import { EliCartao } from "./componentes/cartao";
import { EliTabela } from "./componentes/EliTabela";
import { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora } from "./componentes/EliEntrada";
import { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora, EliEntradaParagrafo, EliEntradaSelecao } from "./componentes/EliEntrada";
export { EliOlaMundo };
export { EliBotao };
export { EliBadge };
export { EliCartao };
export { EliTabela };
export { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora };
export { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora, EliEntradaParagrafo, EliEntradaSelecao };
declare const EliVue: Plugin;
export default EliVue;

View file

@ -1,6 +1,6 @@
{
"name": "eli-vue",
"version": "0.1.71",
"version": "0.1.81",
"private": false,
"main": "./dist/eli-vue.umd.js",
"module": "./dist/eli-vue.es.js",

View file

@ -0,0 +1,66 @@
<template>
<v-textarea
v-model="localValue"
:label="opcoes?.rotulo"
:placeholder="opcoes?.placeholder"
:rows="opcoes?.linhas ?? 4"
:counter="opcoes?.limiteCaracteres"
:maxlength="opcoes?.limiteCaracteres"
:clearable="Boolean(opcoes?.limpavel)"
:error="Boolean(opcoes?.erro)"
:error-messages="opcoes?.mensagensErro"
:hint="opcoes?.dica"
:persistent-hint="Boolean(opcoes?.dicaPersistente)"
:density="opcoes?.densidade ?? 'comfortable'"
:variant="opcoes?.variante ?? 'outlined'"
auto-grow
v-bind="attrs"
@focus="() => emit('focus')"
@blur="() => emit('blur')"
/>
</template>
<script lang="ts">
import { computed, defineComponent, PropType } from "vue";
import { VTextarea } from "vuetify/components";
import type { PadroesEntradas } from "./tiposEntradas";
type EntradaParagrafo = PadroesEntradas["paragrafo"];
export default defineComponent({
name: "EliEntradaParagrafo",
components: { VTextarea },
inheritAttrs: false,
props: {
value: {
type: [String, null] as unknown as PropType<EntradaParagrafo["value"]>,
default: undefined,
},
opcoes: {
type: Object as PropType<EntradaParagrafo["opcoes"]>,
required: true,
},
},
emits: {
"update:value": (_v: EntradaParagrafo["value"]) => true,
input: (_v: EntradaParagrafo["value"]) => true,
change: (_v: EntradaParagrafo["value"]) => true,
focus: () => true,
blur: () => true,
},
setup(props, { attrs, emit }) {
const localValue = computed<EntradaParagrafo["value"]>({
get: () => props.value,
set: (v) => {
emit("update:value", v);
emit("input", v);
emit("change", v);
},
});
return { attrs, emit, localValue, opcoes: props.opcoes };
},
});
</script>
<style scoped></style>

View file

@ -0,0 +1,93 @@
<template>
<v-select
v-model="localValue"
:label="opcoes?.rotulo"
:placeholder="opcoes?.placeholder"
:items="itens"
item-title="rotulo"
item-value="chave"
:loading="carregando"
:disabled="carregando"
:clearable="Boolean(opcoes?.limpavel)"
:error="Boolean(opcoes?.erro)"
:error-messages="opcoes?.mensagensErro"
:hint="opcoes?.dica"
:persistent-hint="Boolean(opcoes?.dicaPersistente)"
:density="opcoes?.densidade ?? 'comfortable'"
:variant="opcoes?.variante ?? 'outlined'"
v-bind="attrs"
@focus="() => emit('focus')"
@blur="() => emit('blur')"
/>
</template>
<script lang="ts">
import { computed, defineComponent, onMounted, PropType, ref, watch } from "vue";
import { VSelect } from "vuetify/components";
import type { PadroesEntradas } from "./tiposEntradas";
type EntradaSelecao = PadroesEntradas["selecao"];
type ItemSelecao = { chave: string; rotulo: string };
export default defineComponent({
name: "EliEntradaSelecao",
components: { VSelect },
inheritAttrs: false,
props: {
value: {
type: [String, null] as unknown as PropType<EntradaSelecao["value"]>,
default: undefined,
},
opcoes: {
type: Object as PropType<EntradaSelecao["opcoes"]>,
required: true,
},
},
emits: {
"update:value": (_v: EntradaSelecao["value"]) => true,
input: (_v: EntradaSelecao["value"]) => true,
change: (_v: EntradaSelecao["value"]) => true,
focus: () => true,
blur: () => true,
},
setup(props, { attrs, emit }) {
const itens = ref<ItemSelecao[]>([]);
const carregando = ref(false);
const localValue = computed<EntradaSelecao["value"]>({
get: () => props.value,
set: (v) => {
emit("update:value", v);
emit("input", v);
emit("change", v);
},
});
async function carregarItens() {
carregando.value = true;
try {
const resultado = await props.opcoes.itens();
itens.value = Array.isArray(resultado) ? resultado : [];
} finally {
carregando.value = false;
}
}
// Recarrega quando muda a função (caso o consumidor troque dinamicamente).
watch(
() => props.opcoes.itens,
() => {
void carregarItens();
}
);
onMounted(() => {
void carregarItens();
});
return { attrs, emit, localValue, opcoes: props.opcoes, itens, carregando };
},
});
</script>
<style scoped></style>

View file

@ -121,6 +121,84 @@ Exemplo:
/>
```
---
#### 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?: number`
- `limpavel?: boolean`
- `erro?: boolean`
- `mensagensErro?: string | string[]`
- `dica?: string`
- `dicaPersistente?: boolean`
- `densidade?: CampoDensidade`
- `variante?: CampoVariante`
Exemplo:
```vue
<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?: boolean`
- `erro?: boolean`
- `mensagensErro?: string | string[]`
- `dica?: string`
- `dicaPersistente?: boolean`
- `densidade?: CampoDensidade`
- `variante?: CampoVariante`
Comportamento:
- Ao montar, o componente chama `opcoes.itens()`.
- Enquanto carrega, o select fica em `loading` e desabilitado.
Exemplo:
```vue
<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):

View file

@ -1,6 +1,8 @@
import EliEntradaTexto from "./EliEntradaTexto.vue";
import EliEntradaNumero from "./EliEntradaNumero.vue";
import EliEntradaDataHora from "./EliEntradaDataHora.vue";
import EliEntradaParagrafo from "./EliEntradaParagrafo.vue";
import EliEntradaSelecao from "./EliEntradaSelecao.vue";
export { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora };
export { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora, EliEntradaParagrafo, EliEntradaSelecao };
export type { PadroesEntradas, TipoEntrada } from "./tiposEntradas";

View file

@ -3,6 +3,8 @@ import type { Component } from "vue";
import EliEntradaTexto from "./EliEntradaTexto.vue";
import EliEntradaNumero from "./EliEntradaNumero.vue";
import EliEntradaDataHora from "./EliEntradaDataHora.vue";
import EliEntradaParagrafo from "./EliEntradaParagrafo.vue";
import EliEntradaSelecao from "./EliEntradaSelecao.vue";
import type { TipoEntrada } from "./tiposEntradas";
@ -10,4 +12,6 @@ export const registryTabelaCelulas = {
texto: EliEntradaTexto,
numero: EliEntradaNumero,
dataHora: EliEntradaDataHora,
paragrafo: EliEntradaParagrafo,
selecao: EliEntradaSelecao,
} as const satisfies Record<TipoEntrada, Component>;

View file

@ -113,6 +113,72 @@ export type PadroesEntradas = {
variante?: import("../../tipos").CampoVariante
}
>
paragrafo: tipoPadraoEntrada<
string | null | undefined,
{
/** Quantidade de linhas visíveis no textarea (Vuetify `rows`). */
linhas?: number
/** Limite máximo de caracteres permitidos (se definido). */
limiteCaracteres?: number
/** Se true, mostra ícone para limpar o valor (Vuetify clearable). */
limpavel?: boolean
/** Estado de erro (visual). */
erro?: boolean
/** Mensagens de erro. */
mensagensErro?: string | string[]
/** Texto de apoio. */
dica?: string
/** Mantém a dica sempre visível. */
dicaPersistente?: boolean
/** Densidade do campo (Vuetify). */
densidade?: import("../../tipos").CampoDensidade
/** Variante do v-text-field (Vuetify). */
variante?: import("../../tipos").CampoVariante
}
>
selecao: tipoPadraoEntrada<
string | null | undefined,
{
/**
* Carrega os itens da seleção (sincrono ou async).
* - Cada item precisa ter uma chave estável (value) e um rótulo (title).
*/
itens: () =>
| { chave: string; rotulo: string }[]
| Promise<{ chave: string; rotulo: string }[]>
/** Se true, mostra ícone para limpar o valor (Vuetify clearable). */
limpavel?: boolean
/** Estado de erro (visual). */
erro?: boolean
/** Mensagens de erro. */
mensagensErro?: string | string[]
/** Texto de apoio. */
dica?: string
/** Mantém a dica sempre visível. */
dicaPersistente?: boolean
/** Densidade do campo (Vuetify). */
densidade?: import("../../tipos").CampoDensidade
/** Variante do v-text-field (Vuetify). */
variante?: import("../../tipos").CampoVariante
}
>
}
/**

View file

@ -0,0 +1,78 @@
<template>
<button
v-if="dados?.acao"
type="button"
class="eli-tabela__celula-link"
@click.stop.prevent="dados.acao()"
>
{{ textoData }}
</button>
<span v-else>{{ textoData }}</span>
</template>
<script lang="ts">
import { computed, defineComponent, PropType } from "vue";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import type { TiposTabelaCelulas } from "./tiposTabelaCelulas";
// Necessário para `fromNow()`.
dayjs.extend(relativeTime);
export default defineComponent({
name: "EliTabelaCelulaData",
props: {
dados: {
type: Object as PropType<TiposTabelaCelulas["data"]>,
required: false,
},
},
setup({ dados }) {
const textoData = computed(() => {
const valorIso = dados?.valor;
if (!valorIso) return "";
const formato = dados?.formato ?? "data";
if (formato === "relativo") {
return dayjs(valorIso).fromNow();
}
if (formato === "data_hora") {
// Padrão pt-BR simples (sem depender de locale do dayjs)
return dayjs(valorIso).format("DD/MM/YYYY HH:mm");
}
// formato === "data"
return dayjs(valorIso).format("DD/MM/YYYY");
});
return { dados, textoData };
},
});
</script>
<style scoped>
.eli-tabela__celula-link {
all: unset;
display: inline;
color: #2563eb;
cursor: pointer;
text-decoration: underline;
text-decoration-color: rgba(37, 99, 235, 0.55);
text-underline-offset: 2px;
}
.eli-tabela__celula-link:hover {
color: #1d4ed8;
text-decoration-color: rgba(29, 78, 216, 0.75);
}
.eli-tabela__celula-link:focus-visible {
outline: 2px solid rgba(37, 99, 235, 0.45);
outline-offset: 2px;
border-radius: 4px;
}
</style>

View file

@ -5,13 +5,13 @@
class="eli-tabela__celula-link"
@click.stop.prevent="dados.acao()"
>
{{ String(dados?.numero).replace('.', ',') }}
{{ textoNumero }}
</button>
<span v-else>{{ String(dados?.numero).replace('.', ',') }}</span>
<span v-else>{{ textoNumero }}</span>
</template>
<script lang="ts">
import { defineComponent, PropType } from "vue"
import { computed, defineComponent, PropType } from "vue"
import type { TiposTabelaCelulas } from "./tiposTabelaCelulas";
export default defineComponent({
@ -21,16 +21,21 @@ export default defineComponent({
dados: {
type: Object as PropType<TiposTabelaCelulas["numero"]>,
},
},
data() {
return {
}
},
methods: {
},
setup({ dados }) {
return { dados }
const textoNumero = computed(() => {
// Mantemos o comportamento anterior (trocar "." por ","), mas agora suportamos prefixo/sufixo.
const numero = String(dados?.numero).replace(".", ",");
const prefixo = dados?.prefixo?.trim();
const sufixo = dados?.sufixo?.trim();
const inicio = prefixo ? `${prefixo} ` : "";
const fim = sufixo ? ` ${sufixo}` : "";
return `${inicio}${numero}${fim}`;
});
return { dados, textoNumero }
},
})
</script>

View file

@ -0,0 +1,61 @@
<template>
<div class="eli-tabela__celula-tags">
<v-chip
v-for="(tag, idx) in dados?.opcoes ?? []"
:key="idx"
class="eli-tabela__celula-tag"
size="small"
variant="tonal"
:color="tag.cor"
:clickable="Boolean(tag.acao)"
@click.stop.prevent="tag.acao?.()"
>
<component
:is="tag.icone"
v-if="tag.icone"
class="eli-tabela__celula-tag-icone"
:size="14"
/>
<span>{{ tag.rotulo }}</span>
</v-chip>
</div>
</template>
<script lang="ts">
import { defineComponent, PropType } from "vue";
import { VChip } from "vuetify/components";
import type { TiposTabelaCelulas } from "./tiposTabelaCelulas";
export default defineComponent({
name: "EliTabelaCelulaTags",
components: { VChip },
props: {
dados: {
type: Object as PropType<TiposTabelaCelulas["tags"]>,
required: false,
},
},
setup({ dados }) {
return { dados };
},
});
</script>
<style scoped>
.eli-tabela__celula-tags {
display: flex;
flex-wrap: wrap;
gap: 6px;
align-items: center;
}
.eli-tabela__celula-tag {
cursor: default;
}
.eli-tabela__celula-tag-icone {
margin-right: 6px;
}
</style>

View file

@ -0,0 +1,81 @@
# Células da EliTabela
Este diretório contém os componentes de **célula** usados pela `EliTabela`.
## Como funcionam as células
A `EliTabela` não renderiza o conteúdo direto: cada coluna retorna uma tupla tipada via helper:
```ts
import { celulaTabela } from "@/componentes/EliTabela";
celula: (linha) => celulaTabela("textoSimples", { texto: linha.nome })
```
O `tipo` seleciona qual componente de célula será usado (via registry) e o `dados` define o payload tipado.
---
## Tipos disponíveis
### 1) `textoSimples`
```ts
{ texto: string; acao?: () => void }
```
### 2) `textoTruncado`
```ts
{ texto: string; acao?: () => void }
```
### 3) `numero`
```ts
{ numero: number; prefixo?: string; sufixo?: string; acao?: () => void }
```
Exemplos:
```ts
// moeda
celula: (l) => celulaTabela("numero", { numero: l.total, prefixo: "R$" })
// unidade de medida
celula: (l) => celulaTabela("numero", { numero: l.peso, sufixo: "kg" })
```
### 4) `tags`
```ts
{
opcoes: {
rotulo: string;
cor?: string;
icone?: import("lucide-vue-next").LucideIcon;
acao?: () => void;
}[]
}
```
### 5) `data`
```ts
{ valor: string; formato: "data" | "data_hora" | "relativo"; acao?: () => void }
```
Exemplos:
```ts
celula: (l) => celulaTabela("data", { valor: l.criado_em, formato: "data" })
celula: (l) => celulaTabela("data", { valor: l.criado_em, formato: "data_hora" })
celula: (l) => celulaTabela("data", { valor: l.atualizado_em, formato: "relativo" })
```
---
## Onde ficam os tipos e o registry
- Tipos: `src/componentes/EliTabela/celulas/tiposTabelaCelulas.ts`
- Registry: `src/componentes/EliTabela/celulas/registryTabelaCelulas.ts`

View file

@ -3,10 +3,14 @@ import type { Component } from "vue";
import EliTabelaCelulaTextoSimples from "./EliTabelaCelulaTextoSimples.vue";
import EliTabelaCelulaTextoTruncado from "./EliTabelaCelulaTextoTruncado.vue";
import EliTabelaCelulaNumero from "./EliTabelaCelulaNumero.vue";
import EliTabelaCelulaTags from "./EliTabelaCelulaTags.vue";
import EliTabelaCelulaData from "./EliTabelaCelulaData.vue";
import type { TipoTabelaCelula } from "./tiposTabelaCelulas";
export const registryTabelaCelulas = {
textoSimples: EliTabelaCelulaTextoSimples,
textoTruncado: EliTabelaCelulaTextoTruncado,
numero: EliTabelaCelulaNumero,
tags: EliTabelaCelulaTags,
data: EliTabelaCelulaData,
} as const satisfies Record<TipoTabelaCelula, Component>;

View file

@ -2,6 +2,8 @@
* Tipagem dos dados de entrada dos componentes de celulas
*/
import type { LucideIcon } from "lucide-vue-next";
export type TiposTabelaCelulas = {
textoSimples: {
texto: string;
@ -13,6 +15,32 @@ export type TiposTabelaCelulas = {
};
numero: {
numero: number;
/** Texto opcional exibido antes do número (ex.: "R$", "≈"). */
prefixo?: string;
/** Texto opcional exibido depois do número (ex.: "kg", "%"). */
sufixo?: string;
acao?: () => void;
};
tags: {
opcoes: {
/** Texto exibido dentro da tag. */
rotulo: string;
/** Cor do chip (segue as cores do Vuetify, ex.: "primary", "success", "error"). */
cor?: string;
/** Ícone (Lucide) opcional exibido antes do rótulo. */
icone?: LucideIcon;
/** Ação opcional da tag. Quando existir, o chip vira clicável. */
acao?: () => void;
}[];
};
data: {
/** Valor em ISO 8601 (ex.: "2026-01-09T16:15:00Z"). */
valor: string;
/** Define o formato de exibição. */
formato: "data" | "data_hora" | "relativo";
/** Ação opcional ao clicar no valor. */
acao?: () => void;
};
};

View file

@ -5,14 +5,20 @@ import { EliBotao } from "./componentes/botao";
import { EliBadge } from "./componentes/indicador";
import { EliCartao } from "./componentes/cartao";
import { EliTabela } from "./componentes/EliTabela";
import { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora } from "./componentes/EliEntrada";
import {
EliEntradaTexto,
EliEntradaNumero,
EliEntradaDataHora,
EliEntradaParagrafo,
EliEntradaSelecao,
} from "./componentes/EliEntrada";
export { EliOlaMundo };
export { EliBotao };
export { EliBadge };
export { EliCartao };
export { EliTabela };
export { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora };
export { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora, EliEntradaParagrafo, EliEntradaSelecao };
const EliVue: Plugin = {
install(app: App) {
@ -24,6 +30,8 @@ const EliVue: Plugin = {
app.component("EliEntradaTexto", EliEntradaTexto);
app.component("EliEntradaNumero", EliEntradaNumero);
app.component("EliEntradaDataHora", EliEntradaDataHora);
app.component("EliEntradaParagrafo", EliEntradaParagrafo);
app.component("EliEntradaSelecao", EliEntradaSelecao);
},
};

View file

@ -64,22 +64,81 @@
<strong>v-model:value</strong>: {{ numeroDecimal ?? "(null)" }}
</div>
</section>
<v-divider />
<section class="d-flex flex-column ga-3">
<h3 class="text-subtitle-1">Parágrafo</h3>
<EliEntradaParagrafo
v-model:value="paragrafo"
:opcoes="{
rotulo: 'Descrição',
placeholder: 'Digite uma descrição mais longa...',
linhas: 5,
limiteCaracteres: 300,
limpavel: true,
}"
/>
<div class="text-caption">
<strong>v-model:value</strong>: {{ paragrafo ?? "(null)" }}
</div>
</section>
<v-divider />
<section class="d-flex flex-column ga-3">
<h3 class="text-subtitle-1">Seleção</h3>
<EliEntradaSelecao
v-model:value="selecao"
:opcoes="{
rotulo: 'Categoria',
placeholder: 'Selecione...',
limpavel: true,
// OBS: não usar `new Promise(...)` direto no template.
// O template do Vue resolve identificadores via `_ctx`, então `Promise`
// pode ser tratado como variável do componente.
itens: itensCategorias,
}"
/>
<div class="text-caption">
<strong>v-model:value</strong>: {{ selecao ?? "(null)" }}
</div>
</section>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { EliEntradaNumero, EliEntradaTexto } from "../index";
import { EliEntradaNumero, EliEntradaParagrafo, EliEntradaSelecao, EliEntradaTexto } from "../index";
export default defineComponent({
name: "EntradasPlayground",
components: {
EliEntradaTexto,
EliEntradaNumero,
EliEntradaParagrafo,
EliEntradaSelecao,
},
methods: {
async itensCategorias() {
// Exemplo async (simula consulta)
await new Promise((r) => setTimeout(r, 600));
return [
{ chave: "a", rotulo: "Categoria A" },
{ chave: "b", rotulo: "Categoria B" },
{ chave: "c", rotulo: "Categoria C" },
];
},
},
data() {
return {
texto: null as string | null,
paragrafo: null as string | null,
selecao: null as string | null,
numero: null as number | null,
numeroDecimal: null as number | null,
};

View file

@ -14,7 +14,7 @@
<script lang="ts">
import { defineComponent, ref } from "vue";
import { codigosResposta } from "p-respostas";
import { Eye, Plus, Trash2 } from "lucide-vue-next";
import { BadgeCheck, Eye, Pencil, Plus, Trash2 } from "lucide-vue-next";
import { celulaTabela, EliTabela } from "@/componentes/EliTabela";
import type { ComponenteEntrada } from "@/componentes/EliEntrada/tiposEntradas";
import type { EliTabelaConsulta } from "@/componentes/EliTabela";
@ -25,6 +25,10 @@ type Linha = {
documento: string;
email: string;
telefone: string;
faturamento: number;
peso_kg: number;
criado_em: string;
atualizado_em: string;
};
export default defineComponent({
@ -58,6 +62,10 @@ export default defineComponent({
documento: "12.345.678/0001-90",
email: "contato.comercial.super.longo@doces-da-maria-exemplo-muito-grande.com.br",
telefone: "(11) 91234-5678",
faturamento: 12500.5,
peso_kg: 12.4,
criado_em: "2026-01-09T16:15:00Z",
atualizado_em: "2026-01-29T15:30:00-03:00",
},
{
empreendedor: "João Pereira",
@ -65,6 +73,10 @@ export default defineComponent({
documento: "98.765.432/0001-12",
email: "contato@cafeperegrino.com",
telefone: "(11) 93456-7810",
faturamento: 8000,
peso_kg: 6.2,
criado_em: "2026-01-02T10:00:00-03:00",
atualizado_em: "2026-01-20T08:10:00-03:00",
},
{
empreendedor: "Ana Costa",
@ -72,6 +84,10 @@ export default defineComponent({
documento: "45.678.912/0001-55",
email: "ana@flordesal.com",
telefone: "(21) 99876-5432",
faturamento: 3200.75,
peso_kg: 4.8,
criado_em: "2025-12-10T09:30:00-03:00",
atualizado_em: "2026-01-15T19:20:00-03:00",
},
{
empreendedor: "Rafael Lima",
@ -79,6 +95,10 @@ export default defineComponent({
documento: "07.654.321/0001-00",
email: "rafael@techagro.com",
telefone: "(31) 94567-8899",
faturamento: 15999.9,
peso_kg: 9.1,
criado_em: "2026-01-12T12:00:00-03:00",
atualizado_em: "2026-01-28T11:00:00-03:00",
},
{
empreendedor: "Juliana Torres",
@ -86,6 +106,10 @@ export default defineComponent({
documento: "33.210.987/0001-44",
email: "juliana@torresmoda.com",
telefone: "(71) 97766-5544",
faturamento: 4500,
peso_kg: 3.3,
criado_em: "2026-01-01T00:00:00Z",
atualizado_em: "2026-01-10T13:45:00-03:00",
},
{
empreendedor: "Marcos Vieira",
@ -93,6 +117,10 @@ export default defineComponent({
documento: "21.109.876/0001-32",
email: "marcos@paoquentinho.com",
telefone: "(48) 99654-3210",
faturamento: 2200.4,
peso_kg: 15.7,
criado_em: "2026-01-05T07:25:00-03:00",
atualizado_em: "2026-01-23T20:15:00-03:00",
},
{
empreendedor: "Bianca Rocha",
@ -100,6 +128,10 @@ export default defineComponent({
documento: "54.321.098/0001-21",
email: "contato@belezaemcasa.com",
telefone: "(85) 98877-1122",
faturamento: 990,
peso_kg: 1.9,
criado_em: "2026-01-03T14:00:00-03:00",
atualizado_em: "2026-01-29T09:00:00-03:00",
},
{
empreendedor: "Caio Albuquerque",
@ -107,6 +139,10 @@ export default defineComponent({
documento: "65.432.109/0001-09",
email: "caio@engenhariaverde.com",
telefone: "(61) 98123-4567",
faturamento: 100000,
peso_kg: 21.3,
criado_em: "2025-11-18T16:10:00-03:00",
atualizado_em: "2026-01-25T10:40:00-03:00",
},
{
empreendedor: "Fernanda Almeida",
@ -114,6 +150,10 @@ export default defineComponent({
documento: "87.654.210/0001-98",
email: "fernanda@fazbem.com",
telefone: "(41) 99777-6655",
faturamento: 5600.2,
peso_kg: 8.6,
criado_em: "2026-01-08T12:12:00-03:00",
atualizado_em: "2026-01-21T17:55:00-03:00",
},
{
empreendedor: "Gabriel Martins",
@ -121,6 +161,10 @@ export default defineComponent({
documento: "19.876.543/0001-76",
email: "suporte@martinstech.com",
telefone: "(19) 98888-9090",
faturamento: 7550,
peso_kg: 7.7,
criado_em: "2026-01-11T11:00:00-03:00",
atualizado_em: "2026-01-18T11:30:00-03:00",
},
{
empreendedor: "Helena Duarte",
@ -128,6 +172,10 @@ export default defineComponent({
documento: "23.456.789/0001-65",
email: "helena@costuracriativa.com",
telefone: "(51) 98765-4433",
faturamento: 2700,
peso_kg: 2.5,
criado_em: "2026-01-07T08:00:00-03:00",
atualizado_em: "2026-01-16T14:10:00-03:00",
},
{
empreendedor: "Igor Santos",
@ -135,6 +183,10 @@ export default defineComponent({
documento: "43.219.876/0001-54",
email: "igor@santosconsultoria.com",
telefone: "(31) 99332-1100",
faturamento: 12000,
peso_kg: 5.4,
criado_em: "2026-01-06T10:30:00-03:00",
atualizado_em: "2026-01-22T18:30:00-03:00",
},
{
empreendedor: "Jéssica Nunes",
@ -142,6 +194,10 @@ export default defineComponent({
documento: "09.876.543/0001-33",
email: "jessica@nunesdecora.com",
telefone: "(62) 99922-3344",
faturamento: 3300.1,
peso_kg: 4.1,
criado_em: "2026-01-04T13:30:00-03:00",
atualizado_em: "2026-01-26T09:20:00-03:00",
},
{
empreendedor: "Leonardo Prado",
@ -149,6 +205,10 @@ export default defineComponent({
documento: "72.345.098/0001-27",
email: "contato@pradobike.com",
telefone: "(47) 98444-6677",
faturamento: 4100,
peso_kg: 6.8,
criado_em: "2026-01-02T18:40:00-03:00",
atualizado_em: "2026-01-27T12:00:00-03:00",
},
{
empreendedor: "Marina Lopes",
@ -156,6 +216,10 @@ export default defineComponent({
documento: "56.789.012/0001-11",
email: "marina@lopesdesign.com",
telefone: "(27) 99911-2233",
faturamento: 2100,
peso_kg: 3.7,
criado_em: "2026-01-09T09:00:00-03:00",
atualizado_em: "2026-01-19T15:35:00-03:00",
},
{
empreendedor: "Nicolas Teixeira",
@ -163,6 +227,10 @@ export default defineComponent({
documento: "34.567.890/0001-02",
email: "nicolas@qualivida.com",
telefone: "(92) 99456-7788",
faturamento: 8600.9,
peso_kg: 11.2,
criado_em: "2026-01-12T19:15:00-03:00",
atualizado_em: "2026-01-29T10:50:00-03:00",
},
{
empreendedor: "Olívia Azevedo",
@ -170,6 +238,10 @@ export default defineComponent({
documento: "88.901.234/0001-45",
email: "olivia@petcare.com",
telefone: "(16) 99788-6655",
faturamento: 1900.3,
peso_kg: 2.2,
criado_em: "2026-01-10T15:00:00-03:00",
atualizado_em: "2026-01-14T16:00:00-03:00",
},
{
empreendedor: "Paulo Henrique",
@ -177,6 +249,10 @@ export default defineComponent({
documento: "44.556.778/0001-90",
email: "paulo@solucoeseletricas.com",
telefone: "(13) 98810-2020",
faturamento: 50000,
peso_kg: 17.9,
criado_em: "2026-01-13T10:10:00-03:00",
atualizado_em: "2026-01-24T21:00:00-03:00",
},
{
empreendedor: "Renata Souza",
@ -184,6 +260,10 @@ export default defineComponent({
documento: "11.223.344/0001-08",
email: "renata@souzatraducoes.com",
telefone: "(24) 99661-7788",
faturamento: 6400,
peso_kg: 9.9,
criado_em: "2026-01-08T07:00:00-03:00",
atualizado_em: "2026-01-28T09:05:00-03:00",
},
{
empreendedor: "Tiago Moura",
@ -191,6 +271,10 @@ export default defineComponent({
documento: "78.912.345/0001-67",
email: "tiago@mouraagro.com",
telefone: "(68) 99999-4545",
faturamento: 7200,
peso_kg: 13.5,
criado_em: "2026-01-03T12:00:00-03:00",
atualizado_em: "2026-01-23T12:45:00-03:00",
},
{
empreendedor: "Viviane Castro",
@ -198,6 +282,10 @@ export default defineComponent({
documento: "32.165.498/0001-87",
email: "viviane@castroarte.com",
telefone: "(81) 98787-1212",
faturamento: 2800,
peso_kg: 4.6,
criado_em: "2026-01-01T09:00:00-03:00",
atualizado_em: "2026-01-17T09:30:00-03:00",
},
]);
@ -214,6 +302,10 @@ export default defineComponent({
documento: "00.000.000/0000-00",
email: `novo${proximo}@exemplo.com`,
telefone: "(00) 90000-0000",
faturamento: 0,
peso_kg: 0,
criado_em: new Date().toISOString(),
atualizado_em: new Date().toISOString(),
});
versaoTabelaOk.value++;
@ -307,6 +399,67 @@ export default defineComponent({
coluna_ordem: "telefone",
visivel: true,
},
{
rotulo: "Faturamento",
celula: (l) =>
celulaTabela("numero", {
numero: l.faturamento,
prefixo: "R$",
// Exemplo de ação (clicável)
acao: () => alert(`Faturamento de ${l.empreendedor}: R$ ${l.faturamento}`),
}),
visivel: true,
},
{
rotulo: "Peso",
celula: (l) =>
celulaTabela("numero", {
numero: l.peso_kg,
sufixo: "kg",
}),
visivel: false,
},
{
rotulo: "Status",
celula: (l) =>
celulaTabela("tags", {
opcoes: [
{
rotulo: "Ativo",
cor: "success",
icone: BadgeCheck,
},
{
rotulo: "Editar",
cor: "primary",
icone: Pencil,
acao: () => {
alert(`Editar ${l.empreendedor}`);
},
},
],
}),
visivel: true,
},
{
rotulo: "Criado em",
celula: (l) =>
celulaTabela("data", {
valor: l.criado_em,
formato: "data",
}),
visivel: false,
},
{
rotulo: "Atualizado",
celula: (l) =>
celulaTabela("data", {
valor: l.atualizado_em,
formato: "relativo",
acao: () => alert(`Atualizado em: ${l.atualizado_em}`),
}),
visivel: true,
},
],
acoesLinha: acoesLinha,
filtroAvancado: [