Compare commits
No commits in common. "8c5a31ef30bf9fcce58864b052b8b28863536b0f" and "5c587c92322993f517ff2ddb935f1af9033fbac1" have entirely different histories.
8c5a31ef30
...
5c587c9232
108 changed files with 3431 additions and 6000 deletions
39
.agent
39
.agent
|
|
@ -40,27 +40,6 @@ Construir um Design System de componentes em **Vue 3** para reutilização em m
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Convenção atual de entradas (IMPORTANTE)
|
|
||||||
|
|
||||||
O componente **`EliInput` foi removido**. O padrão atual é a família **`EliEntrada*`**:
|
|
||||||
|
|
||||||
- `EliEntradaTexto`
|
|
||||||
- `EliEntradaNumero`
|
|
||||||
- `EliEntradaDataHora`
|
|
||||||
|
|
||||||
E o contrato padrão para entradas é:
|
|
||||||
- prop `value`
|
|
||||||
- evento `update:value`
|
|
||||||
- prop obrigatória `opcoes` (contém `rotulo` e outras opções)
|
|
||||||
|
|
||||||
Exemplo:
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<EliEntradaTexto v-model:value="nome" :opcoes="{ rotulo: 'Nome' }" />
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Estrutura obrigatória do repositório
|
## Estrutura obrigatória do repositório
|
||||||
- Cada componente deve possuir **sua própria pasta** em `src/componentes/`
|
- Cada componente deve possuir **sua própria pasta** em `src/componentes/`
|
||||||
- Dentro de cada pasta do componente:
|
- Dentro de cada pasta do componente:
|
||||||
|
|
@ -183,24 +162,6 @@ Evitar comentários óbvios (“isso é um botão”).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Convenção atual de EliTabela (IMPORTANTE)
|
|
||||||
|
|
||||||
### Filtro avançado
|
|
||||||
|
|
||||||
O filtro avançado da `EliTabela` é configurado via `tabela.filtroAvancado`.
|
|
||||||
|
|
||||||
Regras:
|
|
||||||
- O **operador é travado na definição** (o usuário não escolhe operador)
|
|
||||||
- Cada filtro pode ser usado **no máximo 1 vez**
|
|
||||||
- UI: modal mostra **apenas os componentes de entrada** definidos no filtro
|
|
||||||
- Persistência: salva em `localStorage` apenas `{ coluna, valor }[]` por `tabela.nome`
|
|
||||||
|
|
||||||
Se você for evoluir isso para backend:
|
|
||||||
- usar `parametrosConsulta.filtros` (`tipoFiltro[]`) no `tabela.consulta`
|
|
||||||
- manter compatibilidade com simulação local (quando necessário)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Publicação do pacote (npm)
|
## Publicação do pacote (npm)
|
||||||
|
|
||||||
### Regra de publicação (sem usar `package.json.files`)
|
### Regra de publicação (sem usar `package.json.files`)
|
||||||
|
|
|
||||||
114
IA.md
114
IA.md
|
|
@ -61,15 +61,7 @@ createApp(App)
|
||||||
### 2) Importação direta (quando não quiser plugin)
|
### 2) Importação direta (quando não quiser plugin)
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import {
|
import { EliBotao, EliInput, EliBadge, EliCartao, EliDataHora } from "eli-vue";
|
||||||
EliBotao,
|
|
||||||
EliBadge,
|
|
||||||
EliCartao,
|
|
||||||
EliTabela,
|
|
||||||
EliEntradaTexto,
|
|
||||||
EliEntradaNumero,
|
|
||||||
EliEntradaDataHora,
|
|
||||||
} from "eli-vue";
|
|
||||||
```
|
```
|
||||||
|
|
||||||
> Observação: ainda pode ser necessário importar o CSS do pacote:
|
> Observação: ainda pode ser necessário importar o CSS do pacote:
|
||||||
|
|
@ -90,18 +82,11 @@ import "eli-vue/dist/eli-vue.css";
|
||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Entradas (EliEntrada*) com v-model
|
### Input com v-model
|
||||||
|
|
||||||
O `eli-vue` usa uma família de componentes `EliEntrada*` (em vez do antigo `EliInput`).
|
|
||||||
|
|
||||||
#### Texto
|
|
||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<EliEntradaTexto
|
<EliInput v-model="nome" label="Nome" placeholder="Digite seu nome" />
|
||||||
v-model:value="nome"
|
|
||||||
:opcoes="{ rotulo: 'Nome', placeholder: 'Digite seu nome' }"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
@ -109,37 +94,33 @@ import { defineComponent, ref } from "vue";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup() {
|
setup() {
|
||||||
const nome = ref<string | null>("");
|
const nome = ref("");
|
||||||
return { nome };
|
function salvar() {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
return { nome, salvar };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Texto com formato/máscara
|
### Input de porcentagem
|
||||||
|
|
||||||
> Regra importante: o `value` emitido é **sempre o texto formatado** (igual ao que aparece no input).
|
Quando precisar de um campo numérico com sufixo `%`, use `type="porcentagem"`.
|
||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<EliEntradaTexto
|
<EliInput v-model="taxa" type="porcentagem" label="Taxa" placeholder="0,00" />
|
||||||
v-model:value="documento"
|
|
||||||
:opcoes="{ rotulo: 'CPF/CNPJ', formato: 'cpfCnpj' }"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<EliEntradaTexto
|
|
||||||
v-model:value="telefone"
|
|
||||||
:opcoes="{ rotulo: 'Telefone', formato: 'telefone' }"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, ref } from "vue";
|
import { defineComponent, ref } from "vue";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup() {
|
setup() {
|
||||||
const documento = ref<string | null>("");
|
const taxa = ref("");
|
||||||
const telefone = ref<string | null>("");
|
return { taxa };
|
||||||
return { documento, telefone };
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -150,10 +131,10 @@ export default defineComponent({
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<!-- Valor chega do backend em ISO 8601 (UTC/offset), e o componente exibe em horário local -->
|
<!-- 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' }" />
|
<EliDataHora v-model="dataHora" rotulo="Agendamento" />
|
||||||
|
|
||||||
<!-- Somente data -->
|
<!-- Somente data -->
|
||||||
<EliEntradaDataHora v-model:value="data" :opcoes="{ rotulo: 'Nascimento', modo: 'data' }" />
|
<EliDataHora v-model="data" modo="data" rotulo="Nascimento" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
@ -171,67 +152,6 @@ export default defineComponent({
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 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: [] },
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
> Observação: em modo simulação/local, a tabela pode buscar uma lista completa e aplicar filtro/paginação localmente.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Troubleshooting (para IAs)
|
## Troubleshooting (para IAs)
|
||||||
|
|
||||||
### 1) “Failed to resolve component”
|
### 1) “Failed to resolve component”
|
||||||
|
|
|
||||||
75
README.md
75
README.md
|
|
@ -35,26 +35,21 @@ src/
|
||||||
EliBotao.vue
|
EliBotao.vue
|
||||||
index.ts
|
index.ts
|
||||||
README.md
|
README.md
|
||||||
cartao/
|
campo/
|
||||||
EliCartao.vue
|
EliInput.vue
|
||||||
index.ts
|
index.ts
|
||||||
README.md
|
README.md
|
||||||
indicador/
|
indicador/
|
||||||
EliBadge.vue
|
EliBadge.vue
|
||||||
index.ts
|
index.ts
|
||||||
README.md
|
README.md
|
||||||
EliEntrada/
|
data_hora/
|
||||||
EliEntradaTexto.vue
|
EliDataHora.vue
|
||||||
EliEntradaNumero.vue
|
|
||||||
EliEntradaDataHora.vue
|
|
||||||
index.ts
|
|
||||||
README.md
|
|
||||||
EliTabela/
|
|
||||||
EliTabela.vue
|
|
||||||
index.ts
|
index.ts
|
||||||
README.md
|
README.md
|
||||||
tipos/
|
tipos/
|
||||||
botao.ts
|
botao.ts
|
||||||
|
campo.ts
|
||||||
indicador.ts
|
indicador.ts
|
||||||
index.ts
|
index.ts
|
||||||
playground/
|
playground/
|
||||||
|
|
@ -65,7 +60,7 @@ src/
|
||||||
|
|
||||||
### Convenções (nomenclatura)
|
### Convenções (nomenclatura)
|
||||||
|
|
||||||
- Componentes usam **prefixo `Eli`** (ex.: `EliBotao`, `EliEntradaTexto`).
|
- Componentes usam **prefixo `Eli`** (ex.: `EliBotao`, `EliInput`).
|
||||||
- Pastas preferem **português** (ex.: `src/componentes/botao`, `src/componentes/campo`).
|
- Pastas preferem **português** (ex.: `src/componentes/botao`, `src/componentes/campo`).
|
||||||
- Tipos compartilhados ficam em `src/tipos/`.
|
- Tipos compartilhados ficam em `src/tipos/`.
|
||||||
- Sem TSX; padrão SFC: `<template>` + `<script lang="ts">` + `defineComponent`.
|
- Sem TSX; padrão SFC: `<template>` + `<script lang="ts">` + `defineComponent`.
|
||||||
|
|
@ -133,15 +128,7 @@ createApp(App)
|
||||||
### 2) Importação direta de componentes
|
### 2) Importação direta de componentes
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import {
|
import { EliBotao, EliInput, EliBadge, EliDataHora } from "eli-vue";
|
||||||
EliBotao,
|
|
||||||
EliBadge,
|
|
||||||
EliCartao,
|
|
||||||
EliTabela,
|
|
||||||
EliEntradaTexto,
|
|
||||||
EliEntradaNumero,
|
|
||||||
EliEntradaDataHora,
|
|
||||||
} from "eli-vue";
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Exemplos rápidos de uso
|
## Exemplos rápidos de uso
|
||||||
|
|
@ -154,14 +141,11 @@ import {
|
||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Entradas (EliEntrada*) com v-model
|
### EliInput (v-model)
|
||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<EliEntradaTexto
|
<EliInput v-model="nome" label="Nome" placeholder="Digite seu nome" />
|
||||||
v-model:value="nome"
|
|
||||||
:opcoes="{ rotulo: 'Nome', placeholder: 'Digite seu nome' }"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
@ -169,21 +153,20 @@ import { defineComponent, ref } from "vue";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup() {
|
setup() {
|
||||||
const nome = ref<string | null>("");
|
const nome = ref("");
|
||||||
return { nome };
|
return { nome };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
### EliEntradaNumero (exemplo)
|
### EliInput (porcentagem)
|
||||||
|
|
||||||
|
Use `type="porcentagem"` quando precisar de um campo numérico com sufixo `%` embutido.
|
||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<EliEntradaNumero
|
<EliInput v-model="taxa" type="porcentagem" label="Taxa" placeholder="0,00" />
|
||||||
v-model:value="taxa"
|
|
||||||
:opcoes="{ rotulo: 'Taxa', placeholder: '0,00' }"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
@ -191,7 +174,7 @@ import { defineComponent, ref } from "vue";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup() {
|
setup() {
|
||||||
const taxa = ref<number | null>(null);
|
const taxa = ref("");
|
||||||
return { taxa };
|
return { taxa };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -208,7 +191,7 @@ export default defineComponent({
|
||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
### EliEntradaDataHora
|
### EliDataHora
|
||||||
|
|
||||||
> Entrada/saída sempre em **ISO 8601**.
|
> Entrada/saída sempre em **ISO 8601**.
|
||||||
> - Aceita UTC absoluto (`Z`) ou com offset.
|
> - Aceita UTC absoluto (`Z`) ou com offset.
|
||||||
|
|
@ -216,19 +199,16 @@ export default defineComponent({
|
||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
<EliEntradaDataHora v-model:value="agendamento" :opcoes="{ rotulo: 'Agendamento' }" />
|
<EliDataHora v-model="agendamento" rotulo="Agendamento" />
|
||||||
<EliEntradaDataHora
|
<EliDataHora v-model="nascimento" modo="data" rotulo="Nascimento" />
|
||||||
v-model:value="nascimento"
|
|
||||||
:opcoes="{ rotulo: 'Nascimento', modo: 'data' }"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, ref } from "vue";
|
import { defineComponent, ref } from "vue";
|
||||||
import { EliEntradaDataHora } from "eli-vue";
|
import { EliDataHora } from "eli-vue";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { EliEntradaDataHora },
|
components: { EliDataHora },
|
||||||
setup() {
|
setup() {
|
||||||
const agendamento = ref<string | null>("2026-01-09T16:15:00Z");
|
const agendamento = ref<string | null>("2026-01-09T16:15:00Z");
|
||||||
const nascimento = ref<string | null>("2026-01-09T00:00:00-03:00");
|
const nascimento = ref<string | null>("2026-01-09T00:00:00-03:00");
|
||||||
|
|
@ -273,9 +253,11 @@ Exemplo: um **pipeline** em colunas (estilo Trello/Kanban) com cards de oportuni
|
||||||
<v-container class="py-6">
|
<v-container class="py-6">
|
||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<h2 class="text-h6">Pipeline de Oportunidades</h2>
|
<h2 class="text-h6">Pipeline de Oportunidades</h2>
|
||||||
<EliEntradaTexto
|
<EliInput
|
||||||
v-model:value="filtro"
|
v-model="filtro"
|
||||||
:opcoes="{ rotulo: 'Buscar', placeholder: 'Cliente, proposta, valor...' }"
|
label="Buscar"
|
||||||
|
placeholder="Cliente, proposta, valor..."
|
||||||
|
density="compact"
|
||||||
/>
|
/>
|
||||||
<EliBotao @click="criarOportunidade">Nova oportunidade</EliBotao>
|
<EliBotao @click="criarOportunidade">Nova oportunidade</EliBotao>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -331,7 +313,7 @@ Exemplo: um **pipeline** em colunas (estilo Trello/Kanban) com cards de oportuni
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, ref } from "vue";
|
import { defineComponent, ref } from "vue";
|
||||||
import { EliBadge, EliBotao, EliEntradaTexto } from "eli-vue";
|
import { EliBadge, EliBotao, EliInput } from "eli-vue";
|
||||||
|
|
||||||
type Oportunidade = {
|
type Oportunidade = {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
@ -350,7 +332,7 @@ type Coluna = {
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "PipelineExemplo",
|
name: "PipelineExemplo",
|
||||||
components: { EliBadge, EliBotao, EliEntradaTexto },
|
components: { EliBadge, EliBotao, EliInput },
|
||||||
setup() {
|
setup() {
|
||||||
const filtro = ref("");
|
const filtro = ref("");
|
||||||
|
|
||||||
|
|
@ -485,9 +467,6 @@ pnpm run build
|
||||||
|
|
||||||
Gera `dist/` (artefatos de build) e `dist/types` (declarações `.d.ts`).
|
Gera `dist/` (artefatos de build) e `dist/types` (declarações `.d.ts`).
|
||||||
|
|
||||||
> 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.
|
|
||||||
|
|
||||||
## Guia rápido para IAs (antes de codar)
|
## Guia rápido para IAs (antes de codar)
|
||||||
|
|
||||||
1) **Leia** `.agent` e este README.
|
1) **Leia** `.agent` e este README.
|
||||||
|
|
|
||||||
2
dist/eli-vue.css
vendored
2
dist/eli-vue.css
vendored
File diff suppressed because one or more lines are too long
3279
dist/eli-vue.es.js
vendored
3279
dist/eli-vue.es.js
vendored
File diff suppressed because it is too large
Load diff
38
dist/eli-vue.umd.js
vendored
38
dist/eli-vue.umd.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -1,231 +0,0 @@
|
||||||
import { PropType } from "vue";
|
|
||||||
import type { CampoDensidade, CampoVariante } from "../../tipos";
|
|
||||||
import type { PadroesEntradas } from "./tiposEntradas";
|
|
||||||
type EntradaDataHora = PadroesEntradas["dataHora"];
|
|
||||||
type PropsAntigas = {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
rotulo?: string;
|
|
||||||
placeholder?: string;
|
|
||||||
desabilitado?: boolean;
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
densidade?: CampoDensidade;
|
|
||||||
variante?: CampoVariante;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
};
|
|
||||||
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<EntradaDataHora["value"]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<EntradaDataHora["opcoes"]>;
|
|
||||||
required: false;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
modelValue: {
|
|
||||||
type: PropType<string | null>;
|
|
||||||
default: null;
|
|
||||||
};
|
|
||||||
modo: {
|
|
||||||
type: PropType<PropsAntigas["modo"]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
rotulo: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
placeholder: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
desabilitado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
limpavel: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
erro: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
mensagensErro: {
|
|
||||||
type: PropType<string | string[]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dica: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dicaPersistente: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
densidade: {
|
|
||||||
type: PropType<CampoDensidade>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
variante: {
|
|
||||||
type: PropType<CampoVariante>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
min: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
max: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: {
|
|
||||||
[x: string]: unknown;
|
|
||||||
};
|
|
||||||
valor: import("vue").WritableComputedRef<string, string>;
|
|
||||||
tipoInput: import("vue").ComputedRef<"date" | "datetime-local">;
|
|
||||||
minLocal: import("vue").ComputedRef<string | undefined>;
|
|
||||||
maxLocal: import("vue").ComputedRef<string | undefined>;
|
|
||||||
opcoesEfetivas: import("vue").ComputedRef<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../../tipos").CampoDensidade;
|
|
||||||
variante?: import("../../tipos").CampoVariante;
|
|
||||||
}>;
|
|
||||||
desabilitadoEfetivo: import("vue").ComputedRef<boolean>;
|
|
||||||
emitCompatFocus: () => void;
|
|
||||||
emitCompatBlur: () => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: string | null) => true;
|
|
||||||
input: (_v: string | null) => true;
|
|
||||||
change: (_v: string | null) => true;
|
|
||||||
"update:modelValue": (_v: string | null) => true;
|
|
||||||
alterar: (_v: string | null) => true;
|
|
||||||
foco: () => true;
|
|
||||||
desfoco: () => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<EntradaDataHora["value"]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<EntradaDataHora["opcoes"]>;
|
|
||||||
required: false;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
modelValue: {
|
|
||||||
type: PropType<string | null>;
|
|
||||||
default: null;
|
|
||||||
};
|
|
||||||
modo: {
|
|
||||||
type: PropType<PropsAntigas["modo"]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
rotulo: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
placeholder: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
desabilitado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
limpavel: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
erro: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
mensagensErro: {
|
|
||||||
type: PropType<string | string[]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dica: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dicaPersistente: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
densidade: {
|
|
||||||
type: PropType<CampoDensidade>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
variante: {
|
|
||||||
type: PropType<CampoVariante>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
min: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
max: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
"onUpdate:value"?: ((_v: string | null) => any) | undefined;
|
|
||||||
onInput?: ((_v: string | null) => any) | undefined;
|
|
||||||
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;
|
|
||||||
onFoco?: (() => any) | undefined;
|
|
||||||
onDesfoco?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
modo: "data" | "dataHora" | undefined;
|
|
||||||
limpavel: boolean;
|
|
||||||
erro: boolean;
|
|
||||||
mensagensErro: string | string[];
|
|
||||||
dica: string;
|
|
||||||
dicaPersistente: boolean;
|
|
||||||
min: string | undefined;
|
|
||||||
max: string | undefined;
|
|
||||||
densidade: CampoDensidade;
|
|
||||||
variante: CampoVariante;
|
|
||||||
opcoes: {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../../tipos").CampoDensidade;
|
|
||||||
variante?: import("../../tipos").CampoVariante;
|
|
||||||
};
|
|
||||||
value: string | null | undefined;
|
|
||||||
placeholder: string;
|
|
||||||
rotulo: string;
|
|
||||||
modelValue: string | null;
|
|
||||||
desabilitado: boolean;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
||||||
declare const _default: typeof __VLS_export;
|
|
||||||
export default _default;
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
import { PropType } from "vue";
|
|
||||||
import type { PadroesEntradas } from "./tiposEntradas";
|
|
||||||
type EntradaNumero = PadroesEntradas["numero"];
|
|
||||||
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
/** Interface padrão (EliEntrada): value + opcoes. */
|
|
||||||
value: {
|
|
||||||
type: PropType<EntradaNumero["value"]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<EntradaNumero["opcoes"]>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: {
|
|
||||||
[x: string]: unknown;
|
|
||||||
};
|
|
||||||
emit: ((event: "update:value", _v: number | null | undefined) => void) & ((event: "input", _v: number | null | undefined) => void) & ((event: "change", _v: number | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
|
||||||
displayValue: import("vue").Ref<string, string>;
|
|
||||||
isInteiro: import("vue").ComputedRef<boolean>;
|
|
||||||
onUpdateModelValue: (texto: string) => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: EntradaNumero["value"]) => true;
|
|
||||||
/** Compat Vue2 (v-model padrão: value + input) */
|
|
||||||
input: (_v: EntradaNumero["value"]) => true;
|
|
||||||
change: (_v: EntradaNumero["value"]) => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
/** Interface padrão (EliEntrada): value + opcoes. */
|
|
||||||
value: {
|
|
||||||
type: PropType<EntradaNumero["value"]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<EntradaNumero["opcoes"]>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
"onUpdate:value"?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onInput?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onChange?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
value: number | null | undefined;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
||||||
declare const _default: typeof __VLS_export;
|
|
||||||
export default _default;
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
import { PropType } from "vue";
|
|
||||||
import type { PadroesEntradas } from "./tiposEntradas";
|
|
||||||
type EntradaTexto = PadroesEntradas["texto"];
|
|
||||||
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
/** Interface padrão (EliEntrada): value + opcoes. */
|
|
||||||
value: {
|
|
||||||
type: PropType<EntradaTexto["value"]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<EntradaTexto["opcoes"]>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: {
|
|
||||||
[x: string]: unknown;
|
|
||||||
};
|
|
||||||
emit: ((event: "update:value", _v: string | null | undefined) => void) & ((event: "input", _v: string | null | undefined) => void) & ((event: "change", _v: string | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
|
||||||
localValue: import("vue").WritableComputedRef<string | null | undefined, string | null | undefined>;
|
|
||||||
inputHtmlType: import("vue").ComputedRef<"text" | "email" | "url">;
|
|
||||||
inputMode: import("vue").ComputedRef<string | undefined>;
|
|
||||||
onInput: (e: Event) => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: EntradaTexto["value"]) => true;
|
|
||||||
/** Compat Vue2 (v-model padrão: value + input) */
|
|
||||||
input: (_v: EntradaTexto["value"]) => true;
|
|
||||||
change: (_v: EntradaTexto["value"]) => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
/** Interface padrão (EliEntrada): value + opcoes. */
|
|
||||||
value: {
|
|
||||||
type: PropType<EntradaTexto["value"]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<EntradaTexto["opcoes"]>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
"onUpdate:value"?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onInput?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onChange?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
value: string | null | undefined;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
||||||
declare const _default: typeof __VLS_export;
|
|
||||||
export default _default;
|
|
||||||
5
dist/types/componentes/EliEntrada/index.d.ts
vendored
5
dist/types/componentes/EliEntrada/index.d.ts
vendored
|
|
@ -1,5 +0,0 @@
|
||||||
import EliEntradaTexto from "./EliEntradaTexto.vue";
|
|
||||||
import EliEntradaNumero from "./EliEntradaNumero.vue";
|
|
||||||
import EliEntradaDataHora from "./EliEntradaDataHora.vue";
|
|
||||||
export { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora };
|
|
||||||
export type { PadroesEntradas, TipoEntrada } from "./tiposEntradas";
|
|
||||||
|
|
@ -1,349 +0,0 @@
|
||||||
export declare const registryTabelaCelulas: {
|
|
||||||
readonly texto: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: import("vue").PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: import("vue").PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
limiteCaracteres?: number;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep";
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: {
|
|
||||||
[x: string]: unknown;
|
|
||||||
};
|
|
||||||
emit: ((event: "update:value", _v: string | null | undefined) => void) & ((event: "input", _v: string | null | undefined) => void) & ((event: "change", _v: string | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
|
||||||
localValue: import("vue").WritableComputedRef<string | null | undefined, string | null | undefined>;
|
|
||||||
inputHtmlType: import("vue").ComputedRef<"text" | "email" | "url">;
|
|
||||||
inputMode: import("vue").ComputedRef<string | undefined>;
|
|
||||||
onInput: (e: Event) => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: string | null | undefined) => true;
|
|
||||||
input: (_v: string | null | undefined) => true;
|
|
||||||
change: (_v: string | null | undefined) => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: import("vue").PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: import("vue").PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
limiteCaracteres?: number;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep";
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
"onUpdate:value"?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onInput?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onChange?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
value: string | null | undefined;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
||||||
readonly numero: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: import("vue").PropType<number | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: import("vue").PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
sufixo?: string;
|
|
||||||
prefixo?: string;
|
|
||||||
precisao?: number;
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: {
|
|
||||||
[x: string]: unknown;
|
|
||||||
};
|
|
||||||
emit: ((event: "update:value", _v: number | null | undefined) => void) & ((event: "input", _v: number | null | undefined) => void) & ((event: "change", _v: number | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
|
||||||
displayValue: import("vue").Ref<string, string>;
|
|
||||||
isInteiro: import("vue").ComputedRef<boolean>;
|
|
||||||
onUpdateModelValue: (texto: string) => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: number | null | undefined) => true;
|
|
||||||
input: (_v: number | null | undefined) => true;
|
|
||||||
change: (_v: number | null | undefined) => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: import("vue").PropType<number | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: import("vue").PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
sufixo?: string;
|
|
||||||
prefixo?: string;
|
|
||||||
precisao?: number;
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
"onUpdate:value"?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onInput?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onChange?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
value: number | null | undefined;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
||||||
readonly dataHora: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: import("vue").PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: import("vue").PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../../tipos/entrada.js").CampoDensidade;
|
|
||||||
variante?: import("../../tipos/entrada.js").CampoVariante;
|
|
||||||
}>;
|
|
||||||
required: false;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
modelValue: {
|
|
||||||
type: import("vue").PropType<string | null>;
|
|
||||||
default: null;
|
|
||||||
};
|
|
||||||
modo: {
|
|
||||||
type: import("vue").PropType<"data" | "dataHora" | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
rotulo: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
placeholder: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
desabilitado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
limpavel: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
erro: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
mensagensErro: {
|
|
||||||
type: import("vue").PropType<string | string[]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dica: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dicaPersistente: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
densidade: {
|
|
||||||
type: import("vue").PropType<import("../../tipos/entrada.js").CampoDensidade>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
variante: {
|
|
||||||
type: import("vue").PropType<import("../../tipos/entrada.js").CampoVariante>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
min: {
|
|
||||||
type: import("vue").PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
max: {
|
|
||||||
type: import("vue").PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: {
|
|
||||||
[x: string]: unknown;
|
|
||||||
};
|
|
||||||
valor: import("vue").WritableComputedRef<string, string>;
|
|
||||||
tipoInput: import("vue").ComputedRef<"date" | "datetime-local">;
|
|
||||||
minLocal: import("vue").ComputedRef<string | undefined>;
|
|
||||||
maxLocal: import("vue").ComputedRef<string | undefined>;
|
|
||||||
opcoesEfetivas: import("vue").ComputedRef<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../../tipos/entrada.js").CampoDensidade;
|
|
||||||
variante?: import("../../tipos/entrada.js").CampoVariante;
|
|
||||||
}>;
|
|
||||||
desabilitadoEfetivo: import("vue").ComputedRef<boolean>;
|
|
||||||
emitCompatFocus: () => void;
|
|
||||||
emitCompatBlur: () => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: string | null) => true;
|
|
||||||
input: (_v: string | null) => true;
|
|
||||||
change: (_v: string | null) => true;
|
|
||||||
"update:modelValue": (_v: string | null) => true;
|
|
||||||
alterar: (_v: string | null) => true;
|
|
||||||
foco: () => true;
|
|
||||||
desfoco: () => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: import("vue").PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: import("vue").PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../../tipos/entrada.js").CampoDensidade;
|
|
||||||
variante?: import("../../tipos/entrada.js").CampoVariante;
|
|
||||||
}>;
|
|
||||||
required: false;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
modelValue: {
|
|
||||||
type: import("vue").PropType<string | null>;
|
|
||||||
default: null;
|
|
||||||
};
|
|
||||||
modo: {
|
|
||||||
type: import("vue").PropType<"data" | "dataHora" | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
rotulo: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
placeholder: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
desabilitado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
limpavel: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
erro: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
mensagensErro: {
|
|
||||||
type: import("vue").PropType<string | string[]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dica: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dicaPersistente: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
densidade: {
|
|
||||||
type: import("vue").PropType<import("../../tipos/entrada.js").CampoDensidade>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
variante: {
|
|
||||||
type: import("vue").PropType<import("../../tipos/entrada.js").CampoVariante>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
min: {
|
|
||||||
type: import("vue").PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
max: {
|
|
||||||
type: import("vue").PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
"onUpdate:value"?: ((_v: string | null) => any) | undefined;
|
|
||||||
onInput?: ((_v: string | null) => any) | undefined;
|
|
||||||
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;
|
|
||||||
onFoco?: (() => any) | undefined;
|
|
||||||
onDesfoco?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
modo: "data" | "dataHora" | undefined;
|
|
||||||
limpavel: boolean;
|
|
||||||
erro: boolean;
|
|
||||||
mensagensErro: string | string[];
|
|
||||||
dica: string;
|
|
||||||
dicaPersistente: boolean;
|
|
||||||
min: string | undefined;
|
|
||||||
max: string | undefined;
|
|
||||||
densidade: import("../../tipos/entrada.js").CampoDensidade;
|
|
||||||
variante: import("../../tipos/entrada.js").CampoVariante;
|
|
||||||
opcoes: {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../../tipos/entrada.js").CampoDensidade;
|
|
||||||
variante?: import("../../tipos/entrada.js").CampoVariante;
|
|
||||||
};
|
|
||||||
value: string | null | undefined;
|
|
||||||
placeholder: string;
|
|
||||||
rotulo: string;
|
|
||||||
modelValue: string | null;
|
|
||||||
desabilitado: boolean;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
||||||
};
|
|
||||||
|
|
@ -1,96 +0,0 @@
|
||||||
/**
|
|
||||||
* Tipos base para componentes de entrada (EliEntrada*)
|
|
||||||
*
|
|
||||||
* Objetivo:
|
|
||||||
* - Padronizar o shape de dados de todos os componentes de entrada.
|
|
||||||
* - Cada entrada possui sempre:
|
|
||||||
* 1) `value`: o valor atual (tipado)
|
|
||||||
* 2) `opcoes`: configuração do componente (rótulo, placeholder e extras por tipo)
|
|
||||||
*
|
|
||||||
* Como usar:
|
|
||||||
* - `PadroesEntradas[tipo]` retorna a tipagem completa (value + opcoes) daquele tipo.
|
|
||||||
* - `TipoEntrada` é a união com todos os tipos suportados (ex.: "texto" | "numero").
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Contrato padrão de uma entrada.
|
|
||||||
*
|
|
||||||
* @typeParam T - tipo do `value` (ex.: string | null | undefined)
|
|
||||||
* @typeParam Mais - campos adicionais dentro de `opcoes`, específicos do tipo de entrada
|
|
||||||
*/
|
|
||||||
export type tipoPadraoEntrada<T, Mais extends Record<string, unknown> = {}> = {
|
|
||||||
/** Valor atual do campo (pode aceitar null/undefined quando aplicável) */
|
|
||||||
value: T;
|
|
||||||
/** Configurações do componente (visuais + regras simples do tipo) */
|
|
||||||
opcoes: {
|
|
||||||
/** Rótulo exibido ao usuário */
|
|
||||||
rotulo: string;
|
|
||||||
/** Texto de ajuda dentro do input quando vazio */
|
|
||||||
placeholder?: string;
|
|
||||||
} & Mais;
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Mapa de tipos de entrada suportados e suas configurações específicas.
|
|
||||||
*
|
|
||||||
* Observação importante:
|
|
||||||
* - As chaves deste objeto (ex.: "texto", "numero") viram o tipo `TipoEntrada`.
|
|
||||||
* - Cada item define:
|
|
||||||
* - `value`: tipo do valor
|
|
||||||
* - `opcoes`: opções comuns + extras específicas
|
|
||||||
*/
|
|
||||||
export type PadroesEntradas = {
|
|
||||||
texto: tipoPadraoEntrada<string | null | undefined, {
|
|
||||||
/** Limite máximo de caracteres permitidos (se definido) */
|
|
||||||
limiteCaracteres?: number;
|
|
||||||
/**
|
|
||||||
* Formato/máscara aplicada ao texto.
|
|
||||||
* Obs: o `value` SEMPRE será o texto formatado (o que aparece no input).
|
|
||||||
*/
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep";
|
|
||||||
}>;
|
|
||||||
numero: tipoPadraoEntrada<number | null | undefined, {
|
|
||||||
/** Unidade de medida (ex.: "kg", "m³") */
|
|
||||||
sufixo?: string;
|
|
||||||
/** Moéda (ex.: "R$") */
|
|
||||||
prefixo?: string;
|
|
||||||
/**
|
|
||||||
* Passo/precisão do valor numérico.
|
|
||||||
* - 1 => somente inteiros
|
|
||||||
* - 0.1 => 1 casa decimal
|
|
||||||
* - 0.01 => 2 casas decimais
|
|
||||||
*
|
|
||||||
* Dica: este conceito corresponde ao atributo HTML `step`.
|
|
||||||
*/
|
|
||||||
precisao?: number;
|
|
||||||
}>;
|
|
||||||
dataHora: tipoPadraoEntrada<string | null | undefined, {
|
|
||||||
/** Define o tipo de entrada. - `dataHora`: datetime-local - `data`: date */
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
/** 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;
|
|
||||||
/** Valor mínimo permitido (ISO 8601 - offset ou Z). */
|
|
||||||
min?: string;
|
|
||||||
/** Valor máximo permitido (ISO 8601 - offset ou Z). */
|
|
||||||
max?: string;
|
|
||||||
/** 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.
|
|
||||||
* Ex.: "texto" | "numero"
|
|
||||||
*/
|
|
||||||
export type TipoEntrada = keyof PadroesEntradas;
|
|
||||||
export type PadraoComponenteEntrada<T extends TipoEntrada> = readonly [T, PadroesEntradas[T]['opcoes']];
|
|
||||||
export type ComponenteEntrada = {
|
|
||||||
[K in TipoEntrada]: PadraoComponenteEntrada<K>;
|
|
||||||
}[TipoEntrada];
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
/** Formata CEP no padrão 00000-000 */
|
|
||||||
export declare function formatarCep(valor: string): string;
|
|
||||||
|
|
@ -1,467 +0,0 @@
|
||||||
import { PropType } from "vue";
|
|
||||||
import type { ComponenteEntrada } from "../EliEntrada/tiposEntradas";
|
|
||||||
import type { EliTabelaConsulta } from "./types-eli-tabela";
|
|
||||||
type FiltroBase<T> = NonNullable<EliTabelaConsulta<T>["filtroAvancado"]>[number];
|
|
||||||
type LinhaFiltro<T> = {
|
|
||||||
coluna: keyof T;
|
|
||||||
entrada: ComponenteEntrada;
|
|
||||||
operador: string;
|
|
||||||
valor: any;
|
|
||||||
};
|
|
||||||
declare function rotuloDoFiltro(f: FiltroBase<any>): string;
|
|
||||||
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
aberto: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
filtrosBase: {
|
|
||||||
type: PropType<Array<FiltroBase<any>>>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
modelo: {
|
|
||||||
type: PropType<Array<any>>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
linhas: import("vue").Ref<{
|
|
||||||
coluna: string | number | symbol;
|
|
||||||
entrada: readonly ["texto", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
limiteCaracteres?: number | undefined;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep" | undefined;
|
|
||||||
}] | readonly ["dataHora", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
modo?: "data" | "dataHora" | undefined;
|
|
||||||
limpavel?: boolean | undefined;
|
|
||||||
erro?: boolean | undefined;
|
|
||||||
mensagensErro?: string | string[] | undefined;
|
|
||||||
dica?: string | undefined;
|
|
||||||
dicaPersistente?: boolean | undefined;
|
|
||||||
min?: string | undefined;
|
|
||||||
max?: string | undefined;
|
|
||||||
densidade?: import("../../tipos").CampoDensidade | undefined;
|
|
||||||
variante?: import("../../tipos").CampoVariante | undefined;
|
|
||||||
}] | readonly ["numero", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
sufixo?: string | undefined;
|
|
||||||
prefixo?: string | undefined;
|
|
||||||
precisao?: number | undefined;
|
|
||||||
}];
|
|
||||||
operador: string;
|
|
||||||
valor: any;
|
|
||||||
}[], LinhaFiltro<any>[] | {
|
|
||||||
coluna: string | number | symbol;
|
|
||||||
entrada: readonly ["texto", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
limiteCaracteres?: number | undefined;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep" | undefined;
|
|
||||||
}] | readonly ["dataHora", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
modo?: "data" | "dataHora" | undefined;
|
|
||||||
limpavel?: boolean | undefined;
|
|
||||||
erro?: boolean | undefined;
|
|
||||||
mensagensErro?: string | string[] | undefined;
|
|
||||||
dica?: string | undefined;
|
|
||||||
dicaPersistente?: boolean | undefined;
|
|
||||||
min?: string | undefined;
|
|
||||||
max?: string | undefined;
|
|
||||||
densidade?: import("../../tipos").CampoDensidade | undefined;
|
|
||||||
variante?: import("../../tipos").CampoVariante | undefined;
|
|
||||||
}] | readonly ["numero", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
sufixo?: string | undefined;
|
|
||||||
prefixo?: string | undefined;
|
|
||||||
precisao?: number | undefined;
|
|
||||||
}];
|
|
||||||
operador: string;
|
|
||||||
valor: any;
|
|
||||||
}[]>;
|
|
||||||
opcoesParaAdicionar: import("vue").ComputedRef<{
|
|
||||||
rotulo: string;
|
|
||||||
coluna: string | number | symbol;
|
|
||||||
operador: import("p-comuns").operadores | keyof typeof import("p-comuns").operadores;
|
|
||||||
entrada: ComponenteEntrada;
|
|
||||||
}[]>;
|
|
||||||
colunaParaAdicionar: import("vue").Ref<string, string>;
|
|
||||||
componenteEntrada: (entrada: ComponenteEntrada) => import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
limiteCaracteres?: number;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep";
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: {
|
|
||||||
[x: string]: unknown;
|
|
||||||
};
|
|
||||||
emit: ((event: "update:value", _v: string | null | undefined) => void) & ((event: "input", _v: string | null | undefined) => void) & ((event: "change", _v: string | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
|
||||||
localValue: import("vue").WritableComputedRef<string | null | undefined, string | null | undefined>;
|
|
||||||
inputHtmlType: import("vue").ComputedRef<"text" | "email" | "url">;
|
|
||||||
inputMode: import("vue").ComputedRef<string | undefined>;
|
|
||||||
onInput: (e: Event) => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: string | null | undefined) => true;
|
|
||||||
input: (_v: string | null | undefined) => true;
|
|
||||||
change: (_v: string | null | undefined) => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
limiteCaracteres?: number;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep";
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
"onUpdate:value"?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onInput?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onChange?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
value: string | null | undefined;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any> | import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<number | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
sufixo?: string;
|
|
||||||
prefixo?: string;
|
|
||||||
precisao?: number;
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: {
|
|
||||||
[x: string]: unknown;
|
|
||||||
};
|
|
||||||
emit: ((event: "update:value", _v: number | null | undefined) => void) & ((event: "input", _v: number | null | undefined) => void) & ((event: "change", _v: number | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
|
||||||
displayValue: import("vue").Ref<string, string>;
|
|
||||||
isInteiro: import("vue").ComputedRef<boolean>;
|
|
||||||
onUpdateModelValue: (texto: string) => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: number | null | undefined) => true;
|
|
||||||
input: (_v: number | null | undefined) => true;
|
|
||||||
change: (_v: number | null | undefined) => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<number | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
sufixo?: string;
|
|
||||||
prefixo?: string;
|
|
||||||
precisao?: number;
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
"onUpdate:value"?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onInput?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onChange?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
value: number | null | undefined;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any> | import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../../tipos").CampoDensidade;
|
|
||||||
variante?: import("../../tipos").CampoVariante;
|
|
||||||
}>;
|
|
||||||
required: false;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
modelValue: {
|
|
||||||
type: PropType<string | null>;
|
|
||||||
default: null;
|
|
||||||
};
|
|
||||||
modo: {
|
|
||||||
type: PropType<"data" | "dataHora" | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
rotulo: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
placeholder: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
desabilitado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
limpavel: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
erro: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
mensagensErro: {
|
|
||||||
type: PropType<string | string[]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dica: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dicaPersistente: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
densidade: {
|
|
||||||
type: PropType<import("../../tipos").CampoDensidade>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
variante: {
|
|
||||||
type: PropType<import("../../tipos").CampoVariante>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
min: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
max: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: {
|
|
||||||
[x: string]: unknown;
|
|
||||||
};
|
|
||||||
valor: import("vue").WritableComputedRef<string, string>;
|
|
||||||
tipoInput: import("vue").ComputedRef<"date" | "datetime-local">;
|
|
||||||
minLocal: import("vue").ComputedRef<string | undefined>;
|
|
||||||
maxLocal: import("vue").ComputedRef<string | undefined>;
|
|
||||||
opcoesEfetivas: import("vue").ComputedRef<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../../tipos").CampoDensidade;
|
|
||||||
variante?: import("../../tipos").CampoVariante;
|
|
||||||
}>;
|
|
||||||
desabilitadoEfetivo: import("vue").ComputedRef<boolean>;
|
|
||||||
emitCompatFocus: () => void;
|
|
||||||
emitCompatBlur: () => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: string | null) => true;
|
|
||||||
input: (_v: string | null) => true;
|
|
||||||
change: (_v: string | null) => true;
|
|
||||||
"update:modelValue": (_v: string | null) => true;
|
|
||||||
alterar: (_v: string | null) => true;
|
|
||||||
foco: () => true;
|
|
||||||
desfoco: () => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../../tipos").CampoDensidade;
|
|
||||||
variante?: import("../../tipos").CampoVariante;
|
|
||||||
}>;
|
|
||||||
required: false;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
modelValue: {
|
|
||||||
type: PropType<string | null>;
|
|
||||||
default: null;
|
|
||||||
};
|
|
||||||
modo: {
|
|
||||||
type: PropType<"data" | "dataHora" | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
rotulo: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
placeholder: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
desabilitado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
limpavel: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
erro: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
mensagensErro: {
|
|
||||||
type: PropType<string | string[]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dica: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dicaPersistente: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
densidade: {
|
|
||||||
type: PropType<import("../../tipos").CampoDensidade>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
variante: {
|
|
||||||
type: PropType<import("../../tipos").CampoVariante>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
min: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
max: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
"onUpdate:value"?: ((_v: string | null) => any) | undefined;
|
|
||||||
onInput?: ((_v: string | null) => any) | undefined;
|
|
||||||
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;
|
|
||||||
onFoco?: (() => any) | undefined;
|
|
||||||
onDesfoco?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
modo: "data" | "dataHora" | undefined;
|
|
||||||
limpavel: boolean;
|
|
||||||
erro: boolean;
|
|
||||||
mensagensErro: string | string[];
|
|
||||||
dica: string;
|
|
||||||
dicaPersistente: boolean;
|
|
||||||
min: string | undefined;
|
|
||||||
max: string | undefined;
|
|
||||||
densidade: import("../../tipos").CampoDensidade;
|
|
||||||
variante: import("../../tipos").CampoVariante;
|
|
||||||
opcoes: {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../../tipos").CampoDensidade;
|
|
||||||
variante?: import("../../tipos").CampoVariante;
|
|
||||||
};
|
|
||||||
value: string | null | undefined;
|
|
||||||
placeholder: string;
|
|
||||||
rotulo: string;
|
|
||||||
modelValue: string | null;
|
|
||||||
desabilitado: boolean;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
||||||
opcoesEntrada: (entrada: ComponenteEntrada) => any;
|
|
||||||
adicionar: () => void;
|
|
||||||
remover: (idx: number) => void;
|
|
||||||
emitFechar: () => void;
|
|
||||||
emitSalvar: () => void;
|
|
||||||
emitLimpar: () => void;
|
|
||||||
rotuloDoFiltro: typeof rotuloDoFiltro;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
fechar: () => true;
|
|
||||||
limpar: () => true;
|
|
||||||
salvar: (_linhas: any[]) => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
aberto: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
filtrosBase: {
|
|
||||||
type: PropType<Array<FiltroBase<any>>>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
modelo: {
|
|
||||||
type: PropType<Array<any>>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
onFechar?: (() => any) | undefined;
|
|
||||||
onSalvar?: ((_linhas: any[]) => any) | undefined;
|
|
||||||
onLimpar?: (() => any) | undefined;
|
|
||||||
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
||||||
declare const _default: typeof __VLS_export;
|
|
||||||
export default _default;
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
import { PropType } from "vue";
|
|
||||||
import type { TiposTabelaCelulas } from "./tiposTabelaCelulas";
|
|
||||||
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
dados: {
|
|
||||||
type: PropType<TiposTabelaCelulas["textoTruncado"]>;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
dados: {
|
|
||||||
texto: string;
|
|
||||||
acao?: () => void;
|
|
||||||
} | undefined;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
dados: {
|
|
||||||
type: PropType<TiposTabelaCelulas["textoTruncado"]>;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
||||||
declare const _default: typeof __VLS_export;
|
|
||||||
export default _default;
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
export type EliTabelaFiltroAvancadoSalvo<T> = Array<{
|
|
||||||
coluna: keyof T;
|
|
||||||
valor: any;
|
|
||||||
}>;
|
|
||||||
export declare function carregarFiltroAvancado<T>(nomeTabela: string): EliTabelaFiltroAvancadoSalvo<T>;
|
|
||||||
export declare function salvarFiltroAvancado<T>(nomeTabela: string, filtros: EliTabelaFiltroAvancadoSalvo<T>): void;
|
|
||||||
export declare function limparFiltroAvancado(nomeTabela: string): void;
|
|
||||||
146
dist/types/componentes/campo/EliInput.vue.d.ts
vendored
Normal file
146
dist/types/componentes/campo/EliInput.vue.d.ts
vendored
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
import { PropType } from "vue";
|
||||||
|
import type { CampoDensidade, CampoOpcao, CampoOpcaoBruta, CampoTipo, CampoValor, CampoValorMultiplo, CampoVariante } from "../../tipos";
|
||||||
|
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
||||||
|
/**
|
||||||
|
* Aceita valor simples (text-like) ou lista de valores (checkbox/select multiple).
|
||||||
|
* O componente não converte tipos automaticamente: mantém o que receber.
|
||||||
|
*/
|
||||||
|
modelValue: {
|
||||||
|
type: PropType<CampoValor | CampoValorMultiplo>;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
type: {
|
||||||
|
type: PropType<CampoTipo>;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
label: StringConstructor;
|
||||||
|
placeholder: StringConstructor;
|
||||||
|
disabled: BooleanConstructor;
|
||||||
|
error: BooleanConstructor;
|
||||||
|
errorMessages: {
|
||||||
|
type: PropType<string | string[]>;
|
||||||
|
default: () => never[];
|
||||||
|
};
|
||||||
|
hint: StringConstructor;
|
||||||
|
persistentHint: BooleanConstructor;
|
||||||
|
rows: {
|
||||||
|
type: NumberConstructor;
|
||||||
|
default: number;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Para select/radio/checkbox.
|
||||||
|
* Aceita lista já normalizada ({ label, value }) ou valores primitivos.
|
||||||
|
*/
|
||||||
|
options: {
|
||||||
|
type: PropType<Array<CampoOpcaoBruta>>;
|
||||||
|
default: () => never[];
|
||||||
|
};
|
||||||
|
clearable: BooleanConstructor;
|
||||||
|
variant: {
|
||||||
|
type: PropType<CampoVariante>;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
density: {
|
||||||
|
type: PropType<CampoDensidade>;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
color: {
|
||||||
|
type: StringConstructor;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
row: BooleanConstructor;
|
||||||
|
showPasswordToggle: BooleanConstructor;
|
||||||
|
multiple: BooleanConstructor;
|
||||||
|
chips: BooleanConstructor;
|
||||||
|
}>, {
|
||||||
|
attrs: {
|
||||||
|
[x: string]: unknown;
|
||||||
|
};
|
||||||
|
value: import("vue").WritableComputedRef<CampoValor | CampoValorMultiplo, CampoValor | CampoValorMultiplo>;
|
||||||
|
isTextLike: import("vue").ComputedRef<boolean>;
|
||||||
|
inputHtmlType: import("vue").ComputedRef<"text" | "password">;
|
||||||
|
inputMode: import("vue").ComputedRef<"tel" | "decimal" | "numeric" | undefined>;
|
||||||
|
internalColor: import("vue").ComputedRef<string | undefined>;
|
||||||
|
showPassword: import("vue").Ref<boolean, boolean>;
|
||||||
|
togglePassword: () => void;
|
||||||
|
onInput: (e: Event) => void;
|
||||||
|
onFocus: () => void;
|
||||||
|
onBlur: () => void;
|
||||||
|
computedItems: import("vue").ComputedRef<CampoOpcao[]>;
|
||||||
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("update:modelValue" | "change" | "focus" | "blur")[], "update:modelValue" | "change" | "focus" | "blur", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
||||||
|
/**
|
||||||
|
* Aceita valor simples (text-like) ou lista de valores (checkbox/select multiple).
|
||||||
|
* O componente não converte tipos automaticamente: mantém o que receber.
|
||||||
|
*/
|
||||||
|
modelValue: {
|
||||||
|
type: PropType<CampoValor | CampoValorMultiplo>;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
type: {
|
||||||
|
type: PropType<CampoTipo>;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
label: StringConstructor;
|
||||||
|
placeholder: StringConstructor;
|
||||||
|
disabled: BooleanConstructor;
|
||||||
|
error: BooleanConstructor;
|
||||||
|
errorMessages: {
|
||||||
|
type: PropType<string | string[]>;
|
||||||
|
default: () => never[];
|
||||||
|
};
|
||||||
|
hint: StringConstructor;
|
||||||
|
persistentHint: BooleanConstructor;
|
||||||
|
rows: {
|
||||||
|
type: NumberConstructor;
|
||||||
|
default: number;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Para select/radio/checkbox.
|
||||||
|
* Aceita lista já normalizada ({ label, value }) ou valores primitivos.
|
||||||
|
*/
|
||||||
|
options: {
|
||||||
|
type: PropType<Array<CampoOpcaoBruta>>;
|
||||||
|
default: () => never[];
|
||||||
|
};
|
||||||
|
clearable: BooleanConstructor;
|
||||||
|
variant: {
|
||||||
|
type: PropType<CampoVariante>;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
density: {
|
||||||
|
type: PropType<CampoDensidade>;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
color: {
|
||||||
|
type: StringConstructor;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
row: BooleanConstructor;
|
||||||
|
showPasswordToggle: BooleanConstructor;
|
||||||
|
multiple: BooleanConstructor;
|
||||||
|
chips: BooleanConstructor;
|
||||||
|
}>> & Readonly<{
|
||||||
|
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
||||||
|
onChange?: ((...args: any[]) => any) | undefined;
|
||||||
|
onFocus?: ((...args: any[]) => any) | undefined;
|
||||||
|
onBlur?: ((...args: any[]) => any) | undefined;
|
||||||
|
}>, {
|
||||||
|
color: string;
|
||||||
|
type: CampoTipo;
|
||||||
|
variant: CampoVariante;
|
||||||
|
disabled: boolean;
|
||||||
|
error: boolean;
|
||||||
|
persistentHint: boolean;
|
||||||
|
clearable: boolean;
|
||||||
|
row: boolean;
|
||||||
|
showPasswordToggle: boolean;
|
||||||
|
multiple: boolean;
|
||||||
|
chips: boolean;
|
||||||
|
modelValue: CampoValor | CampoValorMultiplo;
|
||||||
|
errorMessages: string | string[];
|
||||||
|
rows: number;
|
||||||
|
options: CampoOpcaoBruta[];
|
||||||
|
density: CampoDensidade;
|
||||||
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
||||||
|
declare const _default: typeof __VLS_export;
|
||||||
|
export default _default;
|
||||||
1
dist/types/componentes/campo/index.d.ts
vendored
Normal file
1
dist/types/componentes/campo/index.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export { default as EliInput } from "./EliInput.vue";
|
||||||
1
dist/types/componentes/campo/utils/cep.d.ts
vendored
Normal file
1
dist/types/componentes/campo/utils/cep.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export declare function formatarCep(v: string): string;
|
||||||
9
dist/types/componentes/campo/utils/numerico.d.ts
vendored
Normal file
9
dist/types/componentes/campo/utils/numerico.d.ts
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
export declare function somenteNumeros(valor: string): string;
|
||||||
|
export declare function formatarDecimal(valor: string): string;
|
||||||
|
/**
|
||||||
|
* Formatação para percentual:
|
||||||
|
* - remove '%' caso venha junto (ex: colar "10%")
|
||||||
|
* - mantém apenas dígitos e vírgula (no máximo uma)
|
||||||
|
*/
|
||||||
|
export declare function formatarPorcentagem(valor: string): string;
|
||||||
|
export declare function formatarMoeda(valor: string): string;
|
||||||
|
|
@ -22,7 +22,7 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
};
|
};
|
||||||
}>, {
|
}>, {
|
||||||
rotuloStatus: import("vue").ComputedRef<CartaoStatus>;
|
rotuloStatus: import("vue").ComputedRef<CartaoStatus>;
|
||||||
corStatus: import("vue").ComputedRef<"primary" | "secondary" | "success" | "error">;
|
corStatus: import("vue").ComputedRef<"primary" | "error" | "secondary" | "success">;
|
||||||
classeStatus: import("vue").ComputedRef<string>;
|
classeStatus: import("vue").ComputedRef<string>;
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
||||||
|
|
|
||||||
221
dist/types/componentes/data_hora/EliDataHora.vue.d.ts
vendored
Normal file
221
dist/types/componentes/data_hora/EliDataHora.vue.d.ts
vendored
Normal file
|
|
@ -0,0 +1,221 @@
|
||||||
|
import { PropType } from "vue";
|
||||||
|
import type { CampoDensidade, CampoVariante } from "../../tipos";
|
||||||
|
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
||||||
|
/**
|
||||||
|
* Valor em ISO 8601:
|
||||||
|
* - com offset (ex.: `2026-01-09T13:15:00-03:00`)
|
||||||
|
* - ou UTC absoluto (ex.: `2026-01-09T16:15:00Z`)
|
||||||
|
*/
|
||||||
|
modelValue: {
|
||||||
|
type: PropType<string | null>;
|
||||||
|
default: null;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Define o tipo de entrada.
|
||||||
|
* - `dataHora`: usa `datetime-local`
|
||||||
|
* - `data`: usa `date`
|
||||||
|
*/
|
||||||
|
modo: {
|
||||||
|
type: PropType<"data" | "dataHora">;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
/** Rótulo exibido no v-text-field (Vuetify). */
|
||||||
|
rotulo: {
|
||||||
|
type: StringConstructor;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
/** Placeholder do input. */
|
||||||
|
placeholder: {
|
||||||
|
type: StringConstructor;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
/** Desabilita a interação. */
|
||||||
|
desabilitado: {
|
||||||
|
type: BooleanConstructor;
|
||||||
|
default: boolean;
|
||||||
|
};
|
||||||
|
/** Se true, mostra ícone para limpar o valor (Vuetify clearable). */
|
||||||
|
limpavel: {
|
||||||
|
type: BooleanConstructor;
|
||||||
|
default: boolean;
|
||||||
|
};
|
||||||
|
/** Estado de erro (visual). */
|
||||||
|
erro: {
|
||||||
|
type: BooleanConstructor;
|
||||||
|
default: boolean;
|
||||||
|
};
|
||||||
|
/** Mensagens de erro. */
|
||||||
|
mensagensErro: {
|
||||||
|
type: PropType<string | string[]>;
|
||||||
|
default: () => never[];
|
||||||
|
};
|
||||||
|
/** Texto de apoio. */
|
||||||
|
dica: {
|
||||||
|
type: StringConstructor;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
/** Mantém a dica sempre visível. */
|
||||||
|
dicaPersistente: {
|
||||||
|
type: BooleanConstructor;
|
||||||
|
default: boolean;
|
||||||
|
};
|
||||||
|
/** Densidade do campo (Vuetify). */
|
||||||
|
densidade: {
|
||||||
|
type: PropType<CampoDensidade>;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
/** Variante do v-text-field (Vuetify). */
|
||||||
|
variante: {
|
||||||
|
type: PropType<CampoVariante>;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Valor mínimo permitido.
|
||||||
|
* ISO 8601 (offset ou `Z`).
|
||||||
|
*/
|
||||||
|
min: {
|
||||||
|
type: PropType<string | undefined>;
|
||||||
|
default: undefined;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Valor máximo permitido.
|
||||||
|
* ISO 8601 (offset ou `Z`).
|
||||||
|
*/
|
||||||
|
max: {
|
||||||
|
type: PropType<string | undefined>;
|
||||||
|
default: undefined;
|
||||||
|
};
|
||||||
|
}>, {
|
||||||
|
attrs: {
|
||||||
|
[x: string]: unknown;
|
||||||
|
};
|
||||||
|
valor: import("vue").WritableComputedRef<string, string>;
|
||||||
|
emit: ((event: "update:modelValue", _valor: string | null) => void) & ((event: "alterar", _valor: string | null) => void) & ((event: "foco") => void) & ((event: "desfoco") => void);
|
||||||
|
minLocal: import("vue").ComputedRef<string | undefined>;
|
||||||
|
maxLocal: import("vue").ComputedRef<string | undefined>;
|
||||||
|
tipoInput: import("vue").ComputedRef<"date" | "datetime-local">;
|
||||||
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
||||||
|
/** v-model padrão. */
|
||||||
|
"update:modelValue": (_valor: string | null) => true;
|
||||||
|
/** Alias para consumidores que querem um evento semântico. */
|
||||||
|
alterar: (_valor: string | null) => true;
|
||||||
|
foco: () => true;
|
||||||
|
desfoco: () => true;
|
||||||
|
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
||||||
|
/**
|
||||||
|
* Valor em ISO 8601:
|
||||||
|
* - com offset (ex.: `2026-01-09T13:15:00-03:00`)
|
||||||
|
* - ou UTC absoluto (ex.: `2026-01-09T16:15:00Z`)
|
||||||
|
*/
|
||||||
|
modelValue: {
|
||||||
|
type: PropType<string | null>;
|
||||||
|
default: null;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Define o tipo de entrada.
|
||||||
|
* - `dataHora`: usa `datetime-local`
|
||||||
|
* - `data`: usa `date`
|
||||||
|
*/
|
||||||
|
modo: {
|
||||||
|
type: PropType<"data" | "dataHora">;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
/** Rótulo exibido no v-text-field (Vuetify). */
|
||||||
|
rotulo: {
|
||||||
|
type: StringConstructor;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
/** Placeholder do input. */
|
||||||
|
placeholder: {
|
||||||
|
type: StringConstructor;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
/** Desabilita a interação. */
|
||||||
|
desabilitado: {
|
||||||
|
type: BooleanConstructor;
|
||||||
|
default: boolean;
|
||||||
|
};
|
||||||
|
/** Se true, mostra ícone para limpar o valor (Vuetify clearable). */
|
||||||
|
limpavel: {
|
||||||
|
type: BooleanConstructor;
|
||||||
|
default: boolean;
|
||||||
|
};
|
||||||
|
/** Estado de erro (visual). */
|
||||||
|
erro: {
|
||||||
|
type: BooleanConstructor;
|
||||||
|
default: boolean;
|
||||||
|
};
|
||||||
|
/** Mensagens de erro. */
|
||||||
|
mensagensErro: {
|
||||||
|
type: PropType<string | string[]>;
|
||||||
|
default: () => never[];
|
||||||
|
};
|
||||||
|
/** Texto de apoio. */
|
||||||
|
dica: {
|
||||||
|
type: StringConstructor;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
/** Mantém a dica sempre visível. */
|
||||||
|
dicaPersistente: {
|
||||||
|
type: BooleanConstructor;
|
||||||
|
default: boolean;
|
||||||
|
};
|
||||||
|
/** Densidade do campo (Vuetify). */
|
||||||
|
densidade: {
|
||||||
|
type: PropType<CampoDensidade>;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
/** Variante do v-text-field (Vuetify). */
|
||||||
|
variante: {
|
||||||
|
type: PropType<CampoVariante>;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Valor mínimo permitido.
|
||||||
|
* ISO 8601 (offset ou `Z`).
|
||||||
|
*/
|
||||||
|
min: {
|
||||||
|
type: PropType<string | undefined>;
|
||||||
|
default: undefined;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Valor máximo permitido.
|
||||||
|
* ISO 8601 (offset ou `Z`).
|
||||||
|
*/
|
||||||
|
max: {
|
||||||
|
type: PropType<string | undefined>;
|
||||||
|
default: undefined;
|
||||||
|
};
|
||||||
|
}>> & Readonly<{
|
||||||
|
"onUpdate:modelValue"?: ((_valor: string | null) => any) | undefined;
|
||||||
|
onAlterar?: ((_valor: string | null) => any) | undefined;
|
||||||
|
onFoco?: (() => any) | undefined;
|
||||||
|
onDesfoco?: (() => any) | undefined;
|
||||||
|
}>, {
|
||||||
|
placeholder: string;
|
||||||
|
modelValue: string | null;
|
||||||
|
modo: "data" | "dataHora";
|
||||||
|
rotulo: string;
|
||||||
|
desabilitado: boolean;
|
||||||
|
limpavel: boolean;
|
||||||
|
erro: boolean;
|
||||||
|
mensagensErro: string | string[];
|
||||||
|
dica: string;
|
||||||
|
dicaPersistente: boolean;
|
||||||
|
densidade: CampoDensidade;
|
||||||
|
variante: CampoVariante;
|
||||||
|
min: string | undefined;
|
||||||
|
max: string | undefined;
|
||||||
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
||||||
|
/**
|
||||||
|
* EliDataHora
|
||||||
|
*
|
||||||
|
* Campo para entrada de data + hora.
|
||||||
|
*
|
||||||
|
* Modelo:
|
||||||
|
* - O componente **recebe** `modelValue` em ISO 8601 (UTC `Z` ou com offset)
|
||||||
|
* - Converte para horário local para exibir (`date` ou `datetime-local`)
|
||||||
|
* - Ao editar, **emite** ISO 8601 com o **offset local**
|
||||||
|
*/
|
||||||
|
declare const _default: typeof __VLS_export;
|
||||||
|
export default _default;
|
||||||
1
dist/types/componentes/data_hora/index.d.ts
vendored
Normal file
1
dist/types/componentes/data_hora/index.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export { default as EliDataHora } from "./EliDataHora.vue";
|
||||||
|
|
@ -1,9 +1,18 @@
|
||||||
|
type Habilidade = "vue" | "react";
|
||||||
declare const __VLS_export: import("vue").DefineComponent<{}, {
|
declare const __VLS_export: import("vue").DefineComponent<{}, {
|
||||||
nome: import("vue").Ref<string, string>;
|
nome: import("vue").Ref<string, string>;
|
||||||
email: import("vue").Ref<string, string>;
|
email: import("vue").Ref<string, string>;
|
||||||
documento: import("vue").Ref<string, string>;
|
documento: import("vue").Ref<string, string>;
|
||||||
|
estado: import("vue").Ref<string[], string[]>;
|
||||||
telefone: import("vue").Ref<string, string>;
|
telefone: import("vue").Ref<string, string>;
|
||||||
|
mensagem: import("vue").Ref<string, string>;
|
||||||
|
senha: import("vue").Ref<string, string>;
|
||||||
|
cor: import("vue").Ref<"azul" | "verde" | null, "azul" | "verde" | null>;
|
||||||
|
habilidades: import("vue").Ref<Habilidade[], Habilidade[]>;
|
||||||
|
idade: import("vue").Ref<string, string>;
|
||||||
|
altura: import("vue").Ref<string, string>;
|
||||||
cep: import("vue").Ref<string, string>;
|
cep: import("vue").Ref<string, string>;
|
||||||
|
valor: import("vue").Ref<string, string>;
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {
|
||||||
EliBotao: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
EliBotao: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
||||||
color: {
|
color: {
|
||||||
|
|
@ -135,59 +144,131 @@ declare const __VLS_export: import("vue").DefineComponent<{}, {
|
||||||
badge: string | number | undefined;
|
badge: string | number | undefined;
|
||||||
radius: import("../../tipos/indicador.js").IndicadorPresetRaio | import("../../tipos/indicador.js").CssLength;
|
radius: import("../../tipos/indicador.js").IndicadorPresetRaio | import("../../tipos/indicador.js").CssLength;
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
||||||
EliEntradaTexto: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
EliInput: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
||||||
value: {
|
modelValue: {
|
||||||
type: import("vue").PropType<string | null | undefined>;
|
type: import("vue").PropType<import("../../tipos/campo.js").CampoValor | import("../../tipos/campo.js").CampoValorMultiplo>;
|
||||||
default: undefined;
|
default: string;
|
||||||
};
|
};
|
||||||
opcoes: {
|
type: {
|
||||||
type: import("vue").PropType<{
|
type: import("vue").PropType<import("../../tipos/campo.js").CampoTipo>;
|
||||||
rotulo: string;
|
default: string;
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
limiteCaracteres?: number;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep";
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
};
|
||||||
|
label: StringConstructor;
|
||||||
|
placeholder: StringConstructor;
|
||||||
|
disabled: BooleanConstructor;
|
||||||
|
error: BooleanConstructor;
|
||||||
|
errorMessages: {
|
||||||
|
type: import("vue").PropType<string | string[]>;
|
||||||
|
default: () => never[];
|
||||||
|
};
|
||||||
|
hint: StringConstructor;
|
||||||
|
persistentHint: BooleanConstructor;
|
||||||
|
rows: {
|
||||||
|
type: NumberConstructor;
|
||||||
|
default: number;
|
||||||
|
};
|
||||||
|
options: {
|
||||||
|
type: import("vue").PropType<Array<import("../../tipos/campo.js").CampoOpcaoBruta>>;
|
||||||
|
default: () => never[];
|
||||||
|
};
|
||||||
|
clearable: BooleanConstructor;
|
||||||
|
variant: {
|
||||||
|
type: import("vue").PropType<import("../../tipos/campo.js").CampoVariante>;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
density: {
|
||||||
|
type: import("vue").PropType<import("../../tipos/campo.js").CampoDensidade>;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
color: {
|
||||||
|
type: StringConstructor;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
row: BooleanConstructor;
|
||||||
|
showPasswordToggle: BooleanConstructor;
|
||||||
|
multiple: BooleanConstructor;
|
||||||
|
chips: BooleanConstructor;
|
||||||
}>, {
|
}>, {
|
||||||
attrs: {
|
attrs: {
|
||||||
[x: string]: unknown;
|
[x: string]: unknown;
|
||||||
};
|
};
|
||||||
emit: ((event: "update:value", _v: string | null | undefined) => void) & ((event: "input", _v: string | null | undefined) => void) & ((event: "change", _v: string | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
value: import("vue").WritableComputedRef<import("../../tipos/campo.js").CampoValor | import("../../tipos/campo.js").CampoValorMultiplo, import("../../tipos/campo.js").CampoValor | import("../../tipos/campo.js").CampoValorMultiplo>;
|
||||||
localValue: import("vue").WritableComputedRef<string | null | undefined, string | null | undefined>;
|
isTextLike: import("vue").ComputedRef<boolean>;
|
||||||
inputHtmlType: import("vue").ComputedRef<"text" | "email" | "url">;
|
inputHtmlType: import("vue").ComputedRef<"text" | "password">;
|
||||||
inputMode: import("vue").ComputedRef<string | undefined>;
|
inputMode: import("vue").ComputedRef<"tel" | "decimal" | "numeric" | undefined>;
|
||||||
|
internalColor: import("vue").ComputedRef<string | undefined>;
|
||||||
|
showPassword: import("vue").Ref<boolean, boolean>;
|
||||||
|
togglePassword: () => void;
|
||||||
onInput: (e: Event) => void;
|
onInput: (e: Event) => void;
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
onFocus: () => void;
|
||||||
"update:value": (_v: string | null | undefined) => true;
|
onBlur: () => void;
|
||||||
input: (_v: string | null | undefined) => true;
|
computedItems: import("vue").ComputedRef<import("../../tipos/campo.js").CampoOpcao[]>;
|
||||||
change: (_v: string | null | undefined) => true;
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("update:modelValue" | "change" | "focus" | "blur")[], "update:modelValue" | "change" | "focus" | "blur", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
||||||
focus: () => true;
|
modelValue: {
|
||||||
blur: () => true;
|
type: import("vue").PropType<import("../../tipos/campo.js").CampoValor | import("../../tipos/campo.js").CampoValorMultiplo>;
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
default: string;
|
||||||
value: {
|
|
||||||
type: import("vue").PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
};
|
||||||
opcoes: {
|
type: {
|
||||||
type: import("vue").PropType<{
|
type: import("vue").PropType<import("../../tipos/campo.js").CampoTipo>;
|
||||||
rotulo: string;
|
default: string;
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
limiteCaracteres?: number;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep";
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
};
|
||||||
|
label: StringConstructor;
|
||||||
|
placeholder: StringConstructor;
|
||||||
|
disabled: BooleanConstructor;
|
||||||
|
error: BooleanConstructor;
|
||||||
|
errorMessages: {
|
||||||
|
type: import("vue").PropType<string | string[]>;
|
||||||
|
default: () => never[];
|
||||||
|
};
|
||||||
|
hint: StringConstructor;
|
||||||
|
persistentHint: BooleanConstructor;
|
||||||
|
rows: {
|
||||||
|
type: NumberConstructor;
|
||||||
|
default: number;
|
||||||
|
};
|
||||||
|
options: {
|
||||||
|
type: import("vue").PropType<Array<import("../../tipos/campo.js").CampoOpcaoBruta>>;
|
||||||
|
default: () => never[];
|
||||||
|
};
|
||||||
|
clearable: BooleanConstructor;
|
||||||
|
variant: {
|
||||||
|
type: import("vue").PropType<import("../../tipos/campo.js").CampoVariante>;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
density: {
|
||||||
|
type: import("vue").PropType<import("../../tipos/campo.js").CampoDensidade>;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
color: {
|
||||||
|
type: StringConstructor;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
row: BooleanConstructor;
|
||||||
|
showPasswordToggle: BooleanConstructor;
|
||||||
|
multiple: BooleanConstructor;
|
||||||
|
chips: BooleanConstructor;
|
||||||
}>> & Readonly<{
|
}>> & Readonly<{
|
||||||
"onUpdate:value"?: ((_v: string | null | undefined) => any) | undefined;
|
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
||||||
onInput?: ((_v: string | null | undefined) => any) | undefined;
|
onChange?: ((...args: any[]) => any) | undefined;
|
||||||
onChange?: ((_v: string | null | undefined) => any) | undefined;
|
onFocus?: ((...args: any[]) => any) | undefined;
|
||||||
onFocus?: (() => any) | undefined;
|
onBlur?: ((...args: any[]) => any) | undefined;
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
}>, {
|
||||||
value: string | null | undefined;
|
color: string;
|
||||||
|
type: import("../../tipos/campo.js").CampoTipo;
|
||||||
|
variant: import("../../tipos/campo.js").CampoVariante;
|
||||||
|
disabled: boolean;
|
||||||
|
error: boolean;
|
||||||
|
persistentHint: boolean;
|
||||||
|
clearable: boolean;
|
||||||
|
row: boolean;
|
||||||
|
showPasswordToggle: boolean;
|
||||||
|
multiple: boolean;
|
||||||
|
chips: boolean;
|
||||||
|
modelValue: import("../../tipos/campo.js").CampoValor | import("../../tipos/campo.js").CampoValorMultiplo;
|
||||||
|
errorMessages: string | string[];
|
||||||
|
rows: number;
|
||||||
|
options: import("../../tipos/campo.js").CampoOpcaoBruta[];
|
||||||
|
density: import("../../tipos/campo.js").CampoDensidade;
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
||||||
}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
||||||
declare const _default: typeof __VLS_export;
|
declare const _default: typeof __VLS_export;
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
carregando: import("vue").Ref<boolean, boolean>;
|
carregando: import("vue").Ref<boolean, boolean>;
|
||||||
erro: import("vue").Ref<string | null, string | null>;
|
erro: import("vue").Ref<string | null, string | null>;
|
||||||
linhas: import("vue").Ref<unknown[], unknown[]>;
|
linhas: import("vue").Ref<unknown[], unknown[]>;
|
||||||
linhasPaginadas: import("vue").ComputedRef<unknown[]>;
|
|
||||||
quantidadeFiltrada: import("vue").ComputedRef<number>;
|
|
||||||
quantidade: import("vue").Ref<number, number>;
|
quantidade: import("vue").Ref<number, number>;
|
||||||
menuAberto: import("vue").Ref<number | null, number | null>;
|
menuAberto: import("vue").Ref<number | null, number | null>;
|
||||||
valorBusca: import("vue").Ref<string, string>;
|
valorBusca: import("vue").Ref<string, string>;
|
||||||
|
|
@ -30,7 +28,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
direcaoOrdenacao: import("vue").Ref<"desc" | "asc", "desc" | "asc">;
|
direcaoOrdenacao: import("vue").Ref<"desc" | "asc", "desc" | "asc">;
|
||||||
totalPaginas: import("vue").ComputedRef<number>;
|
totalPaginas: import("vue").ComputedRef<number>;
|
||||||
exibirBusca: import("vue").ComputedRef<boolean>;
|
exibirBusca: import("vue").ComputedRef<boolean>;
|
||||||
exibirFiltroAvancado: import("vue").ComputedRef<boolean>;
|
|
||||||
acoesCabecalho: import("vue").ComputedRef<{
|
acoesCabecalho: import("vue").ComputedRef<{
|
||||||
icone?: import("lucide-vue-next").LucideIcon;
|
icone?: import("lucide-vue-next").LucideIcon;
|
||||||
cor?: string;
|
cor?: string;
|
||||||
|
|
@ -53,23 +50,8 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
colunasInvisiveisEfetivas: import("vue").ComputedRef<EliColuna<any>[]>;
|
colunasInvisiveisEfetivas: import("vue").ComputedRef<EliColuna<any>[]>;
|
||||||
linhasExpandidas: import("vue").Ref<Record<number, boolean>, Record<number, boolean>>;
|
linhasExpandidas: import("vue").Ref<Record<number, boolean>, Record<number, boolean>>;
|
||||||
abrirModalColunas: () => void;
|
abrirModalColunas: () => void;
|
||||||
abrirModalFiltro: () => void;
|
|
||||||
fecharModalColunas: () => void;
|
fecharModalColunas: () => void;
|
||||||
salvarModalColunas: (cfg: EliTabelaColunasConfig) => void;
|
salvarModalColunas: (cfg: EliTabelaColunasConfig) => void;
|
||||||
modalFiltroAberto: import("vue").Ref<boolean, boolean>;
|
|
||||||
filtrosUi: import("vue").Ref<{
|
|
||||||
coluna: string | number | symbol;
|
|
||||||
valor: any;
|
|
||||||
}[], {
|
|
||||||
coluna: string | number | symbol;
|
|
||||||
valor: any;
|
|
||||||
}[] | {
|
|
||||||
coluna: string | number | symbol;
|
|
||||||
valor: any;
|
|
||||||
}[]>;
|
|
||||||
salvarFiltrosAvancados: (novo: any[]) => void;
|
|
||||||
limparFiltrosAvancados: () => void;
|
|
||||||
fecharModalFiltro: () => void;
|
|
||||||
alternarLinhaExpandida: (indice: number) => void;
|
alternarLinhaExpandida: (indice: number) => void;
|
||||||
alternarOrdenacao: (chave?: string) => void;
|
alternarOrdenacao: (chave?: string) => void;
|
||||||
atualizarBusca: (texto: string) => void;
|
atualizarBusca: (texto: string) => void;
|
||||||
|
|
@ -121,11 +103,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
required: false;
|
required: false;
|
||||||
default: boolean;
|
default: boolean;
|
||||||
};
|
};
|
||||||
exibirBotaoFiltroAvancado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
required: false;
|
|
||||||
default: boolean;
|
|
||||||
};
|
|
||||||
valorBusca: {
|
valorBusca: {
|
||||||
type: StringConstructor;
|
type: StringConstructor;
|
||||||
required: true;
|
required: true;
|
||||||
|
|
@ -155,11 +132,9 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
temAcoesCabecalho: import("vue").ComputedRef<boolean>;
|
temAcoesCabecalho: import("vue").ComputedRef<boolean>;
|
||||||
emitBuscar: (texto: string) => void;
|
emitBuscar: (texto: string) => void;
|
||||||
emitColunas: () => void;
|
emitColunas: () => void;
|
||||||
emitFiltroAvancado: () => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
||||||
buscar(valor: string): boolean;
|
buscar(valor: string): boolean;
|
||||||
colunas(): true;
|
colunas(): true;
|
||||||
filtroAvancado(): true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
||||||
exibirBusca: {
|
exibirBusca: {
|
||||||
type: BooleanConstructor;
|
type: BooleanConstructor;
|
||||||
|
|
@ -170,11 +145,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
required: false;
|
required: false;
|
||||||
default: boolean;
|
default: boolean;
|
||||||
};
|
};
|
||||||
exibirBotaoFiltroAvancado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
required: false;
|
|
||||||
default: boolean;
|
|
||||||
};
|
|
||||||
valorBusca: {
|
valorBusca: {
|
||||||
type: StringConstructor;
|
type: StringConstructor;
|
||||||
required: true;
|
required: true;
|
||||||
|
|
@ -203,10 +173,8 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
}>> & Readonly<{
|
}>> & Readonly<{
|
||||||
onBuscar?: ((valor: string) => any) | undefined;
|
onBuscar?: ((valor: string) => any) | undefined;
|
||||||
onColunas?: (() => any) | undefined;
|
onColunas?: (() => any) | undefined;
|
||||||
onFiltroAvancado?: (() => any) | undefined;
|
|
||||||
}>, {
|
}>, {
|
||||||
exibirBotaoColunas: boolean;
|
exibirBotaoColunas: boolean;
|
||||||
exibirBotaoFiltroAvancado: boolean;
|
|
||||||
}, {}, {
|
}, {}, {
|
||||||
EliTabelaCaixaDeBusca: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
EliTabelaCaixaDeBusca: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
||||||
modelo: {
|
modelo: {
|
||||||
|
|
@ -322,6 +290,7 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
ArrowUp: import("vue").FunctionalComponent<import("lucide-vue-next").LucideProps, {}, any, {}>;
|
ArrowUp: import("vue").FunctionalComponent<import("lucide-vue-next").LucideProps, {}, any, {}>;
|
||||||
ArrowDown: import("vue").FunctionalComponent<import("lucide-vue-next").LucideProps, {}, any, {}>;
|
ArrowDown: import("vue").FunctionalComponent<import("lucide-vue-next").LucideProps, {}, any, {}>;
|
||||||
isOrdenavel: (coluna: any) => boolean;
|
isOrdenavel: (coluna: any) => boolean;
|
||||||
|
obterClasseAlinhamento: (alinhamento?: string) => "eli-tabela__celula--direita" | "eli-tabela__celula--centro" | "eli-tabela__celula--esquerda";
|
||||||
emitAlternarOrdenacao: (chave: string) => void;
|
emitAlternarOrdenacao: (chave: string) => void;
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
||||||
alternarOrdenacao(chave: string): boolean;
|
alternarOrdenacao(chave: string): boolean;
|
||||||
|
|
@ -396,6 +365,9 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
}>, {
|
}>, {
|
||||||
ChevronRight: import("vue").FunctionalComponent<import("lucide-vue-next").LucideProps, {}, any, {}>;
|
ChevronRight: import("vue").FunctionalComponent<import("lucide-vue-next").LucideProps, {}, any, {}>;
|
||||||
ChevronDown: import("vue").FunctionalComponent<import("lucide-vue-next").LucideProps, {}, any, {}>;
|
ChevronDown: import("vue").FunctionalComponent<import("lucide-vue-next").LucideProps, {}, any, {}>;
|
||||||
|
obterClasseAlinhamento: (alinhamento?: string) => "eli-tabela__celula--direita" | "eli-tabela__celula--centro" | "eli-tabela__celula--esquerda";
|
||||||
|
obterMaxWidth: (largura?: number | string) => string | undefined;
|
||||||
|
obterTooltipCelula: (celula: unknown) => any;
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
||||||
colunas: {
|
colunas: {
|
||||||
type: PropType<Array<EliColuna<any>>>;
|
type: PropType<Array<EliColuna<any>>>;
|
||||||
|
|
@ -448,9 +420,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
dadosParaComponente: import("vue").ComputedRef<{
|
dadosParaComponente: import("vue").ComputedRef<{
|
||||||
texto: string;
|
texto: string;
|
||||||
acao?: () => void;
|
acao?: () => void;
|
||||||
} | {
|
|
||||||
texto: string;
|
|
||||||
acao?: () => void;
|
|
||||||
} | {
|
} | {
|
||||||
numero: number;
|
numero: number;
|
||||||
acao?: () => void;
|
acao?: () => void;
|
||||||
|
|
@ -490,9 +459,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
dadosParaComponente: import("vue").ComputedRef<{
|
dadosParaComponente: import("vue").ComputedRef<{
|
||||||
texto: string;
|
texto: string;
|
||||||
acao?: () => void;
|
acao?: () => void;
|
||||||
} | {
|
|
||||||
texto: string;
|
|
||||||
acao?: () => void;
|
|
||||||
} | {
|
} | {
|
||||||
numero: number;
|
numero: number;
|
||||||
acao?: () => void;
|
acao?: () => void;
|
||||||
|
|
@ -629,10 +595,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
type: PropType<EliTabelaColunasConfig>;
|
type: PropType<EliTabelaColunasConfig>;
|
||||||
required: true;
|
required: true;
|
||||||
};
|
};
|
||||||
colunas: {
|
|
||||||
type: PropType<Array<EliColuna<any>>>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
}>, {
|
||||||
visiveisLocal: import("vue").Ref<string[], string[]>;
|
visiveisLocal: import("vue").Ref<string[], string[]>;
|
||||||
invisiveisLocal: import("vue").Ref<string[], string[]>;
|
invisiveisLocal: import("vue").Ref<string[], string[]>;
|
||||||
|
|
@ -657,488 +619,10 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
type: PropType<EliTabelaColunasConfig>;
|
type: PropType<EliTabelaColunasConfig>;
|
||||||
required: true;
|
required: true;
|
||||||
};
|
};
|
||||||
colunas: {
|
|
||||||
type: PropType<Array<EliColuna<any>>>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
}>> & Readonly<{
|
||||||
onFechar?: (() => any) | undefined;
|
onFechar?: (() => any) | undefined;
|
||||||
onSalvar?: ((_config: EliTabelaColunasConfig) => any) | undefined;
|
onSalvar?: ((_config: EliTabelaColunasConfig) => any) | undefined;
|
||||||
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
||||||
EliTabelaModalFiltroAvancado: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
aberto: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
filtrosBase: {
|
|
||||||
type: PropType<Array<{
|
|
||||||
rotulo: string;
|
|
||||||
coluna: string | number | symbol;
|
|
||||||
operador: import("p-comuns").operadores | keyof typeof import("p-comuns").operadores;
|
|
||||||
entrada: import("../EliEntrada/tiposEntradas.js").ComponenteEntrada;
|
|
||||||
}>>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
modelo: {
|
|
||||||
type: PropType<Array<any>>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
linhas: import("vue").Ref<{
|
|
||||||
coluna: string | number | symbol;
|
|
||||||
entrada: readonly ["texto", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
limiteCaracteres?: number | undefined;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep" | undefined;
|
|
||||||
}] | readonly ["dataHora", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
modo?: "data" | "dataHora" | undefined;
|
|
||||||
limpavel?: boolean | undefined;
|
|
||||||
erro?: boolean | undefined;
|
|
||||||
mensagensErro?: string | string[] | undefined;
|
|
||||||
dica?: string | undefined;
|
|
||||||
dicaPersistente?: boolean | undefined;
|
|
||||||
min?: string | undefined;
|
|
||||||
max?: string | undefined;
|
|
||||||
densidade?: import("../../tipos/entrada.js").CampoDensidade | undefined;
|
|
||||||
variante?: import("../../tipos/entrada.js").CampoVariante | undefined;
|
|
||||||
}] | readonly ["numero", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
sufixo?: string | undefined;
|
|
||||||
prefixo?: string | undefined;
|
|
||||||
precisao?: number | undefined;
|
|
||||||
}];
|
|
||||||
operador: string;
|
|
||||||
valor: any;
|
|
||||||
}[], {
|
|
||||||
coluna: string | number | symbol;
|
|
||||||
entrada: import("../EliEntrada/tiposEntradas.js").ComponenteEntrada;
|
|
||||||
operador: string;
|
|
||||||
valor: any;
|
|
||||||
}[] | {
|
|
||||||
coluna: string | number | symbol;
|
|
||||||
entrada: readonly ["texto", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
limiteCaracteres?: number | undefined;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep" | undefined;
|
|
||||||
}] | readonly ["dataHora", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
modo?: "data" | "dataHora" | undefined;
|
|
||||||
limpavel?: boolean | undefined;
|
|
||||||
erro?: boolean | undefined;
|
|
||||||
mensagensErro?: string | string[] | undefined;
|
|
||||||
dica?: string | undefined;
|
|
||||||
dicaPersistente?: boolean | undefined;
|
|
||||||
min?: string | undefined;
|
|
||||||
max?: string | undefined;
|
|
||||||
densidade?: import("../../tipos/entrada.js").CampoDensidade | undefined;
|
|
||||||
variante?: import("../../tipos/entrada.js").CampoVariante | undefined;
|
|
||||||
}] | readonly ["numero", {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string | undefined;
|
|
||||||
sufixo?: string | undefined;
|
|
||||||
prefixo?: string | undefined;
|
|
||||||
precisao?: number | undefined;
|
|
||||||
}];
|
|
||||||
operador: string;
|
|
||||||
valor: any;
|
|
||||||
}[]>;
|
|
||||||
opcoesParaAdicionar: import("vue").ComputedRef<{
|
|
||||||
rotulo: string;
|
|
||||||
coluna: string | number | symbol;
|
|
||||||
operador: import("p-comuns").operadores | keyof typeof import("p-comuns").operadores;
|
|
||||||
entrada: import("../EliEntrada/tiposEntradas.js").ComponenteEntrada;
|
|
||||||
}[]>;
|
|
||||||
colunaParaAdicionar: import("vue").Ref<string, string>;
|
|
||||||
componenteEntrada: (entrada: import("../EliEntrada/tiposEntradas.js").ComponenteEntrada) => import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
limiteCaracteres?: number;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep";
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: {
|
|
||||||
[x: string]: unknown;
|
|
||||||
};
|
|
||||||
emit: ((event: "update:value", _v: string | null | undefined) => void) & ((event: "input", _v: string | null | undefined) => void) & ((event: "change", _v: string | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
|
||||||
localValue: import("vue").WritableComputedRef<string | null | undefined, string | null | undefined>;
|
|
||||||
inputHtmlType: import("vue").ComputedRef<"text" | "email" | "url">;
|
|
||||||
inputMode: import("vue").ComputedRef<string | undefined>;
|
|
||||||
onInput: (e: Event) => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: string | null | undefined) => true;
|
|
||||||
input: (_v: string | null | undefined) => true;
|
|
||||||
change: (_v: string | null | undefined) => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
limiteCaracteres?: number;
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep";
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
"onUpdate:value"?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onInput?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onChange?: ((_v: string | null | undefined) => any) | undefined;
|
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
value: string | null | undefined;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any> | import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<number | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
sufixo?: string;
|
|
||||||
prefixo?: string;
|
|
||||||
precisao?: number;
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: {
|
|
||||||
[x: string]: unknown;
|
|
||||||
};
|
|
||||||
emit: ((event: "update:value", _v: number | null | undefined) => void) & ((event: "input", _v: number | null | undefined) => void) & ((event: "change", _v: number | null | undefined) => void) & ((event: "focus") => void) & ((event: "blur") => void);
|
|
||||||
displayValue: import("vue").Ref<string, string>;
|
|
||||||
isInteiro: import("vue").ComputedRef<boolean>;
|
|
||||||
onUpdateModelValue: (texto: string) => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: number | null | undefined) => true;
|
|
||||||
input: (_v: number | null | undefined) => true;
|
|
||||||
change: (_v: number | null | undefined) => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<number | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
sufixo?: string;
|
|
||||||
prefixo?: string;
|
|
||||||
precisao?: number;
|
|
||||||
}>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
"onUpdate:value"?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onInput?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onChange?: ((_v: number | null | undefined) => any) | undefined;
|
|
||||||
onFocus?: (() => any) | undefined;
|
|
||||||
onBlur?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
value: number | null | undefined;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any> | import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../../tipos/entrada.js").CampoDensidade;
|
|
||||||
variante?: import("../../tipos/entrada.js").CampoVariante;
|
|
||||||
}>;
|
|
||||||
required: false;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
modelValue: {
|
|
||||||
type: PropType<string | null>;
|
|
||||||
default: null;
|
|
||||||
};
|
|
||||||
modo: {
|
|
||||||
type: PropType<"data" | "dataHora" | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
rotulo: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
placeholder: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
desabilitado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
limpavel: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
erro: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
mensagensErro: {
|
|
||||||
type: PropType<string | string[]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dica: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dicaPersistente: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
densidade: {
|
|
||||||
type: PropType<import("../../tipos/entrada.js").CampoDensidade>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
variante: {
|
|
||||||
type: PropType<import("../../tipos/entrada.js").CampoVariante>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
min: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
max: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
attrs: {
|
|
||||||
[x: string]: unknown;
|
|
||||||
};
|
|
||||||
valor: import("vue").WritableComputedRef<string, string>;
|
|
||||||
tipoInput: import("vue").ComputedRef<"date" | "datetime-local">;
|
|
||||||
minLocal: import("vue").ComputedRef<string | undefined>;
|
|
||||||
maxLocal: import("vue").ComputedRef<string | undefined>;
|
|
||||||
opcoesEfetivas: import("vue").ComputedRef<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../../tipos/entrada.js").CampoDensidade;
|
|
||||||
variante?: import("../../tipos/entrada.js").CampoVariante;
|
|
||||||
}>;
|
|
||||||
desabilitadoEfetivo: import("vue").ComputedRef<boolean>;
|
|
||||||
emitCompatFocus: () => void;
|
|
||||||
emitCompatBlur: () => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
"update:value": (_v: string | null) => true;
|
|
||||||
input: (_v: string | null) => true;
|
|
||||||
change: (_v: string | null) => true;
|
|
||||||
"update:modelValue": (_v: string | null) => true;
|
|
||||||
alterar: (_v: string | null) => true;
|
|
||||||
foco: () => true;
|
|
||||||
desfoco: () => true;
|
|
||||||
focus: () => true;
|
|
||||||
blur: () => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
value: {
|
|
||||||
type: PropType<string | null | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
opcoes: {
|
|
||||||
type: PropType<{
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../../tipos/entrada.js").CampoDensidade;
|
|
||||||
variante?: import("../../tipos/entrada.js").CampoVariante;
|
|
||||||
}>;
|
|
||||||
required: false;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
modelValue: {
|
|
||||||
type: PropType<string | null>;
|
|
||||||
default: null;
|
|
||||||
};
|
|
||||||
modo: {
|
|
||||||
type: PropType<"data" | "dataHora" | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
rotulo: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
placeholder: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
desabilitado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
limpavel: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
erro: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
mensagensErro: {
|
|
||||||
type: PropType<string | string[]>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dica: {
|
|
||||||
type: StringConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
dicaPersistente: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
densidade: {
|
|
||||||
type: PropType<import("../../tipos/entrada.js").CampoDensidade>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
variante: {
|
|
||||||
type: PropType<import("../../tipos/entrada.js").CampoVariante>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
min: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
max: {
|
|
||||||
type: PropType<string | undefined>;
|
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
"onUpdate:value"?: ((_v: string | null) => any) | undefined;
|
|
||||||
onInput?: ((_v: string | null) => any) | undefined;
|
|
||||||
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;
|
|
||||||
onFoco?: (() => any) | undefined;
|
|
||||||
onDesfoco?: (() => any) | undefined;
|
|
||||||
}>, {
|
|
||||||
modo: "data" | "dataHora" | undefined;
|
|
||||||
limpavel: boolean;
|
|
||||||
erro: boolean;
|
|
||||||
mensagensErro: string | string[];
|
|
||||||
dica: string;
|
|
||||||
dicaPersistente: boolean;
|
|
||||||
min: string | undefined;
|
|
||||||
max: string | undefined;
|
|
||||||
densidade: import("../../tipos/entrada.js").CampoDensidade;
|
|
||||||
variante: import("../../tipos/entrada.js").CampoVariante;
|
|
||||||
opcoes: {
|
|
||||||
rotulo: string;
|
|
||||||
placeholder?: string;
|
|
||||||
} & {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
densidade?: import("../../tipos/entrada.js").CampoDensidade;
|
|
||||||
variante?: import("../../tipos/entrada.js").CampoVariante;
|
|
||||||
};
|
|
||||||
value: string | null | undefined;
|
|
||||||
placeholder: string;
|
|
||||||
rotulo: string;
|
|
||||||
modelValue: string | null;
|
|
||||||
desabilitado: boolean;
|
|
||||||
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
||||||
opcoesEntrada: (entrada: import("../EliEntrada/tiposEntradas.js").ComponenteEntrada) => any;
|
|
||||||
adicionar: () => void;
|
|
||||||
remover: (idx: number) => void;
|
|
||||||
emitFechar: () => void;
|
|
||||||
emitSalvar: () => void;
|
|
||||||
emitLimpar: () => void;
|
|
||||||
rotuloDoFiltro: (f: {
|
|
||||||
rotulo: string;
|
|
||||||
coluna: string | number | symbol;
|
|
||||||
operador: import("p-comuns").operadores | keyof typeof import("p-comuns").operadores;
|
|
||||||
entrada: import("../EliEntrada/tiposEntradas.js").ComponenteEntrada;
|
|
||||||
}) => string;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
||||||
fechar: () => true;
|
|
||||||
limpar: () => true;
|
|
||||||
salvar: (_linhas: any[]) => true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
||||||
aberto: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
filtrosBase: {
|
|
||||||
type: PropType<Array<{
|
|
||||||
rotulo: string;
|
|
||||||
coluna: string | number | symbol;
|
|
||||||
operador: import("p-comuns").operadores | keyof typeof import("p-comuns").operadores;
|
|
||||||
entrada: import("../EliEntrada/tiposEntradas.js").ComponenteEntrada;
|
|
||||||
}>>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
modelo: {
|
|
||||||
type: PropType<Array<any>>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
|
||||||
onFechar?: (() => any) | undefined;
|
|
||||||
onSalvar?: ((_linhas: any[]) => any) | undefined;
|
|
||||||
onLimpar?: (() => any) | undefined;
|
|
||||||
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
||||||
}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
||||||
declare const _default: typeof __VLS_export;
|
declare const _default: typeof __VLS_export;
|
||||||
export default _default;
|
export default _default;
|
||||||
|
|
@ -44,6 +44,9 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
}>, {
|
}>, {
|
||||||
ChevronRight: import("vue").FunctionalComponent<import("lucide-vue-next").LucideProps, {}, any, {}>;
|
ChevronRight: import("vue").FunctionalComponent<import("lucide-vue-next").LucideProps, {}, any, {}>;
|
||||||
ChevronDown: import("vue").FunctionalComponent<import("lucide-vue-next").LucideProps, {}, any, {}>;
|
ChevronDown: import("vue").FunctionalComponent<import("lucide-vue-next").LucideProps, {}, any, {}>;
|
||||||
|
obterClasseAlinhamento: (alinhamento?: string) => "eli-tabela__celula--direita" | "eli-tabela__celula--centro" | "eli-tabela__celula--esquerda";
|
||||||
|
obterMaxWidth: (largura?: number | string) => string | undefined;
|
||||||
|
obterTooltipCelula: (celula: unknown) => any;
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
||||||
colunas: {
|
colunas: {
|
||||||
type: PropType<Array<EliColuna<any>>>;
|
type: PropType<Array<EliColuna<any>>>;
|
||||||
|
|
@ -96,9 +99,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
dadosParaComponente: import("vue").ComputedRef<{
|
dadosParaComponente: import("vue").ComputedRef<{
|
||||||
texto: string;
|
texto: string;
|
||||||
acao?: () => void;
|
acao?: () => void;
|
||||||
} | {
|
|
||||||
texto: string;
|
|
||||||
acao?: () => void;
|
|
||||||
} | {
|
} | {
|
||||||
numero: number;
|
numero: number;
|
||||||
acao?: () => void;
|
acao?: () => void;
|
||||||
|
|
@ -138,9 +138,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
dadosParaComponente: import("vue").ComputedRef<{
|
dadosParaComponente: import("vue").ComputedRef<{
|
||||||
texto: string;
|
texto: string;
|
||||||
acao?: () => void;
|
acao?: () => void;
|
||||||
} | {
|
|
||||||
texto: string;
|
|
||||||
acao?: () => void;
|
|
||||||
} | {
|
} | {
|
||||||
numero: number;
|
numero: number;
|
||||||
acao?: () => void;
|
acao?: () => void;
|
||||||
|
|
@ -9,11 +9,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
required: false;
|
required: false;
|
||||||
default: boolean;
|
default: boolean;
|
||||||
};
|
};
|
||||||
exibirBotaoFiltroAvancado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
required: false;
|
|
||||||
default: boolean;
|
|
||||||
};
|
|
||||||
valorBusca: {
|
valorBusca: {
|
||||||
type: StringConstructor;
|
type: StringConstructor;
|
||||||
required: true;
|
required: true;
|
||||||
|
|
@ -31,11 +26,9 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
temAcoesCabecalho: import("vue").ComputedRef<boolean>;
|
temAcoesCabecalho: import("vue").ComputedRef<boolean>;
|
||||||
emitBuscar: (texto: string) => void;
|
emitBuscar: (texto: string) => void;
|
||||||
emitColunas: () => void;
|
emitColunas: () => void;
|
||||||
emitFiltroAvancado: () => void;
|
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
||||||
buscar(valor: string): boolean;
|
buscar(valor: string): boolean;
|
||||||
colunas(): true;
|
colunas(): true;
|
||||||
filtroAvancado(): true;
|
|
||||||
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
||||||
exibirBusca: {
|
exibirBusca: {
|
||||||
type: BooleanConstructor;
|
type: BooleanConstructor;
|
||||||
|
|
@ -46,11 +39,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
required: false;
|
required: false;
|
||||||
default: boolean;
|
default: boolean;
|
||||||
};
|
};
|
||||||
exibirBotaoFiltroAvancado: {
|
|
||||||
type: BooleanConstructor;
|
|
||||||
required: false;
|
|
||||||
default: boolean;
|
|
||||||
};
|
|
||||||
valorBusca: {
|
valorBusca: {
|
||||||
type: StringConstructor;
|
type: StringConstructor;
|
||||||
required: true;
|
required: true;
|
||||||
|
|
@ -67,10 +55,8 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
}>> & Readonly<{
|
}>> & Readonly<{
|
||||||
onBuscar?: ((valor: string) => any) | undefined;
|
onBuscar?: ((valor: string) => any) | undefined;
|
||||||
onColunas?: (() => any) | undefined;
|
onColunas?: (() => any) | undefined;
|
||||||
onFiltroAvancado?: (() => any) | undefined;
|
|
||||||
}>, {
|
}>, {
|
||||||
exibirBotaoColunas: boolean;
|
exibirBotaoColunas: boolean;
|
||||||
exibirBotaoFiltroAvancado: boolean;
|
|
||||||
}, {}, {
|
}, {}, {
|
||||||
EliTabelaCaixaDeBusca: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
EliTabelaCaixaDeBusca: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
||||||
modelo: {
|
modelo: {
|
||||||
|
|
@ -29,9 +29,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
dadosParaComponente: import("vue").ComputedRef<{
|
dadosParaComponente: import("vue").ComputedRef<{
|
||||||
texto: string;
|
texto: string;
|
||||||
acao?: () => void;
|
acao?: () => void;
|
||||||
} | {
|
|
||||||
texto: string;
|
|
||||||
acao?: () => void;
|
|
||||||
} | {
|
} | {
|
||||||
numero: number;
|
numero: number;
|
||||||
acao?: () => void;
|
acao?: () => void;
|
||||||
|
|
@ -25,6 +25,7 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
ArrowUp: import("vue").FunctionalComponent<import("lucide-vue-next").LucideProps, {}, any, {}>;
|
ArrowUp: import("vue").FunctionalComponent<import("lucide-vue-next").LucideProps, {}, any, {}>;
|
||||||
ArrowDown: import("vue").FunctionalComponent<import("lucide-vue-next").LucideProps, {}, any, {}>;
|
ArrowDown: import("vue").FunctionalComponent<import("lucide-vue-next").LucideProps, {}, any, {}>;
|
||||||
isOrdenavel: (coluna: any) => boolean;
|
isOrdenavel: (coluna: any) => boolean;
|
||||||
|
obterClasseAlinhamento: (alinhamento?: string) => "eli-tabela__celula--direita" | "eli-tabela__celula--centro" | "eli-tabela__celula--esquerda";
|
||||||
emitAlternarOrdenacao: (chave: string) => void;
|
emitAlternarOrdenacao: (chave: string) => void;
|
||||||
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
||||||
alternarOrdenacao(chave: string): boolean;
|
alternarOrdenacao(chave: string): boolean;
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { PropType } from "vue";
|
import { PropType } from "vue";
|
||||||
import type { EliTabelaColunasConfig } from "./colunasStorage";
|
import type { EliTabelaColunasConfig } from "./colunasStorage";
|
||||||
import type { EliColuna } from "./types-eli-tabela";
|
|
||||||
type OrigemLista = "visiveis" | "invisiveis";
|
type OrigemLista = "visiveis" | "invisiveis";
|
||||||
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
||||||
aberto: {
|
aberto: {
|
||||||
|
|
@ -15,10 +14,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
type: PropType<EliTabelaColunasConfig>;
|
type: PropType<EliTabelaColunasConfig>;
|
||||||
required: true;
|
required: true;
|
||||||
};
|
};
|
||||||
colunas: {
|
|
||||||
type: PropType<Array<EliColuna<any>>>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>, {
|
}>, {
|
||||||
visiveisLocal: import("vue").Ref<string[], string[]>;
|
visiveisLocal: import("vue").Ref<string[], string[]>;
|
||||||
invisiveisLocal: import("vue").Ref<string[], string[]>;
|
invisiveisLocal: import("vue").Ref<string[], string[]>;
|
||||||
|
|
@ -43,10 +38,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
type: PropType<EliTabelaColunasConfig>;
|
type: PropType<EliTabelaColunasConfig>;
|
||||||
required: true;
|
required: true;
|
||||||
};
|
};
|
||||||
colunas: {
|
|
||||||
type: PropType<Array<EliColuna<any>>>;
|
|
||||||
required: true;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{
|
}>> & Readonly<{
|
||||||
onFechar?: (() => any) | undefined;
|
onFechar?: (() => any) | undefined;
|
||||||
onSalvar?: ((_config: EliTabelaColunasConfig) => any) | undefined;
|
onSalvar?: ((_config: EliTabelaColunasConfig) => any) | undefined;
|
||||||
|
|
@ -11,9 +11,6 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
||||||
dadosParaComponente: import("vue").ComputedRef<{
|
dadosParaComponente: import("vue").ComputedRef<{
|
||||||
texto: string;
|
texto: string;
|
||||||
acao?: () => void;
|
acao?: () => void;
|
||||||
} | {
|
|
||||||
texto: string;
|
|
||||||
acao?: () => void;
|
|
||||||
} | {
|
} | {
|
||||||
numero: number;
|
numero: number;
|
||||||
acao?: () => void;
|
acao?: () => void;
|
||||||
|
|
@ -13,20 +13,6 @@ export declare const registryTabelaCelulas: {
|
||||||
type: import("vue").PropType<import("./tiposTabelaCelulas").TiposTabelaCelulas["textoSimples"]>;
|
type: import("vue").PropType<import("./tiposTabelaCelulas").TiposTabelaCelulas["textoSimples"]>;
|
||||||
};
|
};
|
||||||
}>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
}>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
||||||
readonly textoTruncado: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
||||||
dados: {
|
|
||||||
type: import("vue").PropType<import("./tiposTabelaCelulas").TiposTabelaCelulas["textoTruncado"]>;
|
|
||||||
};
|
|
||||||
}>, {
|
|
||||||
dados: {
|
|
||||||
texto: string;
|
|
||||||
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["textoTruncado"]>;
|
|
||||||
};
|
|
||||||
}>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
||||||
readonly numero: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
readonly numero: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
||||||
dados: {
|
dados: {
|
||||||
type: import("vue").PropType<import("./tiposTabelaCelulas").TiposTabelaCelulas["numero"]>;
|
type: import("vue").PropType<import("./tiposTabelaCelulas").TiposTabelaCelulas["numero"]>;
|
||||||
|
|
@ -6,10 +6,6 @@ export type TiposTabelaCelulas = {
|
||||||
texto: string;
|
texto: string;
|
||||||
acao?: () => void;
|
acao?: () => void;
|
||||||
};
|
};
|
||||||
textoTruncado: {
|
|
||||||
texto: string;
|
|
||||||
acao?: () => void;
|
|
||||||
};
|
|
||||||
numero: {
|
numero: {
|
||||||
numero: number;
|
numero: number;
|
||||||
acao?: () => void;
|
acao?: () => void;
|
||||||
|
|
@ -1,31 +1,38 @@
|
||||||
import type { tipoResposta } from "p-respostas";
|
import type { tipoResposta } from "p-respostas";
|
||||||
import type { LucideIcon } from "lucide-vue-next";
|
import type { LucideIcon } from "lucide-vue-next";
|
||||||
import type { TipoTabelaCelula, TiposTabelaCelulas } from "./celulas/tiposTabelaCelulas";
|
import type { TipoTabelaCelula, TiposTabelaCelulas } from "./celulas/tiposTabelaCelulas";
|
||||||
import { operadores, zFiltro } from "p-comuns";
|
|
||||||
import { ComponenteEntrada } from "../EliEntrada/tiposEntradas";
|
|
||||||
export type tipoFiltro = ReturnType<(typeof zFiltro)["parse"]>;
|
|
||||||
export type ComponenteCelulaBase<T extends TipoTabelaCelula> = readonly [T, TiposTabelaCelulas[T]];
|
export type ComponenteCelulaBase<T extends TipoTabelaCelula> = readonly [T, TiposTabelaCelulas[T]];
|
||||||
export type ComponenteCelula = {
|
export type ComponenteCelula = {
|
||||||
[K in TipoTabelaCelula]: ComponenteCelulaBase<K>;
|
[K in TipoTabelaCelula]: ComponenteCelulaBase<K>;
|
||||||
}[TipoTabelaCelula];
|
}[TipoTabelaCelula];
|
||||||
export declare const celulaTabela: <T extends TipoTabelaCelula>(tipo: T, dados: TiposTabelaCelulas[T]) => ComponenteCelulaBase<T>;
|
export declare const celulaTabela: <T extends TipoTabelaCelula>(tipo: T, dados: TiposTabelaCelulas[T]) => ComponenteCelulaBase<T>;
|
||||||
export type { TipoTabelaCelula, TiposTabelaCelulas };
|
export type { TipoTabelaCelula, TiposTabelaCelulas };
|
||||||
|
export type EliAlinhamentoColuna = "esquerda" | "centro" | "direita";
|
||||||
export type EliColuna<T> = {
|
export type EliColuna<T> = {
|
||||||
/** Texto exibido no cabeçalho da coluna. */
|
/** Texto exibido no cabeçalho da coluna. */
|
||||||
rotulo: string;
|
rotulo: string;
|
||||||
/** Função responsável por renderizar o conteúdo da célula. */
|
/** Função responsável por renderizar o conteúdo da célula. */
|
||||||
celula: (linha: T) => ComponenteCelula;
|
celula: (linha: T) => ComponenteCelula;
|
||||||
/** Ação opcional disparada ao clicar na célula. */
|
/** Ação opcional disparada ao clicar na célula. */
|
||||||
|
acao?: () => void;
|
||||||
|
/** Alinhamento do conteúdo da coluna (cabeçalho e células). */
|
||||||
|
alinhamento?: EliAlinhamentoColuna;
|
||||||
|
/**
|
||||||
|
* Quando `true`, tenta truncar (ellipsis) conteúdos textuais longos.
|
||||||
|
* Observação: o tooltip automático só é aplicado quando o conteúdo renderizado
|
||||||
|
* da célula é um `string`/`number`.
|
||||||
|
*/
|
||||||
|
truncar?: boolean;
|
||||||
|
/**
|
||||||
|
* Largura máxima usada quando `truncar` estiver ativo.
|
||||||
|
* Exemplos: `240` (px), `"18rem"`, `"30ch"`.
|
||||||
|
*/
|
||||||
|
largura_maxima?: number | string;
|
||||||
/**
|
/**
|
||||||
* Campo de ordenação associado à coluna. Caso informado, a coluna passa a
|
* Campo de ordenação associado à coluna. Caso informado, a coluna passa a
|
||||||
* exibir controles de ordenação e utiliza o valor como chave para o backend.
|
* exibir controles de ordenação e utiliza o valor como chave para o backend.
|
||||||
*/
|
*/
|
||||||
coluna_ordem?: keyof T;
|
coluna_ordem?: keyof T;
|
||||||
/**
|
|
||||||
* indica que a coluna será visivel, se false incia em detalhe
|
|
||||||
* Caso já tenha salvo a propriedade de visibilidade será adotado a propriedade salva
|
|
||||||
*/
|
|
||||||
visivel: boolean;
|
|
||||||
};
|
};
|
||||||
export type EliConsultaPaginada<T> = {
|
export type EliConsultaPaginada<T> = {
|
||||||
/** Registros retornados na consulta. */
|
/** Registros retornados na consulta. */
|
||||||
|
|
@ -69,7 +76,6 @@ export type EliTabelaConsulta<T> = {
|
||||||
* ordenação (`coluna_ordem`/`direcao_ordem`) e paginação (`offSet`/`limit`).
|
* ordenação (`coluna_ordem`/`direcao_ordem`) e paginação (`offSet`/`limit`).
|
||||||
*/
|
*/
|
||||||
consulta: (parametrosConsulta?: {
|
consulta: (parametrosConsulta?: {
|
||||||
filtros?: tipoFiltro[];
|
|
||||||
coluna_ordem?: keyof T;
|
coluna_ordem?: keyof T;
|
||||||
direcao_ordem?: "asc" | "desc";
|
direcao_ordem?: "asc" | "desc";
|
||||||
offSet?: number;
|
offSet?: number;
|
||||||
|
|
@ -97,11 +103,4 @@ export type EliTabelaConsulta<T> = {
|
||||||
/** Função executada ao clicar no botão. */
|
/** Função executada ao clicar no botão. */
|
||||||
acao: () => void;
|
acao: () => void;
|
||||||
}[];
|
}[];
|
||||||
/** configuração para aplicação dos filtros padrões */
|
|
||||||
filtroAvancado?: {
|
|
||||||
rotulo: string;
|
|
||||||
coluna: keyof T;
|
|
||||||
operador: operadores | keyof typeof operadores;
|
|
||||||
entrada: ComponenteEntrada;
|
|
||||||
}[];
|
|
||||||
};
|
};
|
||||||
8
dist/types/index.d.ts
vendored
8
dist/types/index.d.ts
vendored
|
|
@ -3,14 +3,16 @@ import "./styles/eli-vue-fonts.css";
|
||||||
import { EliOlaMundo } from "./componentes/ola_mundo";
|
import { EliOlaMundo } from "./componentes/ola_mundo";
|
||||||
import { EliBotao } from "./componentes/botao";
|
import { EliBotao } from "./componentes/botao";
|
||||||
import { EliBadge } from "./componentes/indicador";
|
import { EliBadge } from "./componentes/indicador";
|
||||||
|
import { EliInput } from "./componentes/campo";
|
||||||
import { EliCartao } from "./componentes/cartao";
|
import { EliCartao } from "./componentes/cartao";
|
||||||
import { EliTabela } from "./componentes/EliTabela";
|
import { EliDataHora } from "./componentes/data_hora";
|
||||||
import { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora } from "./componentes/EliEntrada";
|
import { EliTabela } from "./components/eli/EliTabela";
|
||||||
export { EliOlaMundo };
|
export { EliOlaMundo };
|
||||||
export { EliBotao };
|
export { EliBotao };
|
||||||
export { EliBadge };
|
export { EliBadge };
|
||||||
|
export { EliInput };
|
||||||
export { EliCartao };
|
export { EliCartao };
|
||||||
|
export { EliDataHora };
|
||||||
export { EliTabela };
|
export { EliTabela };
|
||||||
export { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora };
|
|
||||||
declare const EliVue: Plugin;
|
declare const EliVue: Plugin;
|
||||||
export default EliVue;
|
export default EliVue;
|
||||||
|
|
|
||||||
19
dist/types/tipos/campo.d.ts
vendored
Normal file
19
dist/types/tipos/campo.d.ts
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
/**
|
||||||
|
* Tipos do componente EliInput (campo).
|
||||||
|
*/
|
||||||
|
export type CampoValor = string | number | boolean | null;
|
||||||
|
export type CampoValorMultiplo = CampoValor[];
|
||||||
|
export type CampoOpcao<TValor extends CampoValor = CampoValor> = {
|
||||||
|
label: string;
|
||||||
|
value: TValor;
|
||||||
|
disabled?: boolean;
|
||||||
|
};
|
||||||
|
export type CampoOpcaoBruta<TValor extends CampoValor = CampoValor> = TValor | {
|
||||||
|
label?: string;
|
||||||
|
value: TValor;
|
||||||
|
disabled?: boolean;
|
||||||
|
};
|
||||||
|
export type CampoVariante = "outlined" | "filled" | "plain" | "solo" | "solo-filled" | "solo-inverted" | "underlined";
|
||||||
|
export type CampoDensidade = "default" | "comfortable" | "compact";
|
||||||
|
export type CampoTipoNumerico = "numericoInteiro" | "numericoDecimal" | "numericoMoeda" | "porcentagem";
|
||||||
|
export type CampoTipo = "text" | "password" | "email" | "search" | "url" | "textarea" | "radio" | "checkbox" | "telefone" | "cpfCnpj" | "cep" | "select" | CampoTipoNumerico;
|
||||||
9
dist/types/tipos/entrada.d.ts
vendored
9
dist/types/tipos/entrada.d.ts
vendored
|
|
@ -1,9 +0,0 @@
|
||||||
/**
|
|
||||||
* Tipos compartilhados para componentes de entrada (EliEntrada*).
|
|
||||||
*
|
|
||||||
* OBS: Estes tipos existiam anteriormente em `tipos/campo.ts` junto do componente
|
|
||||||
* `EliInput`. Como o `EliInput` foi removido, mantemos aqui apenas o que ainda
|
|
||||||
* é relevante para padronização visual/props do Vuetify.
|
|
||||||
*/
|
|
||||||
export type CampoVariante = "outlined" | "filled" | "plain" | "solo" | "solo-filled" | "solo-inverted" | "underlined";
|
|
||||||
export type CampoDensidade = "default" | "comfortable" | "compact";
|
|
||||||
2
dist/types/tipos/index.d.ts
vendored
2
dist/types/tipos/index.d.ts
vendored
|
|
@ -1,4 +1,4 @@
|
||||||
export * from "./botao";
|
export * from "./botao";
|
||||||
export * from "./cartao";
|
export * from "./cartao";
|
||||||
export * from "./entrada";
|
export * from "./campo";
|
||||||
export * from "./indicador";
|
export * from "./indicador";
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "eli-vue",
|
"name": "eli-vue",
|
||||||
"version": "0.1.71",
|
"version": "0.1.48",
|
||||||
"private": false,
|
"private": false,
|
||||||
"main": "./dist/eli-vue.umd.js",
|
"main": "./dist/eli-vue.umd.js",
|
||||||
"module": "./dist/eli-vue.es.js",
|
"module": "./dist/eli-vue.es.js",
|
||||||
|
|
@ -35,12 +35,8 @@
|
||||||
"vuetify": "^3.11.2"
|
"vuetify": "^3.11.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cross-fetch": "^4.1.0",
|
|
||||||
"dayjs": "^1.11.19",
|
"dayjs": "^1.11.19",
|
||||||
"lucide-vue-next": "^0.563.0",
|
"lucide-vue-next": "^0.563.0",
|
||||||
"p-comuns": "git+https://git2.idz.one/publico/_comuns.git",
|
"p-respostas": "git+https://git2.idz.one/publico/_respostas.git"
|
||||||
"p-respostas": "git+https://git2.idz.one/publico/_respostas.git",
|
|
||||||
"uuid": "^13.0.0",
|
|
||||||
"zod": "^4.3.6"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
40
pnpm-lock.yaml
generated
40
pnpm-lock.yaml
generated
|
|
@ -8,27 +8,15 @@ importers:
|
||||||
|
|
||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
cross-fetch:
|
|
||||||
specifier: ^4.1.0
|
|
||||||
version: 4.1.0
|
|
||||||
dayjs:
|
dayjs:
|
||||||
specifier: ^1.11.19
|
specifier: ^1.11.19
|
||||||
version: 1.11.19
|
version: 1.11.19
|
||||||
lucide-vue-next:
|
lucide-vue-next:
|
||||||
specifier: ^0.563.0
|
specifier: ^0.563.0
|
||||||
version: 0.563.0(vue@3.5.25(typescript@5.9.3))
|
version: 0.563.0(vue@3.5.25(typescript@5.9.3))
|
||||||
p-comuns:
|
|
||||||
specifier: git+https://git2.idz.one/publico/_comuns.git
|
|
||||||
version: git+https://git2.idz.one/publico/_comuns.git#d783fa12940a5b1bcafa5038bd1c49c3f5f9b7fc(cross-fetch@4.1.0)(dayjs@1.11.19)(uuid@13.0.0)(zod@4.3.6)
|
|
||||||
p-respostas:
|
p-respostas:
|
||||||
specifier: git+https://git2.idz.one/publico/_respostas.git
|
specifier: git+https://git2.idz.one/publico/_respostas.git
|
||||||
version: git+https://git2.idz.one/publico/_respostas.git#8c24d790ace7255404745dcbdf12c5396e8b9843(cross-fetch@4.1.0)(dayjs@1.11.19)(uuid@13.0.0)
|
version: git+https://git2.idz.one/publico/_respostas.git#8c24d790ace7255404745dcbdf12c5396e8b9843(cross-fetch@4.1.0)(dayjs@1.11.19)(uuid@11.1.0)
|
||||||
uuid:
|
|
||||||
specifier: ^13.0.0
|
|
||||||
version: 13.0.0
|
|
||||||
zod:
|
|
||||||
specifier: ^4.3.6
|
|
||||||
version: 4.3.6
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@mdi/font':
|
'@mdi/font':
|
||||||
specifier: ^7.4.47
|
specifier: ^7.4.47
|
||||||
|
|
@ -683,8 +671,8 @@ packages:
|
||||||
resolution: {integrity: sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==}
|
resolution: {integrity: sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
uuid@13.0.0:
|
uuid@11.1.0:
|
||||||
resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==}
|
resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
vite-plugin-vuetify@2.1.2:
|
vite-plugin-vuetify@2.1.2:
|
||||||
|
|
@ -776,9 +764,6 @@ packages:
|
||||||
zod@4.1.4:
|
zod@4.1.4:
|
||||||
resolution: {integrity: sha512-2YqJuWkU6IIK9qcE4k1lLLhyZ6zFw7XVRdQGpV97jEIZwTrscUw+DY31Xczd8nwaoksyJUIxCojZXwckJovWxA==}
|
resolution: {integrity: sha512-2YqJuWkU6IIK9qcE4k1lLLhyZ6zFw7XVRdQGpV97jEIZwTrscUw+DY31Xczd8nwaoksyJUIxCojZXwckJovWxA==}
|
||||||
|
|
||||||
zod@4.3.6:
|
|
||||||
resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==}
|
|
||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
'@babel/helper-string-parser@7.27.1': {}
|
'@babel/helper-string-parser@7.27.1': {}
|
||||||
|
|
@ -1212,23 +1197,16 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
whatwg-url: 5.0.0
|
whatwg-url: 5.0.0
|
||||||
|
|
||||||
p-comuns@git+https://git2.idz.one/publico/_comuns.git#d783fa12940a5b1bcafa5038bd1c49c3f5f9b7fc(cross-fetch@4.1.0)(dayjs@1.11.19)(uuid@13.0.0)(zod@4.1.4):
|
p-comuns@git+https://git2.idz.one/publico/_comuns.git#d783fa12940a5b1bcafa5038bd1c49c3f5f9b7fc(cross-fetch@4.1.0)(dayjs@1.11.19)(uuid@11.1.0)(zod@4.1.4):
|
||||||
dependencies:
|
dependencies:
|
||||||
cross-fetch: 4.1.0
|
cross-fetch: 4.1.0
|
||||||
dayjs: 1.11.19
|
dayjs: 1.11.19
|
||||||
uuid: 13.0.0
|
uuid: 11.1.0
|
||||||
zod: 4.1.4
|
zod: 4.1.4
|
||||||
|
|
||||||
p-comuns@git+https://git2.idz.one/publico/_comuns.git#d783fa12940a5b1bcafa5038bd1c49c3f5f9b7fc(cross-fetch@4.1.0)(dayjs@1.11.19)(uuid@13.0.0)(zod@4.3.6):
|
p-respostas@git+https://git2.idz.one/publico/_respostas.git#8c24d790ace7255404745dcbdf12c5396e8b9843(cross-fetch@4.1.0)(dayjs@1.11.19)(uuid@11.1.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
cross-fetch: 4.1.0
|
p-comuns: git+https://git2.idz.one/publico/_comuns.git#d783fa12940a5b1bcafa5038bd1c49c3f5f9b7fc(cross-fetch@4.1.0)(dayjs@1.11.19)(uuid@11.1.0)(zod@4.1.4)
|
||||||
dayjs: 1.11.19
|
|
||||||
uuid: 13.0.0
|
|
||||||
zod: 4.3.6
|
|
||||||
|
|
||||||
p-respostas@git+https://git2.idz.one/publico/_respostas.git#8c24d790ace7255404745dcbdf12c5396e8b9843(cross-fetch@4.1.0)(dayjs@1.11.19)(uuid@13.0.0):
|
|
||||||
dependencies:
|
|
||||||
p-comuns: git+https://git2.idz.one/publico/_comuns.git#d783fa12940a5b1bcafa5038bd1c49c3f5f9b7fc(cross-fetch@4.1.0)(dayjs@1.11.19)(uuid@13.0.0)(zod@4.1.4)
|
|
||||||
zod: 4.1.4
|
zod: 4.1.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- cross-fetch
|
- cross-fetch
|
||||||
|
|
@ -1309,7 +1287,7 @@ snapshots:
|
||||||
|
|
||||||
upath@2.0.1: {}
|
upath@2.0.1: {}
|
||||||
|
|
||||||
uuid@13.0.0: {}
|
uuid@11.1.0: {}
|
||||||
|
|
||||||
vite-plugin-vuetify@2.1.2(vite@6.4.1(@types/node@24.10.1)(sass@1.94.2))(vue@3.5.25(typescript@5.9.3))(vuetify@3.11.2):
|
vite-plugin-vuetify@2.1.2(vite@6.4.1(@types/node@24.10.1)(sass@1.94.2))(vue@3.5.25(typescript@5.9.3))(vuetify@3.11.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -1368,5 +1346,3 @@ snapshots:
|
||||||
webidl-conversions: 3.0.1
|
webidl-conversions: 3.0.1
|
||||||
|
|
||||||
zod@4.1.4: {}
|
zod@4.1.4: {}
|
||||||
|
|
||||||
zod@4.3.6: {}
|
|
||||||
|
|
|
||||||
|
|
@ -1,220 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="eli-data-hora">
|
|
||||||
<v-text-field
|
|
||||||
v-model="valor"
|
|
||||||
:type="tipoInput"
|
|
||||||
:label="opcoesEfetivas.rotulo"
|
|
||||||
:placeholder="opcoesEfetivas.placeholder"
|
|
||||||
:disabled="desabilitadoEfetivo"
|
|
||||||
:clearable="Boolean(opcoesEfetivas.limpavel)"
|
|
||||||
:error="Boolean(opcoesEfetivas.erro)"
|
|
||||||
:error-messages="opcoesEfetivas.mensagensErro"
|
|
||||||
:hint="opcoesEfetivas.dica"
|
|
||||||
:persistent-hint="Boolean(opcoesEfetivas.dicaPersistente)"
|
|
||||||
:density="opcoesEfetivas.densidade ?? 'comfortable'"
|
|
||||||
:variant="opcoesEfetivas.variante ?? 'outlined'"
|
|
||||||
:min="minLocal"
|
|
||||||
:max="maxLocal"
|
|
||||||
v-bind="attrs"
|
|
||||||
@focus="emitCompatFocus"
|
|
||||||
@blur="emitCompatBlur"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { computed, defineComponent, PropType } from "vue";
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
import type { CampoDensidade, CampoVariante } from "../../tipos";
|
|
||||||
import type { PadroesEntradas } from "./tiposEntradas";
|
|
||||||
|
|
||||||
type EntradaDataHora = PadroesEntradas["dataHora"];
|
|
||||||
|
|
||||||
type PropsAntigas = {
|
|
||||||
modo?: "data" | "dataHora";
|
|
||||||
rotulo?: string;
|
|
||||||
placeholder?: string;
|
|
||||||
desabilitado?: boolean;
|
|
||||||
limpavel?: boolean;
|
|
||||||
erro?: boolean;
|
|
||||||
mensagensErro?: string | string[];
|
|
||||||
dica?: string;
|
|
||||||
dicaPersistente?: boolean;
|
|
||||||
densidade?: CampoDensidade;
|
|
||||||
variante?: CampoVariante;
|
|
||||||
min?: string;
|
|
||||||
max?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "EliEntradaDataHora",
|
|
||||||
inheritAttrs: false,
|
|
||||||
props: {
|
|
||||||
// --- Novo padrão EliEntrada ---
|
|
||||||
value: {
|
|
||||||
type: String as PropType<EntradaDataHora["value"]>,
|
|
||||||
default: undefined,
|
|
||||||
},
|
|
||||||
opcoes: {
|
|
||||||
type: Object as PropType<EntradaDataHora["opcoes"]>,
|
|
||||||
required: false,
|
|
||||||
default: undefined,
|
|
||||||
},
|
|
||||||
|
|
||||||
// --- Compatibilidade com componente antigo EliDataHora ---
|
|
||||||
modelValue: {
|
|
||||||
type: String as PropType<string | null>,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
modo: { type: String as PropType<PropsAntigas["modo"]>, default: undefined },
|
|
||||||
rotulo: { type: String, default: undefined },
|
|
||||||
placeholder: { type: String, default: undefined },
|
|
||||||
desabilitado: { type: Boolean, default: undefined },
|
|
||||||
limpavel: { type: Boolean, default: undefined },
|
|
||||||
erro: { type: Boolean, default: undefined },
|
|
||||||
mensagensErro: {
|
|
||||||
type: [String, Array] as PropType<string | string[]>,
|
|
||||||
default: undefined,
|
|
||||||
},
|
|
||||||
dica: { type: String, default: undefined },
|
|
||||||
dicaPersistente: { type: Boolean, default: undefined },
|
|
||||||
densidade: { type: String as PropType<CampoDensidade>, default: undefined },
|
|
||||||
variante: { type: String as PropType<CampoVariante>, default: undefined },
|
|
||||||
min: { type: String as PropType<string | undefined>, default: undefined },
|
|
||||||
max: { type: String as PropType<string | undefined>, default: undefined },
|
|
||||||
},
|
|
||||||
emits: {
|
|
||||||
// Novo padrão
|
|
||||||
"update:value": (_v: string | null) => true,
|
|
||||||
input: (_v: string | null) => true, // compat Vue2
|
|
||||||
change: (_v: string | null) => true,
|
|
||||||
|
|
||||||
// Compat antigo
|
|
||||||
"update:modelValue": (_v: string | null) => true,
|
|
||||||
alterar: (_v: string | null) => true,
|
|
||||||
foco: () => true,
|
|
||||||
desfoco: () => true,
|
|
||||||
focus: () => true,
|
|
||||||
blur: () => true,
|
|
||||||
},
|
|
||||||
setup(props, { emit, attrs }) {
|
|
||||||
const opcoesEfetivas = computed<EntradaDataHora["opcoes"]>(() => {
|
|
||||||
// 1) se veio `opcoes` (novo), usa
|
|
||||||
if (props.opcoes) return props.opcoes;
|
|
||||||
|
|
||||||
// 2) fallback: constrói a partir das props antigas
|
|
||||||
return {
|
|
||||||
rotulo: props.rotulo ?? "Data e hora",
|
|
||||||
placeholder: props.placeholder ?? "",
|
|
||||||
modo: props.modo ?? "dataHora",
|
|
||||||
limpavel: props.limpavel,
|
|
||||||
erro: props.erro,
|
|
||||||
mensagensErro: props.mensagensErro,
|
|
||||||
dica: props.dica,
|
|
||||||
dicaPersistente: props.dicaPersistente,
|
|
||||||
densidade: props.densidade,
|
|
||||||
variante: props.variante,
|
|
||||||
min: props.min,
|
|
||||||
max: props.max,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const modoEfetivo = computed<"data" | "dataHora">(
|
|
||||||
() => opcoesEfetivas.value.modo ?? "dataHora"
|
|
||||||
);
|
|
||||||
|
|
||||||
const desabilitadoEfetivo = computed<boolean>(() => Boolean(props.desabilitado));
|
|
||||||
|
|
||||||
const tipoInput = computed<"date" | "datetime-local">(() =>
|
|
||||||
modoEfetivo.value === "data" ? "date" : "datetime-local"
|
|
||||||
);
|
|
||||||
|
|
||||||
function isoParaInputDatetime(valorIso: string): string {
|
|
||||||
if (modoEfetivo.value === "data") {
|
|
||||||
return dayjs(valorIso).format("YYYY-MM-DD");
|
|
||||||
}
|
|
||||||
return dayjs(valorIso).format("YYYY-MM-DDTHH:mm");
|
|
||||||
}
|
|
||||||
|
|
||||||
function inputDatetimeParaIsoLocal(valorInput: string): string {
|
|
||||||
if (modoEfetivo.value === "data") {
|
|
||||||
return dayjs(`${valorInput}T00:00`).format();
|
|
||||||
}
|
|
||||||
return dayjs(valorInput).format();
|
|
||||||
}
|
|
||||||
|
|
||||||
const effectiveModelValue = computed<string | null>(() => {
|
|
||||||
// Prioridade: value (novo) se vier definido; senão usa modelValue (antigo)
|
|
||||||
return props.value !== undefined ? (props.value ?? null) : props.modelValue;
|
|
||||||
});
|
|
||||||
|
|
||||||
const valor = computed<string>({
|
|
||||||
get: () => {
|
|
||||||
if (!effectiveModelValue.value) return "";
|
|
||||||
return isoParaInputDatetime(effectiveModelValue.value);
|
|
||||||
},
|
|
||||||
set: (v) => {
|
|
||||||
const normalizado = v && v.length > 0 ? v : null;
|
|
||||||
if (!normalizado) {
|
|
||||||
emit("update:value", null);
|
|
||||||
emit("input", null);
|
|
||||||
emit("change", null);
|
|
||||||
|
|
||||||
emit("update:modelValue", null);
|
|
||||||
emit("alterar", null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const valorEmitido = inputDatetimeParaIsoLocal(normalizado);
|
|
||||||
|
|
||||||
emit("update:value", valorEmitido);
|
|
||||||
emit("input", valorEmitido);
|
|
||||||
emit("change", valorEmitido);
|
|
||||||
|
|
||||||
emit("update:modelValue", valorEmitido);
|
|
||||||
emit("alterar", valorEmitido);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const minLocal = computed<string | undefined>(() => {
|
|
||||||
const min = opcoesEfetivas.value.min;
|
|
||||||
if (!min) return undefined;
|
|
||||||
return isoParaInputDatetime(min);
|
|
||||||
});
|
|
||||||
|
|
||||||
const maxLocal = computed<string | undefined>(() => {
|
|
||||||
const max = opcoesEfetivas.value.max;
|
|
||||||
if (!max) return undefined;
|
|
||||||
return isoParaInputDatetime(max);
|
|
||||||
});
|
|
||||||
|
|
||||||
function emitCompatFocus() {
|
|
||||||
emit("foco");
|
|
||||||
emit("focus");
|
|
||||||
}
|
|
||||||
|
|
||||||
function emitCompatBlur() {
|
|
||||||
emit("desfoco");
|
|
||||||
emit("blur");
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
attrs,
|
|
||||||
valor,
|
|
||||||
tipoInput,
|
|
||||||
minLocal,
|
|
||||||
maxLocal,
|
|
||||||
opcoesEfetivas,
|
|
||||||
desabilitadoEfetivo,
|
|
||||||
emitCompatFocus,
|
|
||||||
emitCompatBlur,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.eli-data-hora {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,236 +0,0 @@
|
||||||
<template>
|
|
||||||
<v-text-field
|
|
||||||
:model-value="displayValue"
|
|
||||||
:label="opcoes?.rotulo"
|
|
||||||
:placeholder="opcoes?.placeholder"
|
|
||||||
:type="isInteiro ? 'number' : 'text'"
|
|
||||||
:inputmode="isInteiro ? 'numeric' : 'decimal'"
|
|
||||||
:pattern="isInteiro ? '[0-9]*' : '[0-9.,]*'"
|
|
||||||
v-bind="attrs"
|
|
||||||
@update:model-value="onUpdateModelValue"
|
|
||||||
@focus="() => emit('focus')"
|
|
||||||
@blur="() => emit('blur')"
|
|
||||||
>
|
|
||||||
<!--
|
|
||||||
Em alguns cenários (ex.: type="number"), o prop `suffix` do Vuetify pode não aparecer.
|
|
||||||
Usamos slots para garantir exibição consistente de prefixo/sufixo.
|
|
||||||
-->
|
|
||||||
<template v-if="opcoes?.prefixo" #prepend-inner>
|
|
||||||
<span class="eli-entrada__prefixo">{{ opcoes.prefixo }}</span>
|
|
||||||
</template>
|
|
||||||
<template v-if="opcoes?.sufixo" #append-inner>
|
|
||||||
<span class="eli-entrada__sufixo">{{ opcoes.sufixo }}</span>
|
|
||||||
</template>
|
|
||||||
</v-text-field>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { computed, defineComponent, PropType, ref, watch } from "vue";
|
|
||||||
import type { PadroesEntradas } from "./tiposEntradas";
|
|
||||||
|
|
||||||
type EntradaNumero = PadroesEntradas["numero"];
|
|
||||||
|
|
||||||
function casasDecimaisFromPrecisao(precisao: number): number {
|
|
||||||
if (!Number.isFinite(precisao) || precisao <= 0) return 0;
|
|
||||||
if (precisao >= 1) return 0;
|
|
||||||
|
|
||||||
// Preferência por contar casas decimais na representação (ex.: 0.01 -> 2)
|
|
||||||
const texto = precisao.toString();
|
|
||||||
if (texto.includes("e-")) {
|
|
||||||
const [, exp] = texto.split("e-");
|
|
||||||
const n = Number(exp);
|
|
||||||
return Number.isFinite(n) ? n : 0;
|
|
||||||
}
|
|
||||||
const idx = texto.indexOf(".");
|
|
||||||
if (idx === -1) return 0;
|
|
||||||
const dec = texto.slice(idx + 1).replace(/0+$/, "");
|
|
||||||
return dec.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseNumero(texto: string): number | null {
|
|
||||||
const normalizado = (texto ?? "").trim().replace(/,/g, ".");
|
|
||||||
if (!normalizado) return null;
|
|
||||||
const n = Number(normalizado);
|
|
||||||
if (Number.isNaN(n)) return null;
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatarNumero(value: number | null | undefined, casas: number | null) {
|
|
||||||
if (value === null || value === undefined) return "";
|
|
||||||
if (casas === null) return String(value);
|
|
||||||
|
|
||||||
// Garantimos que o texto visual corresponda ao value (fixed).
|
|
||||||
const fixed = Number(value).toFixed(Math.max(0, casas));
|
|
||||||
// Exibe com vírgula (pt-BR)
|
|
||||||
return fixed.replace(/\./g, ",");
|
|
||||||
}
|
|
||||||
|
|
||||||
function somenteNumeros(texto: string) {
|
|
||||||
return (texto ?? "").replace(/\D+/g, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
function somenteNumerosESeparadorDecimal(texto: string) {
|
|
||||||
// Mantém apenas números e UM separador decimal ("," ou "."), sem sinais.
|
|
||||||
// Implementação baseada em regex + colapso de separadores.
|
|
||||||
const limpo = (texto ?? "").replace(/[^0-9.,]+/g, "");
|
|
||||||
const matchSep = limpo.match(/[.,]/);
|
|
||||||
if (!matchSep) return limpo;
|
|
||||||
|
|
||||||
const sep = matchSep[0];
|
|
||||||
const idx = limpo.indexOf(sep);
|
|
||||||
const antesRaw = limpo.slice(0, idx).replace(/[.,]/g, "");
|
|
||||||
const depois = limpo.slice(idx + 1).replace(/[.,]/g, "");
|
|
||||||
|
|
||||||
// Se o usuário começa pelo separador (",4"), normalizamos para "0,4".
|
|
||||||
const antes = antesRaw.length ? antesRaw : "0";
|
|
||||||
return `${antes}${sep}${depois}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function limitarCasasDecimais(texto: string, casas: number | null) {
|
|
||||||
if (casas === null) return texto;
|
|
||||||
if (casas <= 0) return texto.replace(/[.,]/g, "");
|
|
||||||
|
|
||||||
const matchSep = texto.match(/[.,]/);
|
|
||||||
if (!matchSep) return texto;
|
|
||||||
const sep = matchSep[0];
|
|
||||||
const idx = texto.indexOf(sep);
|
|
||||||
|
|
||||||
const inteiro = texto.slice(0, idx);
|
|
||||||
const frac = texto.slice(idx + 1);
|
|
||||||
return `${inteiro}${sep}${frac.slice(0, casas)}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function valorParcialDecimal(texto: string): number | null {
|
|
||||||
// Regra (B): se o usuário digitou "1," ou "1." emite 1.
|
|
||||||
const m = texto.match(/^(\d+)[.,]$/);
|
|
||||||
if (!m) return null;
|
|
||||||
const n = Number(m[1]);
|
|
||||||
return Number.isNaN(n) ? null : n;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "EliEntradaNumero",
|
|
||||||
inheritAttrs: false,
|
|
||||||
props: {
|
|
||||||
/** Interface padrão (EliEntrada): value + opcoes. */
|
|
||||||
value: {
|
|
||||||
type: [Number, null] as unknown as PropType<EntradaNumero["value"]>,
|
|
||||||
default: undefined,
|
|
||||||
},
|
|
||||||
opcoes: {
|
|
||||||
type: Object as PropType<EntradaNumero["opcoes"]>,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
emits: {
|
|
||||||
"update:value": (_v: EntradaNumero["value"]) => true,
|
|
||||||
/** Compat Vue2 (v-model padrão: value + input) */
|
|
||||||
input: (_v: EntradaNumero["value"]) => true,
|
|
||||||
change: (_v: EntradaNumero["value"]) => true,
|
|
||||||
focus: () => true,
|
|
||||||
blur: () => true,
|
|
||||||
},
|
|
||||||
setup(props, { attrs, emit }) {
|
|
||||||
// Se `precisao` não existir => não limitamos casas (mas ainda bloqueamos caracteres inválidos).
|
|
||||||
const casasDecimais = computed<number | null>(() => {
|
|
||||||
const p = props.opcoes?.precisao;
|
|
||||||
if (p === undefined || p === null) return null;
|
|
||||||
return casasDecimaisFromPrecisao(p);
|
|
||||||
});
|
|
||||||
|
|
||||||
const isInteiro = computed(() => {
|
|
||||||
// quando não existe precisão, tratamos como decimal livre
|
|
||||||
return casasDecimais.value === 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
const isFixedPoint = computed(() => {
|
|
||||||
// Quando precisao existe e é < 1, controlamos a vírgula automaticamente.
|
|
||||||
const casas = casasDecimais.value;
|
|
||||||
return casas !== null && casas > 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Controle do texto exibido: impede o campo de ficar com caracteres inválidos.
|
|
||||||
const displayValue = ref<string>("");
|
|
||||||
const ultimoEmitido = ref<EntradaNumero["value"] | undefined>(undefined);
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.value,
|
|
||||||
(v) => {
|
|
||||||
// Se foi uma atualização resultante do que acabamos de emitir, não sobrescreve.
|
|
||||||
// Isso evita o efeito de "apagar" o texto ao digitar algo parcial (ex.: "1,")
|
|
||||||
// quando o valor emitido é `1` ou `null`.
|
|
||||||
if (v === ultimoEmitido.value) return;
|
|
||||||
|
|
||||||
displayValue.value = formatarNumero(v as any, casasDecimais.value);
|
|
||||||
ultimoEmitido.value = v;
|
|
||||||
},
|
|
||||||
{ immediate: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
function onUpdateModelValue(texto: string) {
|
|
||||||
// Modo fixed-point: usuário digita números continuamente e a vírgula é inserida automaticamente.
|
|
||||||
if (isFixedPoint.value) {
|
|
||||||
const casas = casasDecimais.value ?? 0;
|
|
||||||
const digitos = somenteNumeros(texto);
|
|
||||||
// ex.: casas=2, "1" => 0.01 ; "123" => 1.23
|
|
||||||
const baseInt = digitos ? Number(digitos) : 0;
|
|
||||||
const divisor = Math.pow(10, casas);
|
|
||||||
const n = digitos ? baseInt / divisor : null;
|
|
||||||
|
|
||||||
const out = (n === null ? null : n) as EntradaNumero["value"];
|
|
||||||
ultimoEmitido.value = out;
|
|
||||||
emit("update:value", out);
|
|
||||||
emit("input", out);
|
|
||||||
emit("change", out);
|
|
||||||
|
|
||||||
// display deve ser sempre o reflexo do value
|
|
||||||
displayValue.value = formatarNumero(out as any, casas);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Modo livre (sem precisao) ou inteiro: aceita números e 1 separador (no caso livre)
|
|
||||||
const base = isInteiro.value ? somenteNumeros(texto) : somenteNumerosESeparadorDecimal(texto);
|
|
||||||
const textoFiltrado = isInteiro.value ? base : limitarCasasDecimais(base, casasDecimais.value);
|
|
||||||
|
|
||||||
// Emissão:
|
|
||||||
// - vazio => null
|
|
||||||
// - decimal parcial ("1,") => 1 (regra B)
|
|
||||||
// - caso geral => parse normal
|
|
||||||
let out: EntradaNumero["value"] = null;
|
|
||||||
if (textoFiltrado) {
|
|
||||||
const parcial = isInteiro.value ? null : valorParcialDecimal(textoFiltrado);
|
|
||||||
const n = parcial ?? parseNumero(textoFiltrado);
|
|
||||||
out = (n === null ? null : n) as EntradaNumero["value"];
|
|
||||||
}
|
|
||||||
|
|
||||||
ultimoEmitido.value = out;
|
|
||||||
|
|
||||||
emit("update:value", out);
|
|
||||||
emit("input", out);
|
|
||||||
emit("change", out);
|
|
||||||
|
|
||||||
// display deve sempre corresponder ao value final
|
|
||||||
displayValue.value = formatarNumero(out as any, casasDecimais.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return { attrs, emit, displayValue, isInteiro, onUpdateModelValue };
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.eli-entrada__prefixo,
|
|
||||||
.eli-entrada__sufixo {
|
|
||||||
opacity: 0.75;
|
|
||||||
font-size: 0.9em;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-entrada__prefixo {
|
|
||||||
margin-right: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-entrada__sufixo {
|
|
||||||
margin-left: 6px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
<template>
|
|
||||||
<v-text-field
|
|
||||||
v-model="localValue"
|
|
||||||
:type="inputHtmlType"
|
|
||||||
:inputmode="inputMode"
|
|
||||||
:label="opcoes?.rotulo"
|
|
||||||
:placeholder="opcoes?.placeholder"
|
|
||||||
:counter="opcoes?.limiteCaracteres"
|
|
||||||
:maxlength="opcoes?.limiteCaracteres"
|
|
||||||
v-bind="attrs"
|
|
||||||
@focus="() => emit('focus')"
|
|
||||||
@blur="() => emit('blur')"
|
|
||||||
@input="onInput"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { computed, defineComponent, PropType } from "vue";
|
|
||||||
import type { PadroesEntradas } from "./tiposEntradas";
|
|
||||||
import { formatarCpfCnpj } from "./utils/cpfCnpj";
|
|
||||||
import { formatTelefone } from "./utils/telefone";
|
|
||||||
import { formatarCep } from "./utils/cep";
|
|
||||||
|
|
||||||
type EntradaTexto = PadroesEntradas["texto"];
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "EliEntradaTexto",
|
|
||||||
inheritAttrs: false,
|
|
||||||
props: {
|
|
||||||
/** Interface padrão (EliEntrada): value + opcoes. */
|
|
||||||
value: {
|
|
||||||
type: [String, null] as unknown as PropType<EntradaTexto["value"]>,
|
|
||||||
default: undefined,
|
|
||||||
},
|
|
||||||
opcoes: {
|
|
||||||
type: Object as PropType<EntradaTexto["opcoes"]>,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
emits: {
|
|
||||||
"update:value": (_v: EntradaTexto["value"]) => true,
|
|
||||||
/** Compat Vue2 (v-model padrão: value + input) */
|
|
||||||
input: (_v: EntradaTexto["value"]) => true,
|
|
||||||
change: (_v: EntradaTexto["value"]) => true,
|
|
||||||
focus: () => true,
|
|
||||||
blur: () => true,
|
|
||||||
},
|
|
||||||
setup(props, { attrs, emit }) {
|
|
||||||
const formato = computed(() => props.opcoes?.formato ?? "texto");
|
|
||||||
|
|
||||||
const localValue = computed<EntradaTexto["value"]>({
|
|
||||||
get: () => props.value,
|
|
||||||
set: (v) => {
|
|
||||||
emit("update:value", v);
|
|
||||||
emit("input", v);
|
|
||||||
emit("change", v);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const inputHtmlType = computed(() => {
|
|
||||||
if (formato.value === "email") return "email";
|
|
||||||
if (formato.value === "url") return "url";
|
|
||||||
return "text";
|
|
||||||
});
|
|
||||||
|
|
||||||
const inputMode = computed<string | undefined>(() => {
|
|
||||||
if (formato.value === "telefone") return "tel";
|
|
||||||
if (formato.value === "cpfCnpj" || formato.value === "cep") return "numeric";
|
|
||||||
return undefined;
|
|
||||||
});
|
|
||||||
|
|
||||||
function aplicarFormato(valor: string) {
|
|
||||||
switch (formato.value) {
|
|
||||||
case "telefone":
|
|
||||||
return formatTelefone(valor);
|
|
||||||
case "cpfCnpj":
|
|
||||||
return formatarCpfCnpj(valor);
|
|
||||||
case "cep":
|
|
||||||
return formatarCep(valor);
|
|
||||||
default:
|
|
||||||
return valor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onInput(e: Event) {
|
|
||||||
const target = e.target as HTMLInputElement;
|
|
||||||
const resultado = aplicarFormato(target.value);
|
|
||||||
|
|
||||||
// garante que o input mostre o valor formatado
|
|
||||||
target.value = resultado;
|
|
||||||
|
|
||||||
// regra do projeto: value sempre igual ao que aparece
|
|
||||||
localValue.value = resultado;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { attrs, emit, localValue, inputHtmlType, inputMode, onInput };
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
||||||
|
|
@ -1,176 +0,0 @@
|
||||||
# EliEntrada (Padrão de Entradas)
|
|
||||||
|
|
||||||
Esta pasta define o **padrão EliEntrada**: um conjunto de componentes de entrada (inputs) com uma **API uniforme**.
|
|
||||||
|
|
||||||
> TL;DR
|
|
||||||
> - Toda entrada recebe **`value`** (estado) e **`opcoes`** (configuração).
|
|
||||||
> - O padrão de uso é **`v-model:value`**.
|
|
||||||
> - Mantemos compatibilidade com Vue 2 via evento **`input`**.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Para humanos (uso no dia-a-dia)
|
|
||||||
|
|
||||||
### Conceito
|
|
||||||
|
|
||||||
Um componente **EliEntrada** recebe **duas propriedades**:
|
|
||||||
|
|
||||||
- `value`: o valor atual do campo (entrada e saída)
|
|
||||||
- `opcoes`: um objeto que configura o componente (rótulo, placeholder e opções específicas do tipo)
|
|
||||||
|
|
||||||
Essa padronização facilita:
|
|
||||||
- gerar formulários dinamicamente
|
|
||||||
- trocar tipos de entrada com o mínimo de refactor
|
|
||||||
- documentar e tipar de forma previsível
|
|
||||||
|
|
||||||
### Tipos e contratos
|
|
||||||
|
|
||||||
Os contratos ficam em: [`tiposEntradas.ts`](./tiposEntradas.ts)
|
|
||||||
|
|
||||||
- `PadroesEntradas`: mapa de tipos suportados (ex.: `texto`, `numero`, `dataHora`)
|
|
||||||
- `TipoEntrada`: união das chaves do mapa (ex.: `"texto" | "numero" | "dataHora"`)
|
|
||||||
|
|
||||||
### Componentes disponíveis
|
|
||||||
|
|
||||||
#### 1) `EliEntradaTexto`
|
|
||||||
|
|
||||||
**Value**: `string | null | undefined`
|
|
||||||
|
|
||||||
**Opções** (além de `rotulo`/`placeholder`):
|
|
||||||
- `limiteCaracteres?: number`
|
|
||||||
|
|
||||||
Exemplo:
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<template>
|
|
||||||
<EliEntradaTexto
|
|
||||||
v-model:value="nome"
|
|
||||||
:opcoes="{ rotulo: 'Nome', placeholder: 'Digite seu nome', limiteCaracteres: 50 }"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref } from 'vue'
|
|
||||||
import { EliEntradaTexto } from '@/index'
|
|
||||||
|
|
||||||
const nome = ref<string | null>(null)
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### 2) `EliEntradaNumero`
|
|
||||||
|
|
||||||
**Value**: `number | null | undefined`
|
|
||||||
|
|
||||||
**Opções**:
|
|
||||||
- `precisao?: number`
|
|
||||||
- `1` => inteiro
|
|
||||||
- `0.1` => 1 casa decimal
|
|
||||||
- `0.01` => 2 casas decimais
|
|
||||||
- `prefixo?: string` (ex.: `"R$"`)
|
|
||||||
- `sufixo?: string` (ex.: `"kg"`)
|
|
||||||
|
|
||||||
Comportamento:
|
|
||||||
- Quando `precisao < 1` o componente entra em modo **fixed-point**: você digita números continuamente e ele insere a vírgula automaticamente.
|
|
||||||
- O que é exibido sempre corresponde ao `value` emitido.
|
|
||||||
|
|
||||||
Exemplos:
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<EliEntradaNumero
|
|
||||||
v-model:value="quantidade"
|
|
||||||
:opcoes="{ rotulo: 'Quantidade', placeholder: 'Ex: 10', precisao: 1, sufixo: 'kg' }"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<EliEntradaNumero
|
|
||||||
v-model:value="preco"
|
|
||||||
:opcoes="{ rotulo: 'Preço', placeholder: 'Digite', precisao: 0.01, prefixo: 'R$' }"
|
|
||||||
/>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### 3) `EliEntradaDataHora`
|
|
||||||
|
|
||||||
**Value**: `string | null | undefined` (ISO 8601 com offset ou `Z`)
|
|
||||||
|
|
||||||
**Opções**:
|
|
||||||
- `modo?: "data" | "dataHora"` (default: `dataHora`)
|
|
||||||
- `min?: string` (ISO)
|
|
||||||
- `max?: string` (ISO)
|
|
||||||
- `limpavel?: boolean`
|
|
||||||
- `erro?: boolean`
|
|
||||||
- `mensagensErro?: string | string[]`
|
|
||||||
- `dica?: string`
|
|
||||||
- `dicaPersistente?: boolean`
|
|
||||||
- `densidade?: CampoDensidade`
|
|
||||||
- `variante?: CampoVariante`
|
|
||||||
|
|
||||||
Importante:
|
|
||||||
- O input nativo `datetime-local` não carrega timezone.
|
|
||||||
- O componente converte ISO (Z/offset) para **local** para exibir.
|
|
||||||
- Ao alterar, emite ISO 8601 com o **offset local**.
|
|
||||||
|
|
||||||
Exemplo:
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<EliEntradaDataHora
|
|
||||||
v-model:value="agendamento"
|
|
||||||
:opcoes="{ rotulo: 'Agendar', modo: 'dataHora', min, max, limpavel: true }"
|
|
||||||
/>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Compatibilidade Vue 2 / Vue 3
|
|
||||||
|
|
||||||
Padrão recomendado (Vue 3):
|
|
||||||
- `v-model:value`
|
|
||||||
|
|
||||||
Compat Vue 2:
|
|
||||||
- todos os EliEntradas também emitem `input`.
|
|
||||||
- isso permite consumir com o padrão `value + input` quando necessário.
|
|
||||||
|
|
||||||
### Playground
|
|
||||||
|
|
||||||
- Entradas: `src/playground/entradas.playground.vue`
|
|
||||||
- Data/hora: `src/playground/data_hora.playground.vue`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Para IA (contratos, invariantes e padrões de evolução)
|
|
||||||
|
|
||||||
### Contratos (não quebrar)
|
|
||||||
|
|
||||||
1) **Todo EliEntrada tem**:
|
|
||||||
- prop `value`
|
|
||||||
- prop `opcoes`
|
|
||||||
- evento `update:value`
|
|
||||||
|
|
||||||
2) **Compatibilidade**:
|
|
||||||
- emitir `input` (compat Vue 2) é obrigatório
|
|
||||||
|
|
||||||
3) **Tipagem**:
|
|
||||||
- `PadroesEntradas` é a fonte única do contrato (value/opcoes)
|
|
||||||
- `TipoEntrada = keyof PadroesEntradas`
|
|
||||||
|
|
||||||
4) **Sanitização/Normalização**:
|
|
||||||
- `EliEntradaNumero` deve bloquear caracteres inválidos e manter display coerente com `value`
|
|
||||||
- `EliEntradaDataHora` deve receber/emitir ISO e converter para local apenas para exibição
|
|
||||||
|
|
||||||
### Como adicionar uma nova entrada (checklist)
|
|
||||||
|
|
||||||
1) Adicionar chave em `PadroesEntradas` em `tiposEntradas.ts`
|
|
||||||
2) Criar `EliEntradaX.vue` seguindo o padrão:
|
|
||||||
- `value` + `opcoes`
|
|
||||||
- emite `update:value`, `input`, `change`
|
|
||||||
3) Exportar no `src/componentes/EliEntrada/index.ts`
|
|
||||||
4) Registrar no `src/componentes/EliEntrada/registryEliEntradas.ts`
|
|
||||||
5) Criar/atualizar playground (`src/playground/*.playground.vue`)
|
|
||||||
6) Validar `pnpm -s run build:types` e `pnpm -s run build`
|
|
||||||
|
|
||||||
### Padrões de mudança (refactors seguros)
|
|
||||||
|
|
||||||
- Se precisar mudar o contrato, faça **migração incremental**:
|
|
||||||
- manter props/eventos antigos como fallback temporário
|
|
||||||
- atualizar playground e exemplos
|
|
||||||
- rodar `build:types` para garantir geração de `.d.ts`
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
import EliEntradaTexto from "./EliEntradaTexto.vue";
|
|
||||||
import EliEntradaNumero from "./EliEntradaNumero.vue";
|
|
||||||
import EliEntradaDataHora from "./EliEntradaDataHora.vue";
|
|
||||||
|
|
||||||
export { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora };
|
|
||||||
export type { PadroesEntradas, TipoEntrada } from "./tiposEntradas";
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
import type { Component } from "vue";
|
|
||||||
|
|
||||||
import EliEntradaTexto from "./EliEntradaTexto.vue";
|
|
||||||
import EliEntradaNumero from "./EliEntradaNumero.vue";
|
|
||||||
import EliEntradaDataHora from "./EliEntradaDataHora.vue";
|
|
||||||
|
|
||||||
import type { TipoEntrada } from "./tiposEntradas";
|
|
||||||
|
|
||||||
export const registryTabelaCelulas = {
|
|
||||||
texto: EliEntradaTexto,
|
|
||||||
numero: EliEntradaNumero,
|
|
||||||
dataHora: EliEntradaDataHora,
|
|
||||||
} as const satisfies Record<TipoEntrada, Component>;
|
|
||||||
|
|
@ -1,132 +0,0 @@
|
||||||
/**
|
|
||||||
* Tipos base para componentes de entrada (EliEntrada*)
|
|
||||||
*
|
|
||||||
* Objetivo:
|
|
||||||
* - Padronizar o shape de dados de todos os componentes de entrada.
|
|
||||||
* - Cada entrada possui sempre:
|
|
||||||
* 1) `value`: o valor atual (tipado)
|
|
||||||
* 2) `opcoes`: configuração do componente (rótulo, placeholder e extras por tipo)
|
|
||||||
*
|
|
||||||
* Como usar:
|
|
||||||
* - `PadroesEntradas[tipo]` retorna a tipagem completa (value + opcoes) daquele tipo.
|
|
||||||
* - `TipoEntrada` é a união com todos os tipos suportados (ex.: "texto" | "numero").
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Contrato padrão de uma entrada.
|
|
||||||
*
|
|
||||||
* @typeParam T - tipo do `value` (ex.: string | null | undefined)
|
|
||||||
* @typeParam Mais - campos adicionais dentro de `opcoes`, específicos do tipo de entrada
|
|
||||||
*/
|
|
||||||
export type tipoPadraoEntrada<T, Mais extends Record<string, unknown> = {}> = {
|
|
||||||
/** Valor atual do campo (pode aceitar null/undefined quando aplicável) */
|
|
||||||
value: T
|
|
||||||
|
|
||||||
/** Configurações do componente (visuais + regras simples do tipo) */
|
|
||||||
opcoes: {
|
|
||||||
/** Rótulo exibido ao usuário */
|
|
||||||
rotulo: string
|
|
||||||
|
|
||||||
/** Texto de ajuda dentro do input quando vazio */
|
|
||||||
placeholder?: string
|
|
||||||
} & Mais
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mapa de tipos de entrada suportados e suas configurações específicas.
|
|
||||||
*
|
|
||||||
* Observação importante:
|
|
||||||
* - As chaves deste objeto (ex.: "texto", "numero") viram o tipo `TipoEntrada`.
|
|
||||||
* - Cada item define:
|
|
||||||
* - `value`: tipo do valor
|
|
||||||
* - `opcoes`: opções comuns + extras específicas
|
|
||||||
*/
|
|
||||||
export type PadroesEntradas = {
|
|
||||||
texto: tipoPadraoEntrada<
|
|
||||||
string | null | undefined,
|
|
||||||
{
|
|
||||||
/** Limite máximo de caracteres permitidos (se definido) */
|
|
||||||
limiteCaracteres?: number
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formato/máscara aplicada ao texto.
|
|
||||||
* Obs: o `value` SEMPRE será o texto formatado (o que aparece no input).
|
|
||||||
*/
|
|
||||||
formato?: "texto" | "email" | "url" | "telefone" | "cpfCnpj" | "cep"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
|
|
||||||
numero: tipoPadraoEntrada<
|
|
||||||
number | null | undefined,
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** Unidade de medida (ex.: "kg", "m³") */
|
|
||||||
sufixo?: string
|
|
||||||
|
|
||||||
/** Moéda (ex.: "R$") */
|
|
||||||
prefixo?: string
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Passo/precisão do valor numérico.
|
|
||||||
* - 1 => somente inteiros
|
|
||||||
* - 0.1 => 1 casa decimal
|
|
||||||
* - 0.01 => 2 casas decimais
|
|
||||||
*
|
|
||||||
* Dica: este conceito corresponde ao atributo HTML `step`.
|
|
||||||
*/
|
|
||||||
precisao?: number
|
|
||||||
}
|
|
||||||
>
|
|
||||||
|
|
||||||
dataHora: tipoPadraoEntrada<
|
|
||||||
string | null | undefined,
|
|
||||||
{
|
|
||||||
/** Define o tipo de entrada. - `dataHora`: datetime-local - `data`: date */
|
|
||||||
modo?: "data" | "dataHora"
|
|
||||||
|
|
||||||
/** 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
|
|
||||||
|
|
||||||
/** Valor mínimo permitido (ISO 8601 - offset ou Z). */
|
|
||||||
min?: string
|
|
||||||
|
|
||||||
/** Valor máximo permitido (ISO 8601 - offset ou Z). */
|
|
||||||
max?: string
|
|
||||||
|
|
||||||
/** 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.
|
|
||||||
* Ex.: "texto" | "numero"
|
|
||||||
*/
|
|
||||||
export type TipoEntrada = keyof PadroesEntradas
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export type PadraoComponenteEntrada<T extends TipoEntrada> =
|
|
||||||
readonly [T, PadroesEntradas[T]['opcoes']]
|
|
||||||
|
|
||||||
export type ComponenteEntrada = {
|
|
||||||
[K in TipoEntrada]: PadraoComponenteEntrada<K>
|
|
||||||
}[TipoEntrada]
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
function somenteNumeros(valor: string) {
|
|
||||||
return valor.replace(/\D+/g, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Formata CEP no padrão 00000-000 */
|
|
||||||
export function formatarCep(valor: string) {
|
|
||||||
const digitos = somenteNumeros(valor);
|
|
||||||
if (!digitos) return "";
|
|
||||||
return digitos.replace(/^(\d{5})(\d)/, "$1-$2").slice(0, 9);
|
|
||||||
}
|
|
||||||
|
|
@ -1,391 +0,0 @@
|
||||||
<template>
|
|
||||||
<div v-if="aberto" class="eli-tabela-modal-filtro__overlay" role="presentation" @click.self="emitFechar">
|
|
||||||
<div class="eli-tabela-modal-filtro__modal" role="dialog" aria-modal="true" aria-label="Filtro avançado">
|
|
||||||
<header class="eli-tabela-modal-filtro__header">
|
|
||||||
<h3 class="eli-tabela-modal-filtro__titulo">Filtro avançado</h3>
|
|
||||||
<button type="button" class="eli-tabela-modal-filtro__fechar" aria-label="Fechar" @click="emitFechar">
|
|
||||||
×
|
|
||||||
</button>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div class="eli-tabela-modal-filtro__conteudo">
|
|
||||||
<div v-if="!filtrosBase.length" class="eli-tabela-modal-filtro__vazio">
|
|
||||||
Nenhum filtro configurado na tabela.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-else class="eli-tabela-modal-filtro__lista">
|
|
||||||
<div v-for="(linha, idx) in linhas" :key="String(linha.coluna)" class="eli-tabela-modal-filtro__linha">
|
|
||||||
<div class="eli-tabela-modal-filtro__entrada">
|
|
||||||
<component
|
|
||||||
:is="componenteEntrada(linha.entrada)"
|
|
||||||
v-model:value="linha.valor"
|
|
||||||
:opcoes="opcoesEntrada(linha.entrada)"
|
|
||||||
density="compact"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="eli-tabela-modal-filtro__remover"
|
|
||||||
title="Remover"
|
|
||||||
aria-label="Remover"
|
|
||||||
@click="remover(idx)"
|
|
||||||
>
|
|
||||||
×
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="eli-tabela-modal-filtro__acoes">
|
|
||||||
<select v-model="colunaParaAdicionar" class="eli-tabela-modal-filtro__select" :disabled="!opcoesParaAdicionar.length">
|
|
||||||
<option disabled value="">Selecione um filtro…</option>
|
|
||||||
<option v-for="o in opcoesParaAdicionar" :key="String(o.coluna)" :value="String(o.coluna)">
|
|
||||||
{{ rotuloDoFiltro(o) }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="eli-tabela-modal-filtro__botao"
|
|
||||||
@click="adicionar"
|
|
||||||
:disabled="!colunaParaAdicionar"
|
|
||||||
>
|
|
||||||
Adicionar
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer class="eli-tabela-modal-filtro__footer">
|
|
||||||
<button type="button" class="eli-tabela-modal-filtro__botao eli-tabela-modal-filtro__botao--sec" @click="emitLimpar">
|
|
||||||
Limpar
|
|
||||||
</button>
|
|
||||||
<button type="button" class="eli-tabela-modal-filtro__botao eli-tabela-modal-filtro__botao--sec" @click="emitFechar">
|
|
||||||
Cancelar
|
|
||||||
</button>
|
|
||||||
<button type="button" class="eli-tabela-modal-filtro__botao eli-tabela-modal-filtro__botao--prim" @click="emitSalvar">
|
|
||||||
Aplicar
|
|
||||||
</button>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { computed, defineComponent, PropType, ref, watch } from "vue";
|
|
||||||
import { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora } from "../EliEntrada";
|
|
||||||
import type { ComponenteEntrada, TipoEntrada } from "../EliEntrada/tiposEntradas";
|
|
||||||
import type { EliTabelaConsulta } from "./types-eli-tabela";
|
|
||||||
|
|
||||||
type FiltroBase<T> = NonNullable<EliTabelaConsulta<T>["filtroAvancado"]>[number];
|
|
||||||
|
|
||||||
type LinhaFiltro<T> = {
|
|
||||||
coluna: keyof T;
|
|
||||||
entrada: ComponenteEntrada;
|
|
||||||
operador: string;
|
|
||||||
valor: any;
|
|
||||||
};
|
|
||||||
|
|
||||||
function isTipoEntrada(v: unknown): v is TipoEntrada {
|
|
||||||
return v === "texto" || v === "numero" || v === "dataHora";
|
|
||||||
}
|
|
||||||
|
|
||||||
function rotuloDoFiltro(f: FiltroBase<any>) {
|
|
||||||
const rotulo = (f?.entrada?.[1] as any)?.rotulo;
|
|
||||||
return rotulo ? String(rotulo) : String(f?.coluna ?? "Filtro");
|
|
||||||
}
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "EliTabelaModalFiltroAvancado",
|
|
||||||
props: {
|
|
||||||
aberto: { type: Boolean, required: true },
|
|
||||||
filtrosBase: {
|
|
||||||
type: Array as PropType<Array<FiltroBase<any>>>,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
modelo: {
|
|
||||||
type: Array as PropType<Array<any>>,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
emits: {
|
|
||||||
fechar: () => true,
|
|
||||||
limpar: () => true,
|
|
||||||
salvar: (_linhas: any[]) => true,
|
|
||||||
},
|
|
||||||
setup(props, { emit }) {
|
|
||||||
const linhas = ref<Array<LinhaFiltro<any>>>([]);
|
|
||||||
|
|
||||||
const colunaParaAdicionar = ref<string>("");
|
|
||||||
|
|
||||||
const colunasDisponiveis = computed(() => (props.filtrosBase ?? []).map((b) => String(b.coluna)));
|
|
||||||
|
|
||||||
const opcoesParaAdicionar = computed(() => {
|
|
||||||
const usadas = new Set(linhas.value.map((l) => String(l.coluna)));
|
|
||||||
return (props.filtrosBase ?? []).filter((b) => !usadas.has(String(b.coluna)));
|
|
||||||
});
|
|
||||||
|
|
||||||
function componenteEntrada(entrada: ComponenteEntrada) {
|
|
||||||
const tipo = entrada?.[0];
|
|
||||||
if (tipo === "numero") return EliEntradaNumero;
|
|
||||||
if (tipo === "dataHora") return EliEntradaDataHora;
|
|
||||||
return EliEntradaTexto;
|
|
||||||
}
|
|
||||||
|
|
||||||
function opcoesEntrada(entrada: ComponenteEntrada) {
|
|
||||||
// o rótulo vem do próprio componente (entrada[1].rotulo)
|
|
||||||
return (entrada?.[1] as any) ?? { rotulo: "" };
|
|
||||||
}
|
|
||||||
|
|
||||||
function valorInicialPorEntrada(entrada: ComponenteEntrada) {
|
|
||||||
const tipo = entrada?.[0];
|
|
||||||
if (tipo === "numero") return null;
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function normalizarModelo() {
|
|
||||||
const base = props.filtrosBase ?? [];
|
|
||||||
const modelo = Array.isArray(props.modelo) ? props.modelo : [];
|
|
||||||
linhas.value = modelo.map((m: any) => {
|
|
||||||
// operador vem travado no base
|
|
||||||
const baseItem = base.find((b) => String(b.coluna) === String(m.coluna)) ?? base[0];
|
|
||||||
const entrada = (baseItem?.entrada ?? m.entrada) as ComponenteEntrada;
|
|
||||||
const col = (baseItem?.coluna ?? m.coluna) as any;
|
|
||||||
const op = String(baseItem?.operador ?? "=");
|
|
||||||
const val = m.valor ?? valorInicialPorEntrada(entrada);
|
|
||||||
|
|
||||||
return {
|
|
||||||
coluna: col,
|
|
||||||
operador: op,
|
|
||||||
entrada,
|
|
||||||
valor: val,
|
|
||||||
} as LinhaFiltro<any>;
|
|
||||||
});
|
|
||||||
|
|
||||||
// se vazio e existe base, adiciona 1 linha default
|
|
||||||
// não auto-adiciona; usuário escolhe quais filtros quer usar
|
|
||||||
|
|
||||||
// se algum filtro mudou a coluna para valor inválido, ajusta
|
|
||||||
for (const l of linhas.value) {
|
|
||||||
if (!colunasDisponiveis.value.includes(String(l.coluna))) continue;
|
|
||||||
l.operador = String((base.find((b) => String(b.coluna) === String(l.coluna))?.operador ?? "="));
|
|
||||||
// sanity
|
|
||||||
if (l.entrada && !isTipoEntrada(l.entrada[0])) {
|
|
||||||
l.entrada = ["texto", { rotulo: "Valor" }] as any;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => [props.aberto, props.filtrosBase, props.modelo] as const,
|
|
||||||
() => {
|
|
||||||
if (props.aberto) normalizarModelo();
|
|
||||||
},
|
|
||||||
{ deep: true, immediate: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
function adicionar() {
|
|
||||||
if (!colunaParaAdicionar.value) return;
|
|
||||||
const b0 = (props.filtrosBase ?? []).find((b) => String(b.coluna) === String(colunaParaAdicionar.value));
|
|
||||||
if (!b0) return;
|
|
||||||
// evita repetição
|
|
||||||
if (linhas.value.some((l) => String(l.coluna) === String(b0.coluna))) return;
|
|
||||||
|
|
||||||
linhas.value.push({
|
|
||||||
coluna: b0.coluna as any,
|
|
||||||
entrada: b0.entrada,
|
|
||||||
operador: String(b0.operador ?? "="),
|
|
||||||
valor: valorInicialPorEntrada(b0.entrada),
|
|
||||||
});
|
|
||||||
|
|
||||||
colunaParaAdicionar.value = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function remover(idx: number) {
|
|
||||||
linhas.value.splice(idx, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function emitFechar() {
|
|
||||||
emit("fechar");
|
|
||||||
}
|
|
||||||
|
|
||||||
function emitLimpar() {
|
|
||||||
emit("limpar");
|
|
||||||
}
|
|
||||||
|
|
||||||
function emitSalvar() {
|
|
||||||
emit(
|
|
||||||
"salvar",
|
|
||||||
linhas.value.map((l) => ({
|
|
||||||
coluna: l.coluna,
|
|
||||||
valor: l.valor,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
linhas,
|
|
||||||
opcoesParaAdicionar,
|
|
||||||
colunaParaAdicionar,
|
|
||||||
componenteEntrada,
|
|
||||||
opcoesEntrada,
|
|
||||||
adicionar,
|
|
||||||
remover,
|
|
||||||
// exibimos operador fixo só como texto
|
|
||||||
emitFechar,
|
|
||||||
emitSalvar,
|
|
||||||
emitLimpar,
|
|
||||||
rotuloDoFiltro,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.eli-tabela-modal-filtro__overlay {
|
|
||||||
position: fixed;
|
|
||||||
inset: 0;
|
|
||||||
background: rgba(15, 23, 42, 0.35);
|
|
||||||
z-index: 4000;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__modal {
|
|
||||||
width: min(980px, 100%);
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 14px;
|
|
||||||
border: 1px solid rgba(15, 23, 42, 0.1);
|
|
||||||
box-shadow: 0 18px 60px rgba(15, 23, 42, 0.25);
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 14px 16px;
|
|
||||||
border-bottom: 1px solid rgba(15, 23, 42, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__titulo {
|
|
||||||
font-size: 1rem;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__fechar {
|
|
||||||
width: 34px;
|
|
||||||
height: 34px;
|
|
||||||
border-radius: 10px;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 22px;
|
|
||||||
line-height: 1;
|
|
||||||
color: rgba(15, 23, 42, 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__fechar:hover,
|
|
||||||
.eli-tabela-modal-filtro__fechar:focus-visible {
|
|
||||||
background: rgba(15, 23, 42, 0.06);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__conteudo {
|
|
||||||
padding: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__vazio {
|
|
||||||
opacity: 0.75;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__lista {
|
|
||||||
display: grid;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__linha {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 34px;
|
|
||||||
gap: 10px;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__select {
|
|
||||||
height: 34px;
|
|
||||||
border-radius: 10px;
|
|
||||||
border: 1px solid rgba(15, 23, 42, 0.12);
|
|
||||||
padding: 0 10px;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__entrada {
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__remover {
|
|
||||||
width: 34px;
|
|
||||||
height: 34px;
|
|
||||||
border-radius: 10px;
|
|
||||||
border: 1px solid rgba(15, 23, 42, 0.12);
|
|
||||||
background: #fff;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 1;
|
|
||||||
color: rgba(15, 23, 42, 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__remover:hover,
|
|
||||||
.eli-tabela-modal-filtro__remover:focus-visible {
|
|
||||||
background: rgba(15, 23, 42, 0.06);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__acoes {
|
|
||||||
margin-top: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__footer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 14px 16px;
|
|
||||||
border-top: 1px solid rgba(15, 23, 42, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__botao {
|
|
||||||
height: 34px;
|
|
||||||
padding: 0 14px;
|
|
||||||
border-radius: 10px;
|
|
||||||
border: 1px solid rgba(15, 23, 42, 0.12);
|
|
||||||
background: #fff;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__botao:disabled {
|
|
||||||
opacity: 0.55;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__botao--sec:hover,
|
|
||||||
.eli-tabela-modal-filtro__botao--sec:focus-visible {
|
|
||||||
background: rgba(15, 23, 42, 0.06);
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__botao--prim {
|
|
||||||
border: none;
|
|
||||||
background: rgba(37, 99, 235, 0.95);
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eli-tabela-modal-filtro__botao--prim:hover,
|
|
||||||
.eli-tabela-modal-filtro__botao--prim:focus-visible {
|
|
||||||
background: rgba(37, 99, 235, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 880px) {
|
|
||||||
.eli-tabela-modal-filtro__linha {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
<template>
|
|
||||||
<button
|
|
||||||
v-if="dados?.acao"
|
|
||||||
type="button"
|
|
||||||
class="eli-tabela__celula-link"
|
|
||||||
@click.stop.prevent="dados.acao()"
|
|
||||||
>
|
|
||||||
{{ String(dados?.numero).replace('.', ',') }}
|
|
||||||
</button>
|
|
||||||
<span v-else>{{ String(dados?.numero).replace('.', ',') }}</span>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { defineComponent, PropType } from "vue"
|
|
||||||
import type { TiposTabelaCelulas } from "./tiposTabelaCelulas";
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "EliTabelaCelulaNumero",
|
|
||||||
components: {},
|
|
||||||
props: {
|
|
||||||
dados: {
|
|
||||||
type: Object as PropType<TiposTabelaCelulas["numero"]>,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
|
|
||||||
},
|
|
||||||
setup({ dados }) {
|
|
||||||
return { dados }
|
|
||||||
},
|
|
||||||
})
|
|
||||||
</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>
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
<template>
|
|
||||||
<button
|
|
||||||
v-if="dados?.acao"
|
|
||||||
type="button"
|
|
||||||
class="eli-tabela__celula-link"
|
|
||||||
@click.stop.prevent="dados.acao()"
|
|
||||||
>
|
|
||||||
{{ dados?.texto }}
|
|
||||||
</button>
|
|
||||||
<span v-else>{{ dados?.texto }}</span>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { defineComponent, PropType } from "vue"
|
|
||||||
import type { TiposTabelaCelulas } from "./tiposTabelaCelulas";
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "EliTabelaCelulaTextoSimples",
|
|
||||||
components: {},
|
|
||||||
props: {
|
|
||||||
dados: {
|
|
||||||
type: Object as PropType<TiposTabelaCelulas["textoSimples"]>,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
|
|
||||||
},
|
|
||||||
setup({ dados }) {
|
|
||||||
return { dados }
|
|
||||||
},
|
|
||||||
})
|
|
||||||
</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>
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
<template>
|
|
||||||
|
|
||||||
<!-- TODO: Validar de ação está cehgando aqui-->
|
|
||||||
<button
|
|
||||||
v-if="dados?.acao"
|
|
||||||
type="button"
|
|
||||||
class="eli-tabela__texto-truncado eli-tabela__celula-link"
|
|
||||||
:title="dados?.texto"
|
|
||||||
@click.stop.prevent="dados.acao()"
|
|
||||||
>
|
|
||||||
{{ dados?.texto }}
|
|
||||||
</button>
|
|
||||||
<span v-else class="eli-tabela__texto-truncado" :title="dados?.texto">{{ dados?.texto }}</span>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { defineComponent, PropType } from "vue";
|
|
||||||
import type { TiposTabelaCelulas } from "./tiposTabelaCelulas";
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "EliTabelaCelulaTextoTruncado",
|
|
||||||
props: {
|
|
||||||
dados: {
|
|
||||||
type: Object as PropType<TiposTabelaCelulas["textoTruncado"]>,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
setup({ dados }) {
|
|
||||||
return { dados };
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.eli-tabela__texto-truncado {
|
|
||||||
display: inline-block;
|
|
||||||
max-width: 260px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.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>
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
export type EliTabelaFiltroAvancadoSalvo<T> = Array<{
|
|
||||||
coluna: keyof T
|
|
||||||
valor: any
|
|
||||||
}>;
|
|
||||||
|
|
||||||
function key(nomeTabela: string) {
|
|
||||||
return `eli_tabela:${nomeTabela}:filtro_avancado`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function carregarFiltroAvancado<T>(nomeTabela: string): EliTabelaFiltroAvancadoSalvo<T> {
|
|
||||||
try {
|
|
||||||
const raw = localStorage.getItem(key(nomeTabela));
|
|
||||||
if (!raw) return [] as unknown as EliTabelaFiltroAvancadoSalvo<T>;
|
|
||||||
const parsed = JSON.parse(raw);
|
|
||||||
return Array.isArray(parsed) ? (parsed as EliTabelaFiltroAvancadoSalvo<T>) : ([] as any);
|
|
||||||
} catch {
|
|
||||||
return [] as unknown as EliTabelaFiltroAvancadoSalvo<T>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function salvarFiltroAvancado<T>(nomeTabela: string, filtros: EliTabelaFiltroAvancadoSalvo<T>) {
|
|
||||||
try {
|
|
||||||
localStorage.setItem(key(nomeTabela), JSON.stringify(filtros ?? []));
|
|
||||||
} catch {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function limparFiltroAvancado(nomeTabela: string) {
|
|
||||||
try {
|
|
||||||
localStorage.removeItem(key(nomeTabela));
|
|
||||||
} catch {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
304
src/componentes/campo/EliInput.vue
Normal file
304
src/componentes/campo/EliInput.vue
Normal file
|
|
@ -0,0 +1,304 @@
|
||||||
|
<template>
|
||||||
|
<div class="eli-input">
|
||||||
|
<!-- TEXT LIKE INPUTS -->
|
||||||
|
<v-text-field
|
||||||
|
v-if="isTextLike"
|
||||||
|
v-model="value"
|
||||||
|
:type="inputHtmlType"
|
||||||
|
:label="label"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:disabled="disabled"
|
||||||
|
:clearable="clearable && type !== 'password'"
|
||||||
|
:error="error"
|
||||||
|
:error-messages="errorMessages"
|
||||||
|
:hint="hint"
|
||||||
|
:persistent-hint="persistentHint"
|
||||||
|
:density="density"
|
||||||
|
:variant="variant"
|
||||||
|
:color="internalColor"
|
||||||
|
:inputmode="inputMode"
|
||||||
|
:suffix="type === 'porcentagem' ? '%' : undefined"
|
||||||
|
v-bind="attrs"
|
||||||
|
@focus="onFocus"
|
||||||
|
@blur="onBlur"
|
||||||
|
@input="onInput"
|
||||||
|
>
|
||||||
|
<!-- PASSWORD TOGGLE -->
|
||||||
|
<template
|
||||||
|
v-if="type === 'password' && showPasswordToggle"
|
||||||
|
#append-inner
|
||||||
|
>
|
||||||
|
<v-icon
|
||||||
|
class="cursor-pointer"
|
||||||
|
@click="togglePassword"
|
||||||
|
>
|
||||||
|
{{ showPassword ? "mdi-eye-off" : "mdi-eye" }}
|
||||||
|
</v-icon>
|
||||||
|
</template>
|
||||||
|
</v-text-field>
|
||||||
|
|
||||||
|
<!-- TEXTAREA -->
|
||||||
|
<v-textarea
|
||||||
|
v-else-if="type === 'textarea'"
|
||||||
|
v-model="value"
|
||||||
|
:label="label"
|
||||||
|
:rows="rows"
|
||||||
|
:density="density"
|
||||||
|
:variant="variant"
|
||||||
|
v-bind="attrs"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- SELECT -->
|
||||||
|
<v-select
|
||||||
|
v-else-if="type === 'select'"
|
||||||
|
v-model="value"
|
||||||
|
:items="computedItems"
|
||||||
|
:label="label"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:multiple="multiple"
|
||||||
|
:chips="chips"
|
||||||
|
:clearable="clearable"
|
||||||
|
:disabled="disabled"
|
||||||
|
:density="density"
|
||||||
|
:variant="variant"
|
||||||
|
item-title="label"
|
||||||
|
item-value="value"
|
||||||
|
:error="error"
|
||||||
|
:error-messages="errorMessages"
|
||||||
|
v-bind="attrs"
|
||||||
|
@focus="onFocus"
|
||||||
|
@blur="onBlur"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- RADIO -->
|
||||||
|
<v-radio-group
|
||||||
|
v-else-if="type === 'radio'"
|
||||||
|
v-model="value"
|
||||||
|
:row="row"
|
||||||
|
>
|
||||||
|
<v-radio
|
||||||
|
v-for="opt in computedItems"
|
||||||
|
:key="String(opt.value)"
|
||||||
|
:label="opt.label"
|
||||||
|
:value="opt.value"
|
||||||
|
/>
|
||||||
|
</v-radio-group>
|
||||||
|
|
||||||
|
<!-- CHECKBOX -->
|
||||||
|
<div v-else-if="type === 'checkbox'" class="checkbox-group">
|
||||||
|
<v-checkbox
|
||||||
|
v-for="opt in computedItems"
|
||||||
|
:key="String(opt.value)"
|
||||||
|
v-model="value"
|
||||||
|
:label="opt.label"
|
||||||
|
:value="opt.value"
|
||||||
|
:density="density"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, ref, computed, PropType } from "vue";
|
||||||
|
import type {
|
||||||
|
CampoDensidade,
|
||||||
|
CampoOpcao,
|
||||||
|
CampoOpcaoBruta,
|
||||||
|
CampoTipo,
|
||||||
|
CampoValor,
|
||||||
|
CampoValorMultiplo,
|
||||||
|
CampoVariante,
|
||||||
|
} from "../../tipos";
|
||||||
|
import { formatarCpfCnpj } from "./utils/cpfCnpj";
|
||||||
|
import { formatTelefone } from "./utils/telefone";
|
||||||
|
import { formatarDecimal, formatarMoeda, formatarPorcentagem, somenteNumeros } from "./utils/numerico"
|
||||||
|
import { formatarCep } from "./utils/cep";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "EliInput",
|
||||||
|
inheritAttrs: false,
|
||||||
|
|
||||||
|
props: {
|
||||||
|
/**
|
||||||
|
* Aceita valor simples (text-like) ou lista de valores (checkbox/select multiple).
|
||||||
|
* O componente não converte tipos automaticamente: mantém o que receber.
|
||||||
|
*/
|
||||||
|
modelValue: {
|
||||||
|
type: [String, Number, Boolean, Array] as PropType<CampoValor | CampoValorMultiplo>,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
type: { type: String as PropType<CampoTipo>, default: "text" },
|
||||||
|
label: String,
|
||||||
|
placeholder: String,
|
||||||
|
disabled: Boolean,
|
||||||
|
error: Boolean,
|
||||||
|
errorMessages: {
|
||||||
|
type: [String, Array] as PropType<string | string[]>,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
hint: String,
|
||||||
|
persistentHint: Boolean,
|
||||||
|
rows: { type: Number, default: 4 },
|
||||||
|
/**
|
||||||
|
* Para select/radio/checkbox.
|
||||||
|
* Aceita lista já normalizada ({ label, value }) ou valores primitivos.
|
||||||
|
*/
|
||||||
|
options: {
|
||||||
|
type: Array as PropType<Array<CampoOpcaoBruta>>,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
clearable: Boolean,
|
||||||
|
variant: { type: String as PropType<CampoVariante>, default: "outlined" },
|
||||||
|
density: { type: String as PropType<CampoDensidade>, default: "comfortable" },
|
||||||
|
color: { type: String, default: "primary" },
|
||||||
|
row: Boolean,
|
||||||
|
showPasswordToggle: Boolean,
|
||||||
|
multiple: Boolean,
|
||||||
|
chips: Boolean,
|
||||||
|
},
|
||||||
|
|
||||||
|
emits: ["update:modelValue", "change", "focus", "blur"],
|
||||||
|
|
||||||
|
setup(props, { emit, attrs }) {
|
||||||
|
const focused = ref(false);
|
||||||
|
const showPassword = ref(false);
|
||||||
|
|
||||||
|
const value = computed({
|
||||||
|
get: () => props.modelValue,
|
||||||
|
set: (v: CampoValor | CampoValorMultiplo) => {
|
||||||
|
emit("update:modelValue", v);
|
||||||
|
emit("change", v);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const isTextLike = computed(() =>
|
||||||
|
[
|
||||||
|
"text",
|
||||||
|
"password",
|
||||||
|
"email",
|
||||||
|
"search",
|
||||||
|
"url",
|
||||||
|
"telefone",
|
||||||
|
"cpfCnpj",
|
||||||
|
"numericoInteiro",
|
||||||
|
"numericoDecimal",
|
||||||
|
"numericoMoeda",
|
||||||
|
"porcentagem",
|
||||||
|
"cep",
|
||||||
|
].includes(props.type)
|
||||||
|
);
|
||||||
|
|
||||||
|
const inputHtmlType = computed(() =>
|
||||||
|
props.type === "password"
|
||||||
|
? showPassword.value
|
||||||
|
? "text"
|
||||||
|
: "password"
|
||||||
|
: "text"
|
||||||
|
);
|
||||||
|
|
||||||
|
const inputMode = computed(() => {
|
||||||
|
if (props.type === "telefone") return "tel";
|
||||||
|
if (props.type === "porcentagem") return "decimal";
|
||||||
|
if (props.type.startsWith("numerico")) return "numeric";
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
const internalColor = computed(() =>
|
||||||
|
props.error ? "error" : focused.value ? props.color : undefined
|
||||||
|
);
|
||||||
|
|
||||||
|
function onInput(e: Event) {
|
||||||
|
const target = e.target as HTMLInputElement;
|
||||||
|
let resultado = target.value;
|
||||||
|
|
||||||
|
switch (props.type) {
|
||||||
|
case "numericoInteiro":
|
||||||
|
resultado = somenteNumeros(resultado);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "numericoDecimal":
|
||||||
|
resultado = formatarDecimal(resultado);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "numericoMoeda":
|
||||||
|
resultado = formatarMoeda(resultado);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "porcentagem":
|
||||||
|
resultado = formatarPorcentagem(resultado);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "telefone":
|
||||||
|
resultado = formatTelefone(resultado);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "cpfCnpj":
|
||||||
|
resultado = formatarCpfCnpj(resultado);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "cep":
|
||||||
|
resultado = formatarCep(resultado);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
target.value = resultado;
|
||||||
|
emit("update:modelValue", resultado);
|
||||||
|
emit("change", resultado);
|
||||||
|
}
|
||||||
|
|
||||||
|
function togglePassword() {
|
||||||
|
showPassword.value = !showPassword.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Helpers para select / radio / checkbox (aceita objetos ou primitivos) ---
|
||||||
|
const computedItems = computed<Array<CampoOpcao>>(() => {
|
||||||
|
// Normaliza options para [{ label, value, disabled? }]
|
||||||
|
return (props.options || []).map((o) => {
|
||||||
|
if (o && typeof o === "object" && "value" in o) {
|
||||||
|
const valor = o.value as CampoValor;
|
||||||
|
return {
|
||||||
|
label: o.label ?? String(valor),
|
||||||
|
value: valor,
|
||||||
|
disabled: o.disabled,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const valor = o as CampoValor;
|
||||||
|
return { label: String(valor), value: valor };
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
attrs,
|
||||||
|
value,
|
||||||
|
isTextLike,
|
||||||
|
inputHtmlType,
|
||||||
|
inputMode,
|
||||||
|
internalColor,
|
||||||
|
showPassword,
|
||||||
|
togglePassword,
|
||||||
|
onInput,
|
||||||
|
onFocus: () => emit("focus"),
|
||||||
|
onBlur: () => emit("blur"),
|
||||||
|
computedItems,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.eli-input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cursor-pointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
118
src/componentes/campo/README.md
Normal file
118
src/componentes/campo/README.md
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
# EliInput
|
||||||
|
|
||||||
|
**Componente base de input do design system**
|
||||||
|
|
||||||
|
O EliInput unifica vários tipos de campo (v-text-field, v-textarea, v-select, v-radio-group, v-checkbox) em uma única API consistente. Ele encapsula comportamentos, máscaras e regras comuns (CPF/CNPJ, telefone, CEP, numéricos, formatação de moeda etc.) para manter coerência visual e de lógica em toda a aplicação.
|
||||||
|
|
||||||
|
> ⚠️ Nunca use os componentes Vuetify diretamente fora do design system para esses casos.
|
||||||
|
> Utilize sempre EliInput para garantir formatação, tipagem e repasse de atributos padronizados.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Visão geral
|
||||||
|
|
||||||
|
EliInput foi projetado para:
|
||||||
|
|
||||||
|
* Centralizar formatação (máscaras) para tipos de entrada comuns (telefone, CPF/CNPJ, CEP, numéricos).
|
||||||
|
* Fornecer uma API única (type) que representa diferentes controles (text, textarea, select, radio, checkbox, etc.).
|
||||||
|
* Repassar atributos/props do pai para o componente Vuetify interno (v-bind="$attrs") mantendo inheritAttrs: false.
|
||||||
|
* Emitir eventos padronizados: update:modelValue, change, focus, blur.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Principais decisões de implementação
|
||||||
|
|
||||||
|
* inheritAttrs: false — o componente controla explicitamente para onde os atributos são passados (v-bind="attrs" no elemento interno).
|
||||||
|
* Uso de um computed value que faz emit("update:modelValue", v) e emit("change", v) — assim qualquer v-model no pai funciona como esperado.
|
||||||
|
* Normalização de props.options para aceitar objetos { label, value, disabled } ou primitivos ('A', 1).
|
||||||
|
* Separação clara entre lógica de formatação (aplicada em onInput) e componentes que não devem ser formatados (ex.: v-select).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tipagem (TypeScript)
|
||||||
|
|
||||||
|
```ts
|
||||||
|
type ValorCampo = string | number | boolean | null;
|
||||||
|
type Option = { label: string; value: ValorCampo; disabled?: boolean };
|
||||||
|
|
||||||
|
type InputVariant = 'outlined' | 'filled' | 'plain' | 'solo' | 'solo-filled' | 'solo-inverted' | 'underlined';
|
||||||
|
type Density = 'default' | 'comfortable' | 'compact';
|
||||||
|
type TipoNumerico = 'numericoInteiro' | 'numericoDecimal' | 'numericoMoeda' | 'porcentagem';
|
||||||
|
|
||||||
|
type InputType =
|
||||||
|
| 'text' | 'password' | 'email' | 'search' | 'url' | 'textarea'
|
||||||
|
| 'radio' | 'checkbox' | 'telefone' | 'cpfCnpj' | 'cep' | 'select'
|
||||||
|
| TipoNumerico;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Props
|
||||||
|
|
||||||
|
| Prop | Tipo | Default | Descrição |
|
||||||
|
| ---------------- | --------------------------- | --------------- | ------------------------------------------------------ |
|
||||||
|
| `modelValue` | `string \| number \| boolean \| (string \| number \| boolean \| null)[]` | `""` | Valor controlado (use com `v-model`). |
|
||||||
|
| `type` | `InputType` | `"text"` | Tipo do controle (ver `InputType`). |
|
||||||
|
| `label` | `string` | `-` | Rótulo do campo. |
|
||||||
|
| `placeholder` | `string` | `-` | Texto exibido quando o campo está vazio. |
|
||||||
|
| `disabled` | `boolean` | `false` | Desabilita o campo. |
|
||||||
|
| `error` | `boolean` | `false` | Força estado visual de erro. |
|
||||||
|
| `errorMessages` | `string \| string[]` | `[]` | Mensagem ou lista de mensagens de erro. |
|
||||||
|
| `hint` | `string` | `-` | Texto de ajuda exibido abaixo do campo. |
|
||||||
|
| `persistentHint` | `boolean` | `false` | Mantém o hint sempre visível. |
|
||||||
|
| `variant` | `InputVariant` | `"outlined"` | Variante visual do Vuetify. |
|
||||||
|
| `density` | `Density` | `"comfortable"` | Densidade visual do campo. |
|
||||||
|
| `color` | `string` | `"primary"` | Cor do campo quando focado (ou `error`, se aplicável). |
|
||||||
|
| `clearable` | `boolean` | `false` | Permite limpar o valor do campo. |
|
||||||
|
|
||||||
|
|
||||||
|
## Notas sobre props
|
||||||
|
|
||||||
|
* options: aceita arrays como ['Frontend','Backend'] ou { label:'São Paulo', value:'SP' }. O componente normaliza para { label, value, disabled? }.
|
||||||
|
* type determina quais comportamentos internos são aplicados. Tipos numéricos e máscara (telefone, cpfCnpj, cep) passam por formatação em onInput.
|
||||||
|
* multiple/chips: úteis para type="select". O v-select interno recebe item-title="label" e item-value="value" para compatibilidade com objetos.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Emissões (events)
|
||||||
|
|
||||||
|
* update:modelValue — padrão v-model.
|
||||||
|
* change — emitido sempre que o valor muda (alinha com update:modelValue).
|
||||||
|
* focus — quando o campo interno recebe foco.
|
||||||
|
* blur — quando perde o foco.
|
||||||
|
* Observação: como value é um computed com getter/setter que emite ambos, v-model e listeners de mudança no pai funcionarão normalmente.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Repasso de atributos e listeners
|
||||||
|
|
||||||
|
* O componente define inheritAttrs: false e usa v-bind="attrs" nos componentes internos (v-text-field, v-select, etc.). Isso implica que:
|
||||||
|
* Atributos HTML (ex.: type, aria-label, class, style) passados para <EliInput> são aplicados ao componente Vuetify interno apropriado.
|
||||||
|
* Listeners (ex.: @click, @keydown) também fazem parte de $attrs e serão repassados para o componente interno — use o EliInput como se estivesse ouvindo eventos diretamente no input.
|
||||||
|
|
||||||
|
## Exemplo:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<EliInput type="text" v-model="nome" aria-label="Nome completo" @keydown.enter="enviar" />
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Comportamentos de formatação importantes
|
||||||
|
|
||||||
|
* numericoInteiro — remove tudo que não for dígito.
|
||||||
|
* numericoDecimal — mantém separador decimal (aplica formatarDecimal).
|
||||||
|
* numericoMoeda — formata para moeda conforme util (formatarMoeda).
|
||||||
|
* porcentagem — aplica formatação decimal e exibe sufixo `%` automaticamente.
|
||||||
|
* telefone — aplica máscara/format formatTelefone.
|
||||||
|
* cpfCnpj — aplica formatarCpfCnpj.
|
||||||
|
* cep — aplica formatarCep.
|
||||||
|
|
||||||
|
**Importante: a formatação ocorre no onInput (campos text-like). O v-select não passa por onInput — ele usa v-model="value" e o computed que emite o update. Se desejar formatação específica para itens do select (por exemplo, mostrar label formatado), trate nos options antes de passar.**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Slot
|
||||||
|
|
||||||
|
* O componente não expõe slots customizados diretamente. Ele controla internamente o append para toggle de senha quando type === 'password' && showPasswordToggle (ícone de olho).
|
||||||
|
* Se você precisa de slots específicos do v-text-field/v-select, considere estender o componente ou criar uma variação que exponha os slots desejados.
|
||||||
1
src/componentes/campo/index.ts
Normal file
1
src/componentes/campo/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export { default as EliInput } from "./EliInput.vue";
|
||||||
9
src/componentes/campo/utils/cep.ts
Normal file
9
src/componentes/campo/utils/cep.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { somenteNumeros } from "./numerico";
|
||||||
|
|
||||||
|
export function formatarCep(v: string): string {
|
||||||
|
const d = somenteNumeros(v).slice(0, 8);
|
||||||
|
|
||||||
|
if (d.length <= 5) return d;
|
||||||
|
|
||||||
|
return d.replace(/^(\d{5})(\d{1,3})$/, "$1-$2");
|
||||||
|
}
|
||||||
26
src/componentes/campo/utils/numerico.ts
Normal file
26
src/componentes/campo/utils/numerico.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
export function somenteNumeros(valor: string) {
|
||||||
|
return valor.replace(/\D+/g, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatarDecimal(valor: string) {
|
||||||
|
const limpo = valor.replace(/[^\d,]/g, "");
|
||||||
|
const partes = limpo.split(",");
|
||||||
|
return partes.length > 2 ? partes[0] + "," + partes.slice(1).join("") : limpo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formatação para percentual:
|
||||||
|
* - remove '%' caso venha junto (ex: colar "10%")
|
||||||
|
* - mantém apenas dígitos e vírgula (no máximo uma)
|
||||||
|
*/
|
||||||
|
export function formatarPorcentagem(valor: string) {
|
||||||
|
return formatarDecimal(valor.replace(/%/g, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatarMoeda(valor: string) {
|
||||||
|
const numero = somenteNumeros(valor);
|
||||||
|
if (!numero) return "";
|
||||||
|
|
||||||
|
const inteiro = (parseInt(numero, 10) / 100).toFixed(2);
|
||||||
|
return inteiro.replace(".", ",").replace(/\B(?=(\d{3})+(?!\d))/g, ".");
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
// utils/telefone.ts
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove tudo que não é número
|
* Remove tudo que não é número
|
||||||
*/
|
*/
|
||||||
231
src/componentes/data_hora/EliDataHora.vue
Normal file
231
src/componentes/data_hora/EliDataHora.vue
Normal file
|
|
@ -0,0 +1,231 @@
|
||||||
|
<template>
|
||||||
|
<div class="eli-data-hora">
|
||||||
|
<!--
|
||||||
|
Implementação propositalmente “simples” e estável:
|
||||||
|
- Usa o input nativo `datetime-local` (ou `date`) dentro do v-text-field.
|
||||||
|
- Evita depender de componentes experimentais (labs) do Vuetify.
|
||||||
|
- Recebe ISO 8601 (UTC/offset) e emite ISO 8601 com offset local.
|
||||||
|
|
||||||
|
Observação importante:
|
||||||
|
- `datetime-local` NÃO armazena timezone.
|
||||||
|
- Este componente converte a entrada para local para exibir ao usuário.
|
||||||
|
-->
|
||||||
|
<v-text-field
|
||||||
|
v-model="valor"
|
||||||
|
:type="tipoInput"
|
||||||
|
:label="rotulo"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:disabled="desabilitado"
|
||||||
|
:clearable="limpavel"
|
||||||
|
:error="erro"
|
||||||
|
:error-messages="mensagensErro"
|
||||||
|
:hint="dica"
|
||||||
|
:persistent-hint="dicaPersistente"
|
||||||
|
:density="densidade"
|
||||||
|
:variant="variante"
|
||||||
|
:min="minLocal"
|
||||||
|
:max="maxLocal"
|
||||||
|
v-bind="attrs"
|
||||||
|
@focus="emit('foco')"
|
||||||
|
@blur="emit('desfoco')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { computed, defineComponent, PropType } from "vue";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import type { CampoDensidade, CampoVariante } from "../../tipos";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EliDataHora
|
||||||
|
*
|
||||||
|
* Campo para entrada de data + hora.
|
||||||
|
*
|
||||||
|
* Modelo:
|
||||||
|
* - O componente **recebe** `modelValue` em ISO 8601 (UTC `Z` ou com offset)
|
||||||
|
* - Converte para horário local para exibir (`date` ou `datetime-local`)
|
||||||
|
* - Ao editar, **emite** ISO 8601 com o **offset local**
|
||||||
|
*/
|
||||||
|
export default defineComponent({
|
||||||
|
name: "EliDataHora",
|
||||||
|
inheritAttrs: false,
|
||||||
|
|
||||||
|
props: {
|
||||||
|
/**
|
||||||
|
* Valor em ISO 8601:
|
||||||
|
* - com offset (ex.: `2026-01-09T13:15:00-03:00`)
|
||||||
|
* - ou UTC absoluto (ex.: `2026-01-09T16:15:00Z`)
|
||||||
|
*/
|
||||||
|
modelValue: {
|
||||||
|
type: String as PropType<string | null>,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define o tipo de entrada.
|
||||||
|
* - `dataHora`: usa `datetime-local`
|
||||||
|
* - `data`: usa `date`
|
||||||
|
*/
|
||||||
|
modo: {
|
||||||
|
type: String as PropType<"data" | "dataHora">,
|
||||||
|
default: "dataHora",
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Rótulo exibido no v-text-field (Vuetify). */
|
||||||
|
rotulo: {
|
||||||
|
type: String,
|
||||||
|
default: "Data e hora",
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Placeholder do input. */
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Desabilita a interação. */
|
||||||
|
desabilitado: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Se true, mostra ícone para limpar o valor (Vuetify clearable). */
|
||||||
|
limpavel: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Estado de erro (visual). */
|
||||||
|
erro: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Mensagens de erro. */
|
||||||
|
mensagensErro: {
|
||||||
|
type: [String, Array] as PropType<string | string[]>,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Texto de apoio. */
|
||||||
|
dica: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Mantém a dica sempre visível. */
|
||||||
|
dicaPersistente: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Densidade do campo (Vuetify). */
|
||||||
|
densidade: {
|
||||||
|
type: String as PropType<CampoDensidade>,
|
||||||
|
default: "comfortable",
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Variante do v-text-field (Vuetify). */
|
||||||
|
variante: {
|
||||||
|
type: String as PropType<CampoVariante>,
|
||||||
|
default: "outlined",
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valor mínimo permitido.
|
||||||
|
* ISO 8601 (offset ou `Z`).
|
||||||
|
*/
|
||||||
|
min: {
|
||||||
|
// ISO 8601 (offset ou Z)
|
||||||
|
type: String as PropType<string | undefined>,
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valor máximo permitido.
|
||||||
|
* ISO 8601 (offset ou `Z`).
|
||||||
|
*/
|
||||||
|
max: {
|
||||||
|
// ISO 8601 (offset ou Z)
|
||||||
|
type: String as PropType<string | undefined>,
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
emits: {
|
||||||
|
/** v-model padrão. */
|
||||||
|
"update:modelValue": (_valor: string | null) => true,
|
||||||
|
/** Alias para consumidores que querem um evento semântico. */
|
||||||
|
alterar: (_valor: string | null) => true,
|
||||||
|
foco: () => true,
|
||||||
|
desfoco: () => true,
|
||||||
|
},
|
||||||
|
|
||||||
|
setup(props, { emit, attrs }) {
|
||||||
|
const tipoInput = computed<"date" | "datetime-local">(() =>
|
||||||
|
props.modo === "data" ? "date" : "datetime-local"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Converte ISO (Z/offset) para o formato que o `datetime-local` aceita.
|
||||||
|
function isoParaInputDatetime(valorIso: string): string {
|
||||||
|
// `dayjs(valorIso)` interpreta ISO com timezone e converte para o local do usuário.
|
||||||
|
if (props.modo === "data") {
|
||||||
|
return dayjs(valorIso).format("YYYY-MM-DD");
|
||||||
|
}
|
||||||
|
|
||||||
|
return dayjs(valorIso).format("YYYY-MM-DDTHH:mm");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converte o valor do input (`YYYY-MM-DDTHH:mm`) para ISO 8601 com offset local.
|
||||||
|
function inputDatetimeParaIsoLocal(valorInput: string): string {
|
||||||
|
// `format()` retorna ISO 8601 com offset local.
|
||||||
|
// Em modo `data`, normalizamos para o começo do dia (00:00:00) no fuso local.
|
||||||
|
if (props.modo === "data") {
|
||||||
|
return dayjs(`${valorInput}T00:00`).format();
|
||||||
|
}
|
||||||
|
|
||||||
|
return dayjs(valorInput).format();
|
||||||
|
}
|
||||||
|
|
||||||
|
const valor = computed<string>({
|
||||||
|
get: () => {
|
||||||
|
if (!props.modelValue) return "";
|
||||||
|
return isoParaInputDatetime(props.modelValue);
|
||||||
|
},
|
||||||
|
set: (v) => {
|
||||||
|
// O `datetime-local` entrega string ou "" quando limpo.
|
||||||
|
const normalizado = v && v.length > 0 ? v : null;
|
||||||
|
if (!normalizado) {
|
||||||
|
emit("update:modelValue", null);
|
||||||
|
emit("alterar", null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const valorEmitido = inputDatetimeParaIsoLocal(normalizado);
|
||||||
|
emit("update:modelValue", valorEmitido);
|
||||||
|
emit("alterar", valorEmitido);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const minLocal = computed<string | undefined>(() => {
|
||||||
|
if (!props.min) return undefined;
|
||||||
|
return isoParaInputDatetime(props.min);
|
||||||
|
});
|
||||||
|
|
||||||
|
const maxLocal = computed<string | undefined>(() => {
|
||||||
|
if (!props.max) return undefined;
|
||||||
|
return isoParaInputDatetime(props.max);
|
||||||
|
});
|
||||||
|
|
||||||
|
return { attrs, valor, emit, minLocal, maxLocal, tipoInput };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.eli-data-hora {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
108
src/componentes/data_hora/README.md
Normal file
108
src/componentes/data_hora/README.md
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
# EliDataHora
|
||||||
|
|
||||||
|
O `EliDataHora` é um componente de **entrada de data e hora** baseado em `v-text-field` (Vuetify), usando o tipo nativo do HTML `datetime-local`.
|
||||||
|
|
||||||
|
Ele foi criado para oferecer uma solução **estável e leve** sem depender de componentes experimentais do Vuetify.
|
||||||
|
|
||||||
|
## Objetivo
|
||||||
|
|
||||||
|
- Permitir o usuário selecionar **data + hora** com UX nativa do navegador.
|
||||||
|
- Padronizar a API em português (props/eventos) no Design System.
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
### Props
|
||||||
|
|
||||||
|
| Prop | Tipo | Padrão | Descrição |
|
||||||
|
|------|------|--------|-----------|
|
||||||
|
| `modelValue` | `string \| null` | `null` | **Sempre em ISO 8601**, aceitando UTC absoluto (`Z`) ou com offset (ex.: `2026-01-09T16:15:00Z`, `2026-01-09T13:15:00-03:00`). O componente converte para horário **local** antes de exibir. |
|
||||||
|
| `modo` | `"data" \| "dataHora"` | `"dataHora"` | Define se o campo permite selecionar apenas data (`date`) ou data+hora (`datetime-local`). |
|
||||||
|
| `rotulo` | `string` | `"Data e hora"` | Label do campo. |
|
||||||
|
| `placeholder` | `string` | `""` | Placeholder do campo. |
|
||||||
|
| `desabilitado` | `boolean` | `false` | Desabilita o campo. |
|
||||||
|
| `limpavel` | `boolean` | `false` | Habilita botão de limpar (Vuetify `clearable`). |
|
||||||
|
| `erro` | `boolean` | `false` | Estado de erro visual. |
|
||||||
|
| `mensagensErro` | `string \| string[]` | `[]` | Mensagens de erro. |
|
||||||
|
| `dica` | `string` | `""` | Hint/ajuda abaixo do campo. |
|
||||||
|
| `dicaPersistente` | `boolean` | `false` | Mantém dica sempre visível. |
|
||||||
|
| `densidade` | `CampoDensidade` | `"comfortable"` | Densidade (Vuetify). |
|
||||||
|
| `variante` | `CampoVariante` | `"outlined"` | Variante (Vuetify). |
|
||||||
|
| `min` | `string \| undefined` | `undefined` | Mínimo permitido em ISO 8601 (offset ou `Z`). |
|
||||||
|
| `max` | `string \| undefined` | `undefined` | Máximo permitido em ISO 8601 (offset ou `Z`). |
|
||||||
|
|
||||||
|
> Observação: o atributo HTML `datetime-local` **não inclui timezone**.
|
||||||
|
> Este componente resolve isso convertendo:
|
||||||
|
>
|
||||||
|
> - **entrada**: ISO 8601 (UTC/offset) → **exibição** em horário local
|
||||||
|
> - **saída**: valor selecionado → ISO 8601 com **offset local**
|
||||||
|
|
||||||
|
### Emits
|
||||||
|
|
||||||
|
| Evento | Payload | Quando dispara |
|
||||||
|
|--------|---------|---------------|
|
||||||
|
| `update:modelValue` | `string \| null` | Sempre que o valor muda (padrão do v-model). O payload é ISO 8601 com **offset local**. |
|
||||||
|
| `alterar` | `string \| null` | Alias semântico para mudanças de valor (mesmo payload do v-model). |
|
||||||
|
| `foco` | `void` | Ao focar o campo. |
|
||||||
|
| `desfoco` | `void` | Ao sair do foco. |
|
||||||
|
|
||||||
|
### Slots
|
||||||
|
|
||||||
|
Este componente não define slots próprios. Você pode usar slots do `v-text-field` via `v-bind="$attrs"` caso precise (ver exemplos abaixo).
|
||||||
|
|
||||||
|
## Exemplos
|
||||||
|
|
||||||
|
### 1) Uso básico com v-model
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<EliDataHora v-model="dataHora" />
|
||||||
|
<div class="text-caption">Valor: {{ dataHora }}</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, ref } from "vue";
|
||||||
|
import { EliDataHora } from "eli-vue";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
components: { EliDataHora },
|
||||||
|
setup() {
|
||||||
|
const dataHora = ref<string | null>("2026-01-09T16:15:00Z");
|
||||||
|
return { dataHora };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2) Com limites (min/max) e validação visual
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<EliDataHora
|
||||||
|
v-model="dataHora"
|
||||||
|
rotulo="Agendar"
|
||||||
|
:min="min"
|
||||||
|
:max="max"
|
||||||
|
:erro="!dataHora"
|
||||||
|
:mensagensErro="!dataHora ? ['Obrigatório'] : []"
|
||||||
|
limpavel
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Casos de borda / comportamento esperado
|
||||||
|
|
||||||
|
- Ao limpar o campo, o componente emite `null` (não string vazia).
|
||||||
|
- O navegador pode variar a UI do seletor (isso é esperado do `datetime-local`).
|
||||||
|
- `min/max` devem ser strings em ISO 8601 (offset ou `Z`).
|
||||||
|
- Em `modo="data"`, o componente emite ISO no **início do dia** (`00:00:00`) no fuso local.
|
||||||
|
|
||||||
|
## Acessibilidade
|
||||||
|
|
||||||
|
- O `v-text-field` do Vuetify já oferece base de acessibilidade.
|
||||||
|
- Sempre prefira passar `rotulo` significativo.
|
||||||
|
|
||||||
|
## Decisões de implementação
|
||||||
|
|
||||||
|
- Usamos `datetime-local` por ser amplamente suportado e não depender de APIs experimentais.
|
||||||
|
- O componente usa `dayjs` para converter entradas UTC/offset para local antes de exibir e para emitir ISO 8601 com offset local.
|
||||||
|
- Mantemos o valor como `string | null` para evitar conversões implícitas e permitir que cada projeto decida como persistir (UTC/local).
|
||||||
1
src/componentes/data_hora/index.ts
Normal file
1
src/componentes/data_hora/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export { default as EliDataHora } from "./EliDataHora.vue";
|
||||||
|
|
@ -11,31 +11,100 @@
|
||||||
|
|
||||||
<div class="grid-example">
|
<div class="grid-example">
|
||||||
<!-- text normal -->
|
<!-- text normal -->
|
||||||
|
<EliInput
|
||||||
<EliEntradaTexto
|
v-model="nome"
|
||||||
v-model:value="nome"
|
label="Nome"
|
||||||
:opcoes="{ rotulo: 'Nome', placeholder: 'Digite o nome' }"
|
placeholder="Digite o nome"
|
||||||
density="compact"
|
density="compact"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<EliEntradaTexto
|
<EliInput
|
||||||
v-model:value="telefone"
|
v-model="idade"
|
||||||
:opcoes="{ rotulo: 'Telefone', formato: 'telefone' }"
|
type="numericoInteiro"
|
||||||
|
label="Idade"
|
||||||
|
density="default"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<EliEntradaTexto
|
<EliInput
|
||||||
v-model:value="cep"
|
v-model="altura"
|
||||||
:opcoes="{ rotulo: 'CEP', placeholder: '00000-000', formato: 'cep' }"
|
type="numericoDecimal"
|
||||||
|
label="Altura"
|
||||||
|
density="comfortable"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<EliEntradaTexto
|
<EliInput v-model="valor" type="numericoMoeda" label="Valor" />
|
||||||
v-model:value="documento"
|
|
||||||
:opcoes="{ rotulo: 'CPF / CNPJ', formato: 'cpfCnpj' }"
|
<EliInput v-model="telefone" type="telefone" label="Telefone" />
|
||||||
|
|
||||||
|
<EliInput
|
||||||
|
v-model="cep"
|
||||||
|
type="cep"
|
||||||
|
label="CEP"
|
||||||
|
placeholder="00000-000"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<EliEntradaTexto
|
<EliInput
|
||||||
v-model:value="email"
|
type="select"
|
||||||
:opcoes="{ rotulo: 'Email', placeholder: 'email@exemplo.com', formato: 'email' }"
|
label="Estado"
|
||||||
|
:options="[
|
||||||
|
{ label: 'São Paulo', value: 'SP' },
|
||||||
|
{ label: 'Rio de Janeiro', value: 'RJ' }
|
||||||
|
]"
|
||||||
|
v-model="estado"
|
||||||
|
multiple
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EliInput v-model="documento" type="cpfCnpj" label="CPF / CNPJ" />
|
||||||
|
|
||||||
|
<EliInput
|
||||||
|
v-model="email"
|
||||||
|
label="Email"
|
||||||
|
placeholder="email@exemplo.com"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EliInput
|
||||||
|
v-model="senha"
|
||||||
|
label="Senha"
|
||||||
|
type="password"
|
||||||
|
:showPasswordToggle="true"
|
||||||
|
placeholder="Digite sua senha"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- textarea -->
|
||||||
|
<EliInput
|
||||||
|
type="textarea"
|
||||||
|
v-model="mensagem"
|
||||||
|
label="Mensagem"
|
||||||
|
:rows="5"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- radio -->
|
||||||
|
<EliInput
|
||||||
|
type="radio"
|
||||||
|
v-model="cor"
|
||||||
|
label="Cor favorita"
|
||||||
|
:options="[
|
||||||
|
{ label: 'Azul', value: 'azul' },
|
||||||
|
{ label: 'Verde', value: 'verde' },
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- checkbox group -->
|
||||||
|
<EliInput
|
||||||
|
type="checkbox"
|
||||||
|
v-model="habilidades"
|
||||||
|
:options="[
|
||||||
|
{ label: 'Vue', value: 'vue' },
|
||||||
|
{ label: 'React', value: 'react' },
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- erro -->
|
||||||
|
<EliInput
|
||||||
|
v-model="nome"
|
||||||
|
label="Nome"
|
||||||
|
:error="true"
|
||||||
|
:error-messages="['Obrigatório']"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
|
|
@ -52,27 +121,45 @@
|
||||||
import { defineComponent, ref } from "vue";
|
import { defineComponent, ref } from "vue";
|
||||||
import EliBotao from "../botao/EliBotao.vue";
|
import EliBotao from "../botao/EliBotao.vue";
|
||||||
import EliBadge from "../indicador/EliBadge.vue";
|
import EliBadge from "../indicador/EliBadge.vue";
|
||||||
import EliEntradaTexto from "../EliEntrada/EliEntradaTexto.vue";
|
import EliInput from "../campo/EliInput.vue";
|
||||||
|
|
||||||
|
type Habilidade = "vue" | "react";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "EliOlaMundo",
|
name: "EliOlaMundo",
|
||||||
components: {
|
components: {
|
||||||
EliBotao,
|
EliBotao,
|
||||||
EliBadge,
|
EliBadge,
|
||||||
EliEntradaTexto,
|
EliInput,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const nome = ref("");
|
const nome = ref("");
|
||||||
|
const estado = ref<string[]>([]);
|
||||||
const cep = ref("");
|
const cep = ref("");
|
||||||
const telefone = ref("");
|
const telefone = ref("");
|
||||||
|
const idade = ref("");
|
||||||
|
const altura = ref("");
|
||||||
|
const valor = ref("");
|
||||||
const email = ref("");
|
const email = ref("");
|
||||||
|
const mensagem = ref("");
|
||||||
|
const senha = ref("");
|
||||||
const documento = ref("");
|
const documento = ref("");
|
||||||
|
const cor = ref<"azul" | "verde" | null>(null);
|
||||||
|
const habilidades = ref<Habilidade[]>([]);
|
||||||
return {
|
return {
|
||||||
nome,
|
nome,
|
||||||
email,
|
email,
|
||||||
documento,
|
documento,
|
||||||
|
estado,
|
||||||
telefone,
|
telefone,
|
||||||
|
mensagem,
|
||||||
|
senha,
|
||||||
|
cor,
|
||||||
|
habilidades,
|
||||||
|
idade,
|
||||||
|
altura,
|
||||||
cep,
|
cep,
|
||||||
|
valor,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
O `EliOlaMundo` é um componente **de exemplo** usado para validar rapidamente o Design System no playground.
|
O `EliOlaMundo` é um componente **de exemplo** usado para validar rapidamente o Design System no playground.
|
||||||
|
|
||||||
> Ele não é um componente “de produto”; ele existe para demonstrar integração com Vuetify e mostrar variações de uso de `EliEntradaTexto`, `EliEntradaNumero`, `EliBotao` e `EliBadge`.
|
> Ele não é um componente “de produto”; ele existe para demonstrar integração com Vuetify e mostrar variações de uso de `EliInput`, `EliBotao` e `EliBadge`.
|
||||||
|
|
||||||
## Estrutura do repositório (padrão)
|
## Estrutura do repositório (padrão)
|
||||||
|
|
||||||
Neste Design System:
|
Neste Design System:
|
||||||
|
|
||||||
- **Pastas e arquivos** (quando aplicável) preferem português: `botao/`, `EliEntrada/`, `indicador/`, etc.
|
- **Pastas e arquivos** (quando aplicável) preferem português: `botao/`, `campo/`, `indicador/`, etc.
|
||||||
- **Componentes** mantêm prefixo técnico `Eli` (PascalCase): `EliBotao`, `EliEntradaTexto`.
|
- **Componentes** mantêm prefixo técnico `Eli` (PascalCase): `EliBotao`, `EliInput`.
|
||||||
|
|
||||||
Exemplo:
|
Exemplo:
|
||||||
|
|
||||||
|
|
@ -19,10 +19,9 @@ src/componentes/
|
||||||
EliBotao.vue
|
EliBotao.vue
|
||||||
index.ts
|
index.ts
|
||||||
README.md
|
README.md
|
||||||
EliEntrada/
|
campo/
|
||||||
EliEntradaTexto.vue
|
EliInput.vue
|
||||||
EliEntradaNumero.vue
|
index.ts
|
||||||
EliEntradaDataHora.vue
|
|
||||||
README.md
|
README.md
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,26 @@
|
||||||
background: rgba(0, 0, 0, 0.03);
|
background: rgba(0, 0, 0, 0.03);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.eli-tabela__celula--esquerda {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__celula--centro {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__celula--direita {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eli-tabela__celula-conteudo {
|
||||||
|
display: inline-block;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
.eli-tabela--erro {
|
.eli-tabela--erro {
|
||||||
border: 1px solid rgba(220, 53, 69, 0.35);
|
border: 1px solid rgba(220, 53, 69, 0.35);
|
||||||
|
|
@ -13,32 +13,20 @@
|
||||||
<EliTabelaCabecalho
|
<EliTabelaCabecalho
|
||||||
v-if="exibirBusca || temAcoesCabecalho"
|
v-if="exibirBusca || temAcoesCabecalho"
|
||||||
:exibirBusca="exibirBusca"
|
:exibirBusca="exibirBusca"
|
||||||
:exibirBotaoFiltroAvancado="exibirFiltroAvancado"
|
|
||||||
:valorBusca="valorBusca"
|
:valorBusca="valorBusca"
|
||||||
:acoesCabecalho="acoesCabecalho"
|
:acoesCabecalho="acoesCabecalho"
|
||||||
@buscar="atualizarBusca"
|
@buscar="atualizarBusca"
|
||||||
@colunas="abrirModalColunas"
|
@colunas="abrirModalColunas"
|
||||||
@filtroAvancado="abrirModalFiltro"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<EliTabelaModalColunas
|
<EliTabelaModalColunas
|
||||||
:aberto="modalColunasAberto"
|
:aberto="modalColunasAberto"
|
||||||
:rotulosColunas="rotulosColunas"
|
:rotulosColunas="rotulosColunas"
|
||||||
:configInicial="configColunas"
|
:configInicial="configColunas"
|
||||||
:colunas="tabela.colunas"
|
|
||||||
@fechar="fecharModalColunas"
|
@fechar="fecharModalColunas"
|
||||||
@salvar="salvarModalColunas"
|
@salvar="salvarModalColunas"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<EliTabelaModalFiltroAvancado
|
|
||||||
:aberto="modalFiltroAberto"
|
|
||||||
:filtrosBase="tabela.filtroAvancado ?? []"
|
|
||||||
:modelo="filtrosUi"
|
|
||||||
@fechar="fecharModalFiltro"
|
|
||||||
@limpar="limparFiltrosAvancados"
|
|
||||||
@salvar="salvarFiltrosAvancados"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<table class="eli-tabela__table">
|
<table class="eli-tabela__table">
|
||||||
<EliTabelaHead
|
<EliTabelaHead
|
||||||
:colunas="colunasEfetivas"
|
:colunas="colunasEfetivas"
|
||||||
|
|
@ -54,7 +42,7 @@
|
||||||
:colunasInvisiveis="colunasInvisiveisEfetivas"
|
:colunasInvisiveis="colunasInvisiveisEfetivas"
|
||||||
:temColunasInvisiveis="temColunasInvisiveis"
|
:temColunasInvisiveis="temColunasInvisiveis"
|
||||||
:linhasExpandidas="linhasExpandidas"
|
:linhasExpandidas="linhasExpandidas"
|
||||||
:linhas="linhasPaginadas"
|
:linhas="linhas"
|
||||||
:temAcoes="temAcoes"
|
:temAcoes="temAcoes"
|
||||||
:menuAberto="menuAberto"
|
:menuAberto="menuAberto"
|
||||||
:possuiAcoes="possuiAcoes"
|
:possuiAcoes="possuiAcoes"
|
||||||
|
|
@ -68,12 +56,12 @@
|
||||||
:menuAberto="menuAberto"
|
:menuAberto="menuAberto"
|
||||||
:posicao="menuPopupPos"
|
:posicao="menuPopupPos"
|
||||||
:acoes="menuAberto === null ? [] : acoesDisponiveisPorLinha(menuAberto)"
|
:acoes="menuAberto === null ? [] : acoesDisponiveisPorLinha(menuAberto)"
|
||||||
:linha="menuAberto === null ? null : linhasPaginadas[menuAberto]"
|
:linha="menuAberto === null ? null : linhas[menuAberto]"
|
||||||
@executar="({ acao, linha }) => { menuAberto = null; acao.acao(linha as never); }"
|
@executar="({ acao, linha }) => { menuAberto = null; acao.acao(linha as never); }"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<EliTabelaPaginacao
|
<EliTabelaPaginacao
|
||||||
v-if="totalPaginas > 1 && quantidadeFiltrada > 0"
|
v-if="totalPaginas > 1 && quantidade > 0"
|
||||||
:pagina="paginaAtual"
|
:pagina="paginaAtual"
|
||||||
:totalPaginas="totalPaginas"
|
:totalPaginas="totalPaginas"
|
||||||
:maximoBotoes="tabela.maximo_botoes_paginacao"
|
:maximoBotoes="tabela.maximo_botoes_paginacao"
|
||||||
|
|
@ -110,24 +98,15 @@ import EliTabelaBody from "./EliTabelaBody.vue";
|
||||||
import EliTabelaMenuAcoes from "./EliTabelaMenuAcoes.vue";
|
import EliTabelaMenuAcoes from "./EliTabelaMenuAcoes.vue";
|
||||||
import EliTabelaPaginacao from "./EliTabelaPaginacao.vue";
|
import EliTabelaPaginacao from "./EliTabelaPaginacao.vue";
|
||||||
import EliTabelaModalColunas from "./EliTabelaModalColunas.vue";
|
import EliTabelaModalColunas from "./EliTabelaModalColunas.vue";
|
||||||
import EliTabelaModalFiltroAvancado from "./EliTabelaModalFiltroAvancado.vue";
|
|
||||||
import type { EliColuna } from "./types-eli-tabela";
|
import type { EliColuna } from "./types-eli-tabela";
|
||||||
/** Tipos da configuração/contrato da tabela */
|
/** Tipos da configuração/contrato da tabela */
|
||||||
import type { EliTabelaConsulta } from "./types-eli-tabela";
|
import type { EliTabelaConsulta } from "./types-eli-tabela";
|
||||||
import type { tipoFiltro } from "./types-eli-tabela";
|
|
||||||
// operadores usados no tipo de configuração; o operador aplicado vem travado no filtroAvancado.
|
|
||||||
import {
|
import {
|
||||||
carregarConfigColunas,
|
carregarConfigColunas,
|
||||||
salvarConfigColunas,
|
salvarConfigColunas,
|
||||||
type EliTabelaColunasConfig,
|
type EliTabelaColunasConfig,
|
||||||
} from "./colunasStorage";
|
} from "./colunasStorage";
|
||||||
|
|
||||||
import {
|
|
||||||
carregarFiltroAvancado,
|
|
||||||
salvarFiltroAvancado,
|
|
||||||
limparFiltroAvancado,
|
|
||||||
} from "./filtroAvancadoStorage";
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "EliTabela",
|
name: "EliTabela",
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
|
|
@ -140,7 +119,6 @@ export default defineComponent({
|
||||||
EliTabelaMenuAcoes,
|
EliTabelaMenuAcoes,
|
||||||
EliTabelaPaginacao,
|
EliTabelaPaginacao,
|
||||||
EliTabelaModalColunas,
|
EliTabelaModalColunas,
|
||||||
EliTabelaModalFiltroAvancado,
|
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
/** Configuração principal da tabela (colunas, consulta e ações) */
|
/** Configuração principal da tabela (colunas, consulta e ações) */
|
||||||
|
|
@ -172,56 +150,6 @@ export default defineComponent({
|
||||||
const colunaOrdenacao = ref<string | null>(null);
|
const colunaOrdenacao = ref<string | null>(null);
|
||||||
const direcaoOrdenacao = ref<"asc" | "desc">("asc");
|
const direcaoOrdenacao = ref<"asc" | "desc">("asc");
|
||||||
|
|
||||||
/** Filtro avançado (config + estado modal) */
|
|
||||||
const modalFiltroAberto = ref(false);
|
|
||||||
type LinhaFiltroUI<T> = {
|
|
||||||
coluna: keyof T;
|
|
||||||
valor: any;
|
|
||||||
};
|
|
||||||
|
|
||||||
const filtrosUi = ref<Array<LinhaFiltroUI<any>>>(carregarFiltroAvancado<any>(props.tabela.nome) as any);
|
|
||||||
|
|
||||||
function abrirModalFiltro() {
|
|
||||||
modalFiltroAberto.value = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fecharModalFiltro() {
|
|
||||||
modalFiltroAberto.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function limparFiltrosAvancados() {
|
|
||||||
filtrosUi.value = [];
|
|
||||||
limparFiltroAvancado(props.tabela.nome);
|
|
||||||
modalFiltroAberto.value = false;
|
|
||||||
if (paginaAtual.value !== 1) paginaAtual.value = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
function salvarFiltrosAvancados(novo: any[]) {
|
|
||||||
filtrosUi.value = (novo ?? []) as any;
|
|
||||||
salvarFiltroAvancado(props.tabela.nome, (novo ?? []) as any);
|
|
||||||
modalFiltroAberto.value = false;
|
|
||||||
if (paginaAtual.value !== 1) paginaAtual.value = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const filtrosAvancadosAtivos = computed<tipoFiltro[]>(() => {
|
|
||||||
// Operador vem travado na definição (`tabela.filtroAvancado`).
|
|
||||||
const base = (props.tabela.filtroAvancado ?? []) as Array<{ coluna: string; operador: any }>;
|
|
||||||
|
|
||||||
return (filtrosUi.value ?? [])
|
|
||||||
.filter((f) => f && f.coluna !== undefined)
|
|
||||||
.map((f) => {
|
|
||||||
const b = base.find((x) => String(x.coluna) === String(f.coluna));
|
|
||||||
if (!b) return null;
|
|
||||||
|
|
||||||
return {
|
|
||||||
coluna: String(b.coluna),
|
|
||||||
operador: b.operador as any,
|
|
||||||
valor: (f as any).valor,
|
|
||||||
} as tipoFiltro;
|
|
||||||
})
|
|
||||||
.filter(Boolean) as tipoFiltro[];
|
|
||||||
});
|
|
||||||
|
|
||||||
/** Alias reativo da prop tabela */
|
/** Alias reativo da prop tabela */
|
||||||
const tabela = computed(() => props.tabela);
|
const tabela = computed(() => props.tabela);
|
||||||
|
|
||||||
|
|
@ -243,20 +171,11 @@ export default defineComponent({
|
||||||
|
|
||||||
const colunasInvisiveisEfetivas = computed(() => {
|
const colunasInvisiveisEfetivas = computed(() => {
|
||||||
const colunas = props.tabela.colunas as Array<EliColuna<any>>;
|
const colunas = props.tabela.colunas as Array<EliColuna<any>>;
|
||||||
|
const invisiveisSet = new Set(configColunas.value.invisiveis ?? []);
|
||||||
const configTemDados =
|
|
||||||
(configColunas.value.visiveis?.length ?? 0) > 0 ||
|
|
||||||
(configColunas.value.invisiveis?.length ?? 0) > 0;
|
|
||||||
|
|
||||||
const invisiveisBaseRotulos = configTemDados
|
|
||||||
? configColunas.value.invisiveis ?? []
|
|
||||||
: colunas.filter((c) => c.visivel === false).map((c) => c.rotulo);
|
|
||||||
|
|
||||||
const invisiveisSet = new Set(invisiveisBaseRotulos);
|
|
||||||
const base = colunas.filter((c) => invisiveisSet.has(c.rotulo));
|
const base = colunas.filter((c) => invisiveisSet.has(c.rotulo));
|
||||||
|
|
||||||
// ordenação: usa a lista (salva ou derivada do default) e adiciona novas ao final
|
// ordenação: usa a lista salva de invisíveis (se existir), senão segue ordem original
|
||||||
const ordemSalva = invisiveisBaseRotulos;
|
const ordemSalva = configColunas.value.invisiveis ?? [];
|
||||||
const mapa = new Map<string, EliColuna<any>>();
|
const mapa = new Map<string, EliColuna<any>>();
|
||||||
for (const c of base) {
|
for (const c of base) {
|
||||||
if (!mapa.has(c.rotulo)) mapa.set(c.rotulo, c);
|
if (!mapa.has(c.rotulo)) mapa.set(c.rotulo, c);
|
||||||
|
|
@ -279,25 +198,14 @@ export default defineComponent({
|
||||||
const colunasEfetivas = computed(() => {
|
const colunasEfetivas = computed(() => {
|
||||||
const colunas = props.tabela.colunas;
|
const colunas = props.tabela.colunas;
|
||||||
const todosRotulos = rotulosColunas.value;
|
const todosRotulos = rotulosColunas.value;
|
||||||
|
const invisiveisSet = new Set(configColunas.value.invisiveis ?? []);
|
||||||
|
|
||||||
const configTemDados =
|
// default: todas visiveis; so some se estiver explicitamente em invisiveis
|
||||||
(configColunas.value.visiveis?.length ?? 0) > 0 ||
|
|
||||||
(configColunas.value.invisiveis?.length ?? 0) > 0;
|
|
||||||
|
|
||||||
const invisiveisBaseRotulos = configTemDados
|
|
||||||
? configColunas.value.invisiveis ?? []
|
|
||||||
: (props.tabela.colunas as Array<EliColuna<any>>)
|
|
||||||
.filter((c) => c.visivel === false)
|
|
||||||
.map((c) => c.rotulo);
|
|
||||||
|
|
||||||
const invisiveisSet = new Set(invisiveisBaseRotulos);
|
|
||||||
|
|
||||||
// base visiveis: remove invisiveis
|
|
||||||
const visiveisBaseRotulos = todosRotulos.filter((r) => !invisiveisSet.has(r));
|
const visiveisBaseRotulos = todosRotulos.filter((r) => !invisiveisSet.has(r));
|
||||||
const visiveisSet = new Set(visiveisBaseRotulos);
|
const visiveisSet = new Set(visiveisBaseRotulos);
|
||||||
|
|
||||||
// aplica ordem salva; novas (sem definicao) entram no fim, respeitando ordem original
|
// aplica ordem salva; novas (sem definicao) entram no fim, respeitando ordem original
|
||||||
const ordemSalva = configTemDados ? configColunas.value.visiveis ?? [] : [];
|
const ordemSalva = configColunas.value.visiveis ?? [];
|
||||||
const ordemFinal: string[] = [];
|
const ordemFinal: string[] = [];
|
||||||
|
|
||||||
for (const r of ordemSalva) {
|
for (const r of ordemSalva) {
|
||||||
|
|
@ -351,91 +259,20 @@ export default defineComponent({
|
||||||
return 10;
|
return 10;
|
||||||
});
|
});
|
||||||
|
|
||||||
function aplicarFiltroTexto(linhasIn: unknown[]) {
|
/** Total de páginas calculado com base na quantidade */
|
||||||
const q = (valorBusca.value ?? "").trim().toLowerCase();
|
|
||||||
if (!q) return linhasIn;
|
|
||||||
// filtro simples: stringifica o objeto
|
|
||||||
return linhasIn.filter((l) => JSON.stringify(l).toLowerCase().includes(q));
|
|
||||||
}
|
|
||||||
|
|
||||||
function compararOperador(operador: string, valorLinha: any, valorFiltro: any): boolean {
|
|
||||||
switch (operador) {
|
|
||||||
case "=":
|
|
||||||
return valorLinha == valorFiltro;
|
|
||||||
case "!=":
|
|
||||||
return valorLinha != valorFiltro;
|
|
||||||
case ">":
|
|
||||||
return Number(valorLinha) > Number(valorFiltro);
|
|
||||||
case ">=":
|
|
||||||
return Number(valorLinha) >= Number(valorFiltro);
|
|
||||||
case "<":
|
|
||||||
return Number(valorLinha) < Number(valorFiltro);
|
|
||||||
case "<=":
|
|
||||||
return Number(valorLinha) <= Number(valorFiltro);
|
|
||||||
case "like": {
|
|
||||||
const a = String(valorLinha ?? "").toLowerCase();
|
|
||||||
const b = String(valorFiltro ?? "").toLowerCase();
|
|
||||||
return a.includes(b);
|
|
||||||
}
|
|
||||||
case "in": {
|
|
||||||
// aceita "a,b,c" ou array
|
|
||||||
const arr = Array.isArray(valorFiltro)
|
|
||||||
? valorFiltro
|
|
||||||
: String(valorFiltro ?? "")
|
|
||||||
.split(",")
|
|
||||||
.map((s) => s.trim())
|
|
||||||
.filter(Boolean);
|
|
||||||
return arr.includes(String(valorLinha));
|
|
||||||
}
|
|
||||||
case "isNull":
|
|
||||||
return valorLinha === null || valorLinha === undefined || valorLinha === "";
|
|
||||||
default:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function aplicarFiltroAvancado(linhasIn: unknown[]) {
|
|
||||||
const filtros = filtrosAvancadosAtivos.value;
|
|
||||||
if (!filtros.length) return linhasIn;
|
|
||||||
|
|
||||||
return linhasIn.filter((l: any) => {
|
|
||||||
return filtros.every((f) => {
|
|
||||||
const vLinha = l?.[f.coluna as any];
|
|
||||||
return compararOperador(String(f.operador), vLinha, (f as any).valor);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const linhasFiltradas = computed(() => {
|
|
||||||
const base = linhas.value ?? [];
|
|
||||||
return aplicarFiltroAvancado(aplicarFiltroTexto(base));
|
|
||||||
});
|
|
||||||
|
|
||||||
/** Quantidade agora segue a filtragem local */
|
|
||||||
const quantidadeFiltrada = computed(() => linhasFiltradas.value.length);
|
|
||||||
|
|
||||||
/** Total de páginas calculado com base no filtrado */
|
|
||||||
const totalPaginas = computed(() => {
|
const totalPaginas = computed(() => {
|
||||||
const limite = registrosPorConsulta.value;
|
const limite = registrosPorConsulta.value;
|
||||||
if (!limite || limite <= 0) return 1;
|
if (!limite || limite <= 0) return 1;
|
||||||
|
|
||||||
const total = quantidadeFiltrada.value;
|
const total = quantidade.value;
|
||||||
if (!total) return 1;
|
if (!total) return 1;
|
||||||
|
|
||||||
return Math.max(1, Math.ceil(total / limite));
|
return Math.max(1, Math.ceil(total / limite));
|
||||||
});
|
});
|
||||||
|
|
||||||
const linhasPaginadas = computed(() => {
|
|
||||||
const limite = Math.max(1, registrosPorConsulta.value);
|
|
||||||
const offset = (paginaAtual.value - 1) * limite;
|
|
||||||
return linhasFiltradas.value.slice(offset, offset + limite);
|
|
||||||
});
|
|
||||||
|
|
||||||
/** Indica se existem ações por linha */
|
/** Indica se existem ações por linha */
|
||||||
const temAcoes = computed(() => (props.tabela.acoesLinha ?? []).length > 0);
|
const temAcoes = computed(() => (props.tabela.acoesLinha ?? []).length > 0);
|
||||||
|
|
||||||
const exibirFiltroAvancado = computed(() => (props.tabela.filtroAvancado ?? []).length > 0);
|
|
||||||
|
|
||||||
/** Sequencial para evitar race conditions entre consultas */
|
/** Sequencial para evitar race conditions entre consultas */
|
||||||
let carregamentoSequencial = 0;
|
let carregamentoSequencial = 0;
|
||||||
|
|
||||||
|
|
@ -594,10 +431,8 @@ export default defineComponent({
|
||||||
menuAberto.value = null;
|
menuAberto.value = null;
|
||||||
linhasExpandidas.value = {};
|
linhasExpandidas.value = {};
|
||||||
|
|
||||||
// Em modo simulação (filtro local), sempre buscamos a lista completa.
|
|
||||||
// A paginação é aplicada APÓS a filtragem.
|
|
||||||
const limite = Math.max(1, registrosPorConsulta.value);
|
const limite = Math.max(1, registrosPorConsulta.value);
|
||||||
const offset = 0;
|
const offset = (paginaAtual.value - 1) * limite;
|
||||||
|
|
||||||
const parametrosConsulta: {
|
const parametrosConsulta: {
|
||||||
coluna_ordem?: never;
|
coluna_ordem?: never;
|
||||||
|
|
@ -607,10 +442,12 @@ export default defineComponent({
|
||||||
texto_busca?: string;
|
texto_busca?: string;
|
||||||
} = {
|
} = {
|
||||||
offSet: offset,
|
offSet: offset,
|
||||||
limit: 999999,
|
limit: limite,
|
||||||
};
|
};
|
||||||
|
|
||||||
// texto_busca ficará somente para filtragem local.
|
if (valorBusca.value) {
|
||||||
|
parametrosConsulta.texto_busca = valorBusca.value;
|
||||||
|
}
|
||||||
|
|
||||||
if (colunaOrdenacao.value) {
|
if (colunaOrdenacao.value) {
|
||||||
parametrosConsulta.coluna_ordem = colunaOrdenacao.value as never;
|
parametrosConsulta.coluna_ordem = colunaOrdenacao.value as never;
|
||||||
|
|
@ -631,12 +468,12 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
|
|
||||||
const valores = res.valor?.valores ?? [];
|
const valores = res.valor?.valores ?? [];
|
||||||
const total = valores.length;
|
const total = res.valor?.quantidade ?? valores.length;
|
||||||
|
|
||||||
linhas.value = valores;
|
linhas.value = valores;
|
||||||
quantidade.value = total;
|
quantidade.value = total;
|
||||||
|
|
||||||
const totalPaginasRecalculado = Math.max(1, Math.ceil((quantidadeFiltrada.value || 0) / limite));
|
const totalPaginasRecalculado = Math.max(1, Math.ceil((total || 0) / limite));
|
||||||
if (paginaAtual.value > totalPaginasRecalculado) {
|
if (paginaAtual.value > totalPaginasRecalculado) {
|
||||||
paginaAtual.value = totalPaginasRecalculado;
|
paginaAtual.value = totalPaginasRecalculado;
|
||||||
return;
|
return;
|
||||||
|
|
@ -720,10 +557,7 @@ export default defineComponent({
|
||||||
|
|
||||||
/** Watch: mudança de página dispara nova consulta */
|
/** Watch: mudança de página dispara nova consulta */
|
||||||
watch(paginaAtual, (nova, antiga) => {
|
watch(paginaAtual, (nova, antiga) => {
|
||||||
// paginação local não precisa recarregar
|
if (nova !== antiga) void carregar();
|
||||||
if (nova !== antiga) {
|
|
||||||
// noop
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/** Watch: troca de configuração reseta estados e recarrega */
|
/** Watch: troca de configuração reseta estados e recarrega */
|
||||||
|
|
@ -735,9 +569,7 @@ export default defineComponent({
|
||||||
direcaoOrdenacao.value = "asc";
|
direcaoOrdenacao.value = "asc";
|
||||||
valorBusca.value = "";
|
valorBusca.value = "";
|
||||||
modalColunasAberto.value = false;
|
modalColunasAberto.value = false;
|
||||||
modalFiltroAberto.value = false;
|
|
||||||
configColunas.value = carregarConfigColunas(props.tabela.nome);
|
configColunas.value = carregarConfigColunas(props.tabela.nome);
|
||||||
filtrosUi.value = carregarFiltroAvancado<any>(props.tabela.nome) as any;
|
|
||||||
linhasExpandidas.value = {};
|
linhasExpandidas.value = {};
|
||||||
if (paginaAtual.value !== 1) {
|
if (paginaAtual.value !== 1) {
|
||||||
paginaAtual.value = 1;
|
paginaAtual.value = 1;
|
||||||
|
|
@ -773,8 +605,6 @@ export default defineComponent({
|
||||||
carregando,
|
carregando,
|
||||||
erro,
|
erro,
|
||||||
linhas,
|
linhas,
|
||||||
linhasPaginadas,
|
|
||||||
quantidadeFiltrada,
|
|
||||||
quantidade,
|
quantidade,
|
||||||
menuAberto,
|
menuAberto,
|
||||||
valorBusca,
|
valorBusca,
|
||||||
|
|
@ -785,7 +615,6 @@ export default defineComponent({
|
||||||
|
|
||||||
// computed
|
// computed
|
||||||
exibirBusca,
|
exibirBusca,
|
||||||
exibirFiltroAvancado,
|
|
||||||
acoesCabecalho,
|
acoesCabecalho,
|
||||||
temAcoesCabecalho,
|
temAcoesCabecalho,
|
||||||
temAcoes,
|
temAcoes,
|
||||||
|
|
@ -799,16 +628,9 @@ export default defineComponent({
|
||||||
linhasExpandidas,
|
linhasExpandidas,
|
||||||
|
|
||||||
abrirModalColunas,
|
abrirModalColunas,
|
||||||
abrirModalFiltro,
|
|
||||||
fecharModalColunas,
|
fecharModalColunas,
|
||||||
salvarModalColunas,
|
salvarModalColunas,
|
||||||
|
|
||||||
modalFiltroAberto,
|
|
||||||
filtrosUi,
|
|
||||||
salvarFiltrosAvancados,
|
|
||||||
limparFiltrosAvancados,
|
|
||||||
fecharModalFiltro,
|
|
||||||
|
|
||||||
alternarLinhaExpandida,
|
alternarLinhaExpandida,
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
|
|
@ -29,8 +29,22 @@
|
||||||
v-for="(coluna, j) in colunas"
|
v-for="(coluna, j) in colunas"
|
||||||
:key="`td-${i}-${j}`"
|
:key="`td-${i}-${j}`"
|
||||||
class="eli-tabela__td"
|
class="eli-tabela__td"
|
||||||
|
:class="[
|
||||||
|
coluna.acao ? 'eli-tabela__td--clicavel' : undefined,
|
||||||
|
obterClasseAlinhamento(coluna.alinhamento),
|
||||||
|
]"
|
||||||
|
@click="coluna.acao ? () => coluna.acao?.() : undefined"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
v-if="Boolean(coluna.truncar)"
|
||||||
|
class="eli-tabela__celula-conteudo"
|
||||||
|
:style="coluna.largura_maxima ? { maxWidth: obterMaxWidth(coluna.largura_maxima) } : undefined"
|
||||||
|
:title="obterTooltipCelula(coluna.celula(linha as never))"
|
||||||
>
|
>
|
||||||
<EliTabelaCelula :celula="(coluna.celula(linha as never) as never)" />
|
<EliTabelaCelula :celula="(coluna.celula(linha as never) as never)" />
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<EliTabelaCelula v-else :celula="(coluna.celula(linha as never) as never)" />
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td v-if="temAcoes" class="eli-tabela__td eli-tabela__td--acoes" :key="`td-${i}-acoes`">
|
<td v-if="temAcoes" class="eli-tabela__td eli-tabela__td--acoes" :key="`td-${i}-acoes`">
|
||||||
|
|
@ -131,9 +145,40 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
function obterClasseAlinhamento(alinhamento?: string) {
|
||||||
|
if (alinhamento === "direita") return "eli-tabela__celula--direita";
|
||||||
|
if (alinhamento === "centro") return "eli-tabela__celula--centro";
|
||||||
|
return "eli-tabela__celula--esquerda";
|
||||||
|
}
|
||||||
|
|
||||||
|
function obterMaxWidth(largura?: number | string) {
|
||||||
|
if (largura === undefined || largura === null) return undefined;
|
||||||
|
return typeof largura === "number" ? `${largura}px` : String(largura);
|
||||||
|
}
|
||||||
|
|
||||||
|
function obterTooltipCelula(celula: unknown) {
|
||||||
|
if (!Array.isArray(celula)) return undefined;
|
||||||
|
|
||||||
|
const tipo = celula[0];
|
||||||
|
const dados = celula[1] as any;
|
||||||
|
|
||||||
|
if (tipo === "textoSimples") {
|
||||||
|
return typeof dados?.texto === "string" ? dados.texto : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tipo === "numero") {
|
||||||
|
return typeof dados?.numero === "number" ? String(dados.numero) : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ChevronRight,
|
ChevronRight,
|
||||||
ChevronDown,
|
ChevronDown,
|
||||||
|
obterClasseAlinhamento,
|
||||||
|
obterMaxWidth,
|
||||||
|
obterTooltipCelula,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -10,15 +10,6 @@
|
||||||
>
|
>
|
||||||
Colunas
|
Colunas
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
|
||||||
v-if="exibirBotaoFiltroAvancado"
|
|
||||||
type="button"
|
|
||||||
class="eli-tabela__acoes-cabecalho-botao eli-tabela__acoes-cabecalho-botao--filtro"
|
|
||||||
@click="emitFiltroAvancado"
|
|
||||||
>
|
|
||||||
Filtro
|
|
||||||
</button>
|
|
||||||
<EliTabelaCaixaDeBusca :modelo="valorBusca" @buscar="emitBuscar" />
|
<EliTabelaCaixaDeBusca :modelo="valorBusca" @buscar="emitBuscar" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -62,11 +53,6 @@ export default defineComponent({
|
||||||
required: false,
|
required: false,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
exibirBotaoFiltroAvancado: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
valorBusca: {
|
valorBusca: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
|
|
@ -90,9 +76,6 @@ export default defineComponent({
|
||||||
colunas() {
|
colunas() {
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
filtroAvancado() {
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const temAcoesCabecalho = computed(() => props.acoesCabecalho.length > 0);
|
const temAcoesCabecalho = computed(() => props.acoesCabecalho.length > 0);
|
||||||
|
|
@ -105,11 +88,7 @@ export default defineComponent({
|
||||||
emit("colunas");
|
emit("colunas");
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitFiltroAvancado() {
|
return { temAcoesCabecalho, emitBuscar, emitColunas };
|
||||||
emit("filtroAvancado");
|
|
||||||
}
|
|
||||||
|
|
||||||
return { temAcoesCabecalho, emitBuscar, emitColunas, emitFiltroAvancado };
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -7,7 +7,10 @@
|
||||||
v-for="(coluna, idx) in colunas"
|
v-for="(coluna, idx) in colunas"
|
||||||
:key="`th-${idx}`"
|
:key="`th-${idx}`"
|
||||||
class="eli-tabela__th"
|
class="eli-tabela__th"
|
||||||
:class="[isOrdenavel(coluna) ? 'eli-tabela__th--ordenavel' : undefined]"
|
:class="[
|
||||||
|
isOrdenavel(coluna) ? 'eli-tabela__th--ordenavel' : undefined,
|
||||||
|
obterClasseAlinhamento(coluna.alinhamento),
|
||||||
|
]"
|
||||||
scope="col"
|
scope="col"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
|
@ -88,6 +91,12 @@ export default defineComponent({
|
||||||
return coluna?.coluna_ordem !== undefined && coluna?.coluna_ordem !== null;
|
return coluna?.coluna_ordem !== undefined && coluna?.coluna_ordem !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function obterClasseAlinhamento(alinhamento?: string) {
|
||||||
|
if (alinhamento === "direita") return "eli-tabela__celula--direita";
|
||||||
|
if (alinhamento === "centro") return "eli-tabela__celula--centro";
|
||||||
|
return "eli-tabela__celula--esquerda";
|
||||||
|
}
|
||||||
|
|
||||||
function emitAlternarOrdenacao(chave: string) {
|
function emitAlternarOrdenacao(chave: string) {
|
||||||
emit("alternarOrdenacao", chave);
|
emit("alternarOrdenacao", chave);
|
||||||
}
|
}
|
||||||
|
|
@ -96,6 +105,7 @@ export default defineComponent({
|
||||||
ArrowUp,
|
ArrowUp,
|
||||||
ArrowDown,
|
ArrowDown,
|
||||||
isOrdenavel,
|
isOrdenavel,
|
||||||
|
obterClasseAlinhamento,
|
||||||
emitAlternarOrdenacao,
|
emitAlternarOrdenacao,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
@ -74,7 +74,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, PropType, ref, watch } from "vue";
|
import { defineComponent, PropType, ref, watch } from "vue";
|
||||||
import type { EliTabelaColunasConfig } from "./colunasStorage";
|
import type { EliTabelaColunasConfig } from "./colunasStorage";
|
||||||
import type { EliColuna } from "./types-eli-tabela";
|
|
||||||
|
|
||||||
type OrigemLista = "visiveis" | "invisiveis";
|
type OrigemLista = "visiveis" | "invisiveis";
|
||||||
|
|
||||||
|
|
@ -101,10 +100,6 @@ export default defineComponent({
|
||||||
type: Object as PropType<EliTabelaColunasConfig>,
|
type: Object as PropType<EliTabelaColunasConfig>,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
colunas: {
|
|
||||||
type: Array as PropType<Array<EliColuna<any>>>,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
emits: {
|
emits: {
|
||||||
fechar() {
|
fechar() {
|
||||||
|
|
@ -120,18 +115,9 @@ export default defineComponent({
|
||||||
|
|
||||||
function sincronizarEstado() {
|
function sincronizarEstado() {
|
||||||
const todos = props.rotulosColunas;
|
const todos = props.rotulosColunas;
|
||||||
const configTemDados =
|
const invisiveisSet = new Set(props.configInicial.invisiveis ?? []);
|
||||||
(props.configInicial.visiveis?.length ?? 0) > 0 ||
|
|
||||||
(props.configInicial.invisiveis?.length ?? 0) > 0;
|
|
||||||
|
|
||||||
const invisiveisPadraoSet = new Set(
|
|
||||||
props.colunas.filter((c) => c.visivel === false).map((c) => c.rotulo)
|
|
||||||
);
|
|
||||||
|
|
||||||
const invisiveisSet = configTemDados
|
|
||||||
? new Set(props.configInicial.invisiveis ?? [])
|
|
||||||
: invisiveisPadraoSet;
|
|
||||||
|
|
||||||
|
// default: todas visíveis
|
||||||
const baseVisiveis = todos.filter((r) => !invisiveisSet.has(r));
|
const baseVisiveis = todos.filter((r) => !invisiveisSet.has(r));
|
||||||
|
|
||||||
// ordenação: aplica ordem salva (visiveis) e adiciona novas ao final
|
// ordenação: aplica ordem salva (visiveis) e adiciona novas ao final
|
||||||
|
|
@ -153,7 +139,7 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => [props.aberto, props.rotulosColunas, props.configInicial, props.colunas] as const,
|
() => [props.aberto, props.rotulosColunas, props.configInicial] as const,
|
||||||
() => {
|
() => {
|
||||||
if (props.aberto) sincronizarEstado();
|
if (props.aberto) sincronizarEstado();
|
||||||
},
|
},
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
<template>
|
||||||
|
{{ String(dados?.numero).replace('.', ',') }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, PropType } from "vue"
|
||||||
|
import type { TiposTabelaCelulas } from "./tiposTabelaCelulas";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "EliTabelaCelulaNumero",
|
||||||
|
components: {},
|
||||||
|
props: {
|
||||||
|
dados: {
|
||||||
|
type: Object as PropType<TiposTabelaCelulas["numero"]>,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
},
|
||||||
|
setup({ dados }) {
|
||||||
|
return { dados }
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
<template>
|
||||||
|
{{ dados?.texto }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, PropType } from "vue"
|
||||||
|
import type { TiposTabelaCelulas } from "./tiposTabelaCelulas";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "EliTabelaCelulaTextoSimples",
|
||||||
|
components: {},
|
||||||
|
props: {
|
||||||
|
dados: {
|
||||||
|
type: Object as PropType<TiposTabelaCelulas["textoSimples"]>,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
},
|
||||||
|
setup({ dados }) {
|
||||||
|
return { dados }
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
import type { Component } from "vue";
|
import type { Component } from "vue";
|
||||||
|
|
||||||
import EliTabelaCelulaTextoSimples from "./EliTabelaCelulaTextoSimples.vue";
|
import EliTabelaCelulaTextoSimples from "./EliTabelaCelulaTextoSimples.vue";
|
||||||
import EliTabelaCelulaTextoTruncado from "./EliTabelaCelulaTextoTruncado.vue";
|
|
||||||
import EliTabelaCelulaNumero from "./EliTabelaCelulaNumero.vue";
|
import EliTabelaCelulaNumero from "./EliTabelaCelulaNumero.vue";
|
||||||
import type { TipoTabelaCelula } from "./tiposTabelaCelulas";
|
import type { TipoTabelaCelula } from "./tiposTabelaCelulas";
|
||||||
|
|
||||||
export const registryTabelaCelulas = {
|
export const registryTabelaCelulas = {
|
||||||
textoSimples: EliTabelaCelulaTextoSimples,
|
textoSimples: EliTabelaCelulaTextoSimples,
|
||||||
textoTruncado: EliTabelaCelulaTextoTruncado,
|
|
||||||
numero: EliTabelaCelulaNumero,
|
numero: EliTabelaCelulaNumero,
|
||||||
} as const satisfies Record<TipoTabelaCelula, Component>;
|
} as const satisfies Record<TipoTabelaCelula, Component>;
|
||||||
|
|
@ -7,10 +7,6 @@ export type TiposTabelaCelulas = {
|
||||||
texto: string;
|
texto: string;
|
||||||
acao?: () => void;
|
acao?: () => void;
|
||||||
};
|
};
|
||||||
textoTruncado: {
|
|
||||||
texto: string;
|
|
||||||
acao?: () => void;
|
|
||||||
};
|
|
||||||
numero: {
|
numero: {
|
||||||
numero: number;
|
numero: number;
|
||||||
acao?: () => void;
|
acao?: () => void;
|
||||||
|
|
@ -18,4 +14,3 @@ export type TiposTabelaCelulas = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TipoTabelaCelula = keyof TiposTabelaCelulas;
|
export type TipoTabelaCelula = keyof TiposTabelaCelulas;
|
||||||
|
|
||||||
|
|
@ -1,11 +1,6 @@
|
||||||
import type { tipoResposta } from "p-respostas";
|
import type { tipoResposta } from "p-respostas";
|
||||||
import type { LucideIcon } from "lucide-vue-next";
|
import type { LucideIcon } from "lucide-vue-next";
|
||||||
import type { TipoTabelaCelula, TiposTabelaCelulas } from "./celulas/tiposTabelaCelulas";
|
import type { TipoTabelaCelula, TiposTabelaCelulas } from "./celulas/tiposTabelaCelulas";
|
||||||
import { operadores, zFiltro } from "p-comuns";
|
|
||||||
import { ComponenteEntrada } from "../EliEntrada/tiposEntradas";
|
|
||||||
|
|
||||||
// `p-comuns` expõe `zFiltro` (schema). Inferimos o tipo a partir do `parse`.
|
|
||||||
export type tipoFiltro = ReturnType<(typeof zFiltro)["parse"]>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -29,6 +24,7 @@ export type { TipoTabelaCelula, TiposTabelaCelulas };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export type EliAlinhamentoColuna = "esquerda" | "centro" | "direita";
|
||||||
|
|
||||||
export type EliColuna<T> = {
|
export type EliColuna<T> = {
|
||||||
/** Texto exibido no cabeçalho da coluna. */
|
/** Texto exibido no cabeçalho da coluna. */
|
||||||
|
|
@ -36,18 +32,25 @@ export type EliColuna<T> = {
|
||||||
/** Função responsável por renderizar o conteúdo da célula. */
|
/** Função responsável por renderizar o conteúdo da célula. */
|
||||||
celula: (linha: T) => ComponenteCelula;
|
celula: (linha: T) => ComponenteCelula;
|
||||||
/** Ação opcional disparada ao clicar na célula. */
|
/** Ação opcional disparada ao clicar na célula. */
|
||||||
|
acao?: () => void;
|
||||||
|
/** Alinhamento do conteúdo da coluna (cabeçalho e células). */
|
||||||
|
alinhamento?: EliAlinhamentoColuna;
|
||||||
|
/**
|
||||||
|
* Quando `true`, tenta truncar (ellipsis) conteúdos textuais longos.
|
||||||
|
* Observação: o tooltip automático só é aplicado quando o conteúdo renderizado
|
||||||
|
* da célula é um `string`/`number`.
|
||||||
|
*/
|
||||||
|
truncar?: boolean;
|
||||||
|
/**
|
||||||
|
* Largura máxima usada quando `truncar` estiver ativo.
|
||||||
|
* Exemplos: `240` (px), `"18rem"`, `"30ch"`.
|
||||||
|
*/
|
||||||
|
largura_maxima?: number | string;
|
||||||
/**
|
/**
|
||||||
* Campo de ordenação associado à coluna. Caso informado, a coluna passa a
|
* Campo de ordenação associado à coluna. Caso informado, a coluna passa a
|
||||||
* exibir controles de ordenação e utiliza o valor como chave para o backend.
|
* exibir controles de ordenação e utiliza o valor como chave para o backend.
|
||||||
*/
|
*/
|
||||||
coluna_ordem?: keyof T;
|
coluna_ordem?: keyof T;
|
||||||
|
|
||||||
/**
|
|
||||||
* indica que a coluna será visivel, se false incia em detalhe
|
|
||||||
* Caso já tenha salvo a propriedade de visibilidade será adotado a propriedade salva
|
|
||||||
*/
|
|
||||||
visivel: boolean
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EliConsultaPaginada<T> = {
|
export type EliConsultaPaginada<T> = {
|
||||||
|
|
@ -95,10 +98,6 @@ export type EliTabelaConsulta<T> = {
|
||||||
* ordenação (`coluna_ordem`/`direcao_ordem`) e paginação (`offSet`/`limit`).
|
* ordenação (`coluna_ordem`/`direcao_ordem`) e paginação (`offSet`/`limit`).
|
||||||
*/
|
*/
|
||||||
consulta: (parametrosConsulta?: {
|
consulta: (parametrosConsulta?: {
|
||||||
|
|
||||||
//Todo: Esse filtros são recebido do processamento de filtro avandado
|
|
||||||
|
|
||||||
filtros?: tipoFiltro[]
|
|
||||||
coluna_ordem?: keyof T;
|
coluna_ordem?: keyof T;
|
||||||
direcao_ordem?: "asc" | "desc";
|
direcao_ordem?: "asc" | "desc";
|
||||||
offSet?: number;
|
offSet?: number;
|
||||||
|
|
@ -126,18 +125,5 @@ export type EliTabelaConsulta<T> = {
|
||||||
/** Função executada ao clicar no botão. */
|
/** Função executada ao clicar no botão. */
|
||||||
acao: () => void;
|
acao: () => void;
|
||||||
}[];
|
}[];
|
||||||
|
|
||||||
/** configuração para aplicação dos filtros padrões */
|
|
||||||
|
|
||||||
// Todo: quando exite aparace ap lado do obtão coluna o potão filtro avançado, onde abre um modal com dua colunas de compoentes que são contruidas conforme esse padrão
|
|
||||||
// todo: Os filtros criados deverão ser salvo em local storagem como um objeto tipofiltro[]
|
|
||||||
filtroAvancado?: {
|
|
||||||
rotulo: string,
|
|
||||||
coluna: keyof T,
|
|
||||||
operador: operadores | keyof typeof operadores,
|
|
||||||
entrada: ComponenteEntrada
|
|
||||||
}[]
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
13
src/index.ts
13
src/index.ts
|
|
@ -3,27 +3,28 @@ import "./styles/eli-vue-fonts.css";
|
||||||
import { EliOlaMundo } from "./componentes/ola_mundo";
|
import { EliOlaMundo } from "./componentes/ola_mundo";
|
||||||
import { EliBotao } from "./componentes/botao";
|
import { EliBotao } from "./componentes/botao";
|
||||||
import { EliBadge } from "./componentes/indicador";
|
import { EliBadge } from "./componentes/indicador";
|
||||||
|
import { EliInput } from "./componentes/campo";
|
||||||
import { EliCartao } from "./componentes/cartao";
|
import { EliCartao } from "./componentes/cartao";
|
||||||
import { EliTabela } from "./componentes/EliTabela";
|
import { EliDataHora } from "./componentes/data_hora";
|
||||||
import { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora } from "./componentes/EliEntrada";
|
import { EliTabela } from "./components/eli/EliTabela";
|
||||||
|
|
||||||
export { EliOlaMundo };
|
export { EliOlaMundo };
|
||||||
export { EliBotao };
|
export { EliBotao };
|
||||||
export { EliBadge };
|
export { EliBadge };
|
||||||
|
export { EliInput };
|
||||||
export { EliCartao };
|
export { EliCartao };
|
||||||
|
export { EliDataHora };
|
||||||
export { EliTabela };
|
export { EliTabela };
|
||||||
export { EliEntradaTexto, EliEntradaNumero, EliEntradaDataHora };
|
|
||||||
|
|
||||||
const EliVue: Plugin = {
|
const EliVue: Plugin = {
|
||||||
install(app: App) {
|
install(app: App) {
|
||||||
app.component("EliOlaMundo", EliOlaMundo);
|
app.component("EliOlaMundo", EliOlaMundo);
|
||||||
app.component("EliBotao", EliBotao);
|
app.component("EliBotao", EliBotao);
|
||||||
app.component("EliBadge", EliBadge);
|
app.component("EliBadge", EliBadge);
|
||||||
|
app.component("EliInput", EliInput);
|
||||||
app.component("EliCartao", EliCartao);
|
app.component("EliCartao", EliCartao);
|
||||||
|
app.component("EliDataHora", EliDataHora);
|
||||||
app.component("EliTabela", EliTabela);
|
app.component("EliTabela", EliTabela);
|
||||||
app.component("EliEntradaTexto", EliEntradaTexto);
|
|
||||||
app.component("EliEntradaNumero", EliEntradaNumero);
|
|
||||||
app.component("EliEntradaDataHora", EliEntradaDataHora);
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
<v-tab value="botao">Botão</v-tab>
|
<v-tab value="botao">Botão</v-tab>
|
||||||
<v-tab value="indicador">Indicador</v-tab>
|
<v-tab value="indicador">Indicador</v-tab>
|
||||||
<v-tab value="cartao">Cartão</v-tab>
|
<v-tab value="cartao">Cartão</v-tab>
|
||||||
<v-tab value="entradas">Entradas</v-tab>
|
<v-tab value="campo">Campo</v-tab>
|
||||||
<v-tab value="data_hora">Data e hora</v-tab>
|
<v-tab value="data_hora">Data e hora</v-tab>
|
||||||
<v-tab value="tabela">Tabela</v-tab>
|
<v-tab value="tabela">Tabela</v-tab>
|
||||||
<v-tab value="ola_mundo">Demo</v-tab>
|
<v-tab value="ola_mundo">Demo</v-tab>
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
<BotaoPlayground v-if="aba === 'botao'" />
|
<BotaoPlayground v-if="aba === 'botao'" />
|
||||||
<IndicadorPlayground v-else-if="aba === 'indicador'" />
|
<IndicadorPlayground v-else-if="aba === 'indicador'" />
|
||||||
<CartaoPlayground v-else-if="aba === 'cartao'" />
|
<CartaoPlayground v-else-if="aba === 'cartao'" />
|
||||||
<EntradasPlayground v-else-if="aba === 'entradas'" />
|
<CampoPlayground v-else-if="aba === 'campo'" />
|
||||||
<DataHoraPlayground v-else-if="aba === 'data_hora'" />
|
<DataHoraPlayground v-else-if="aba === 'data_hora'" />
|
||||||
<TabelaPlayground v-else-if="aba === 'tabela'" />
|
<TabelaPlayground v-else-if="aba === 'tabela'" />
|
||||||
<OlaMundoPlayground v-else />
|
<OlaMundoPlayground v-else />
|
||||||
|
|
@ -31,7 +31,7 @@ import { defineComponent } from "vue";
|
||||||
import BotaoPlayground from "./botao.playground.vue";
|
import BotaoPlayground from "./botao.playground.vue";
|
||||||
import IndicadorPlayground from "./indicador.playground.vue";
|
import IndicadorPlayground from "./indicador.playground.vue";
|
||||||
import CartaoPlayground from "./cartao.playground.vue";
|
import CartaoPlayground from "./cartao.playground.vue";
|
||||||
import EntradasPlayground from "./entradas.playground.vue";
|
import CampoPlayground from "./campo.playground.vue";
|
||||||
import DataHoraPlayground from "./data_hora.playground.vue";
|
import DataHoraPlayground from "./data_hora.playground.vue";
|
||||||
import TabelaPlayground from "./tabela.playground.vue";
|
import TabelaPlayground from "./tabela.playground.vue";
|
||||||
import OlaMundoPlayground from "./ola_mundo.playground.vue";
|
import OlaMundoPlayground from "./ola_mundo.playground.vue";
|
||||||
|
|
@ -40,7 +40,7 @@ type AbaPlayground =
|
||||||
| "botao"
|
| "botao"
|
||||||
| "indicador"
|
| "indicador"
|
||||||
| "cartao"
|
| "cartao"
|
||||||
| "entradas"
|
| "campo"
|
||||||
| "data_hora"
|
| "data_hora"
|
||||||
| "tabela"
|
| "tabela"
|
||||||
| "ola_mundo";
|
| "ola_mundo";
|
||||||
|
|
@ -49,7 +49,7 @@ const mapaHashParaAba: Record<string, AbaPlayground> = {
|
||||||
botao: "botao",
|
botao: "botao",
|
||||||
indicador: "indicador",
|
indicador: "indicador",
|
||||||
cartao: "cartao",
|
cartao: "cartao",
|
||||||
entradas: "entradas",
|
campo: "campo",
|
||||||
"data-hora": "data_hora",
|
"data-hora": "data_hora",
|
||||||
tabela: "tabela",
|
tabela: "tabela",
|
||||||
demo: "ola_mundo",
|
demo: "ola_mundo",
|
||||||
|
|
@ -59,7 +59,7 @@ const mapaAbaParaHash: Record<AbaPlayground, string> = {
|
||||||
botao: "botao",
|
botao: "botao",
|
||||||
indicador: "indicador",
|
indicador: "indicador",
|
||||||
cartao: "cartao",
|
cartao: "cartao",
|
||||||
entradas: "entradas",
|
campo: "campo",
|
||||||
data_hora: "data-hora",
|
data_hora: "data-hora",
|
||||||
tabela: "tabela",
|
tabela: "tabela",
|
||||||
ola_mundo: "demo",
|
ola_mundo: "demo",
|
||||||
|
|
@ -71,7 +71,7 @@ export default defineComponent({
|
||||||
BotaoPlayground,
|
BotaoPlayground,
|
||||||
IndicadorPlayground,
|
IndicadorPlayground,
|
||||||
CartaoPlayground,
|
CartaoPlayground,
|
||||||
EntradasPlayground,
|
CampoPlayground,
|
||||||
DataHoraPlayground,
|
DataHoraPlayground,
|
||||||
TabelaPlayground,
|
TabelaPlayground,
|
||||||
OlaMundoPlayground,
|
OlaMundoPlayground,
|
||||||
|
|
|
||||||
127
src/playground/campo.playground.vue
Normal file
127
src/playground/campo.playground.vue
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
<template>
|
||||||
|
<section class="stack">
|
||||||
|
<h2>EliInput (campo)</h2>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<EliInput v-model="nome" label="Nome" placeholder="Digite seu nome" />
|
||||||
|
<EliInput v-model="telefone" type="telefone" label="Telefone" />
|
||||||
|
<EliInput v-model="documento" type="cpfCnpj" label="CPF / CNPJ" />
|
||||||
|
|
||||||
|
<EliInput v-model="idade" type="numericoInteiro" label="Idade" />
|
||||||
|
<EliInput v-model="valor" type="numericoMoeda" label="Valor" />
|
||||||
|
<EliInput v-model="taxa" type="porcentagem" label="Taxa" placeholder="0,00" />
|
||||||
|
<EliInput v-model="cep" type="cep" label="CEP" placeholder="00000-000" />
|
||||||
|
|
||||||
|
<EliInput
|
||||||
|
v-model="estado"
|
||||||
|
type="select"
|
||||||
|
label="Estado"
|
||||||
|
multiple
|
||||||
|
:options="[
|
||||||
|
{ label: 'São Paulo', value: 'SP' },
|
||||||
|
{ label: 'Rio de Janeiro', value: 'RJ' },
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EliInput
|
||||||
|
v-model="cor"
|
||||||
|
type="radio"
|
||||||
|
label="Cor favorita"
|
||||||
|
:options="[
|
||||||
|
{ label: 'Azul', value: 'azul' },
|
||||||
|
{ label: 'Verde', value: 'verde' },
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EliInput
|
||||||
|
v-model="habilidades"
|
||||||
|
type="checkbox"
|
||||||
|
label="Habilidades"
|
||||||
|
:options="[
|
||||||
|
{ label: 'Vue', value: 'vue' },
|
||||||
|
{ label: 'React', value: 'react' },
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre class="debug">{{ debug }}</pre>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { computed, defineComponent, ref } from "vue";
|
||||||
|
import { EliInput } from "@/componentes/campo";
|
||||||
|
|
||||||
|
type Cor = "azul" | "verde" | null;
|
||||||
|
type Habilidade = "vue" | "react";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "CampoPlayground",
|
||||||
|
components: { EliInput },
|
||||||
|
setup() {
|
||||||
|
const nome = ref("");
|
||||||
|
const telefone = ref("");
|
||||||
|
const documento = ref("");
|
||||||
|
const idade = ref("");
|
||||||
|
const valor = ref("");
|
||||||
|
const taxa = ref("");
|
||||||
|
const cep = ref("");
|
||||||
|
const estado = ref<string[]>([]);
|
||||||
|
const cor = ref<Cor>(null);
|
||||||
|
const habilidades = ref<Habilidade[]>([]);
|
||||||
|
|
||||||
|
const debug = computed(() =>
|
||||||
|
JSON.stringify(
|
||||||
|
{
|
||||||
|
nome: nome.value,
|
||||||
|
telefone: telefone.value,
|
||||||
|
documento: documento.value,
|
||||||
|
idade: idade.value,
|
||||||
|
valor: valor.value,
|
||||||
|
taxa: taxa.value,
|
||||||
|
cep: cep.value,
|
||||||
|
estado: estado.value,
|
||||||
|
cor: cor.value,
|
||||||
|
habilidades: habilidades.value,
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
nome,
|
||||||
|
telefone,
|
||||||
|
documento,
|
||||||
|
idade,
|
||||||
|
valor,
|
||||||
|
taxa,
|
||||||
|
cep,
|
||||||
|
estado,
|
||||||
|
cor,
|
||||||
|
habilidades,
|
||||||
|
debug,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.stack {
|
||||||
|
display: grid;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 12px;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.debug {
|
||||||
|
padding: 12px;
|
||||||
|
background: rgba(0, 0, 0, 0.04);
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -3,9 +3,10 @@
|
||||||
<h2>EliCartao (pipeline)</h2>
|
<h2>EliCartao (pipeline)</h2>
|
||||||
|
|
||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<EliEntradaTexto
|
<EliInput
|
||||||
v-model:value="filtro"
|
v-model="filtro"
|
||||||
:opcoes="{ rotulo: 'Buscar', placeholder: 'Cliente, título, valor...' }"
|
label="Buscar"
|
||||||
|
placeholder="Cliente, título, valor..."
|
||||||
density="compact"
|
density="compact"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
@ -47,7 +48,7 @@
|
||||||
import { defineComponent, ref } from "vue";
|
import { defineComponent, ref } from "vue";
|
||||||
import { EliBadge } from "@/componentes/indicador";
|
import { EliBadge } from "@/componentes/indicador";
|
||||||
import { EliBotao } from "@/componentes/botao";
|
import { EliBotao } from "@/componentes/botao";
|
||||||
import { EliEntradaTexto } from "@/componentes/EliEntrada";
|
import { EliInput } from "@/componentes/campo";
|
||||||
import { EliCartao } from "@/componentes/cartao";
|
import { EliCartao } from "@/componentes/cartao";
|
||||||
import type { CartaoStatus } from "@/tipos";
|
import type { CartaoStatus } from "@/tipos";
|
||||||
|
|
||||||
|
|
@ -67,7 +68,7 @@ type Coluna = {
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "CartaoPlayground",
|
name: "CartaoPlayground",
|
||||||
components: { EliBadge, EliBotao, EliEntradaTexto, EliCartao },
|
components: { EliBadge, EliBotao, EliInput, EliCartao },
|
||||||
setup() {
|
setup() {
|
||||||
const filtro = ref("");
|
const filtro = ref("");
|
||||||
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue