@wgalleti/primevue-components 0.9.6 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +4 -0
  2. package/dist/WMapSelect.vue_vue_type_script_setup_true_lang-BOhO1F9v.js +4991 -0
  3. package/dist/WMapSelect.vue_vue_type_script_setup_true_lang-BOhO1F9v.js.map +1 -0
  4. package/dist/WMapSelect.vue_vue_type_script_setup_true_lang-BkZhQ_LO.cjs +12 -0
  5. package/dist/WMapSelect.vue_vue_type_script_setup_true_lang-BkZhQ_LO.cjs.map +1 -0
  6. package/dist/components/crud/WEditableTable.vue.d.ts +78 -0
  7. package/dist/components/form/WAutoCompleteFK.vue.d.ts +9 -1
  8. package/dist/components/form/WTreeSelect.vue.d.ts +124 -0
  9. package/dist/components/index.d.ts +6 -0
  10. package/dist/components/ui/WCheckList.vue.d.ts +36 -0
  11. package/dist/components/ui/WInfoCard.vue.d.ts +11 -1
  12. package/dist/components/ui/WMapSelect.vue.d.ts +133 -0
  13. package/dist/components/ui/WStepFlow.vue.d.ts +51 -0
  14. package/dist/components/ui/WStepSection.vue.d.ts +49 -0
  15. package/dist/components.cjs +1 -1
  16. package/dist/components.cjs.map +1 -1
  17. package/dist/components.js +29 -124
  18. package/dist/components.js.map +1 -1
  19. package/dist/index.cjs +1 -1
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.ts +5 -2
  22. package/dist/index.js +79 -70
  23. package/dist/index.js.map +1 -1
  24. package/dist/primevue-components.css +1 -1
  25. package/dist/types/checkList.d.ts +7 -0
  26. package/dist/types/editableTable.d.ts +39 -0
  27. package/dist/types/field.d.ts +27 -1
  28. package/dist/types/index.d.ts +3 -0
  29. package/dist/types/mapSelect.d.ts +31 -0
  30. package/dist/utils/stepFlow.d.ts +27 -0
  31. package/dist/utils/treeSelect.d.ts +76 -0
  32. package/package.json +5 -1
  33. package/skill/references/components.md +7 -0
  34. package/dist/WProgressFlow.vue_vue_type_script_setup_true_lang-Cc0DJRIy.cjs +0 -12
  35. package/dist/WProgressFlow.vue_vue_type_script_setup_true_lang-Cc0DJRIy.cjs.map +0 -1
  36. package/dist/WProgressFlow.vue_vue_type_script_setup_true_lang-DVjJq8Bs.js +0 -3632
  37. package/dist/WProgressFlow.vue_vue_type_script_setup_true_lang-DVjJq8Bs.js.map +0 -1
@@ -0,0 +1,78 @@
1
+ import { EditableColumnDef, EditableRow } from '../../types/editableTable';
2
+ /**
3
+ * Tabela editável sobre ESTADO LOCAL — o oposto do WCrudView, que conversa com a
4
+ * API a cada operação. Aqui nada é persistido: o consumidor mantém o array e
5
+ * salva em bloco quando quiser (o caso "documento com filhos", em que salvar
6
+ * linha a linha criaria registro órfão).
7
+ *
8
+ * As linhas nunca são mutadas no lugar: toda edição emite um array NOVO com a
9
+ * linha trocada (`update:modelValue`), então `v-model` funciona igual em `ref`,
10
+ * `reactive` ou prop vinda de cima.
11
+ *
12
+ * A subtabela de insumos do design é este mesmo componente dentro do slot
13
+ * `#expansion` — não existe componente separado para "tabela filha".
14
+ */
15
+ type __VLS_Props = {
16
+ /** Linhas (`v-model`). */
17
+ modelValue?: EditableRow[];
18
+ columns?: EditableColumnDef[];
19
+ /** Liga a coluna de expansão e o slot `#expansion`. */
20
+ expandable?: boolean;
21
+ /** Rótulo do botão de adicionar. Omitido = sem botão (só o slot `#toolbar`). */
22
+ addLabel?: string;
23
+ /** Liga a coluna da lixeira. */
24
+ removable?: boolean;
25
+ emptyMessage?: string;
26
+ /** Rótulo da primeira célula do rodapé de totais. */
27
+ footerLabel?: string;
28
+ /** Trava todos os editores (a tabela vira leitura). */
29
+ disabled?: boolean;
30
+ /** Campo usado como `key` das linhas. Sem ele, a chave é o índice. */
31
+ rowKey?: string;
32
+ };
33
+ declare function __VLS_template(): {
34
+ attrs: Partial<{}>;
35
+ slots: Partial<Record<`cell-${string}`, (_: {
36
+ row: EditableRow;
37
+ index: number;
38
+ value: unknown;
39
+ column: EditableColumnDef;
40
+ }) => any>> & Partial<Record<`footer-${string}`, (_: {
41
+ rows: EditableRow[];
42
+ column: EditableColumnDef;
43
+ }) => any>> & {
44
+ toolbar?(_: {}): any;
45
+ empty?(_: {}): any;
46
+ expansion?(_: {
47
+ row: EditableRow;
48
+ index: number;
49
+ }): any;
50
+ };
51
+ refs: {};
52
+ rootEl: HTMLDivElement;
53
+ };
54
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
55
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
56
+ "update:modelValue": (rows: EditableRow[]) => any;
57
+ remove: (row: EditableRow, index: number) => any;
58
+ add: () => any;
59
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
60
+ "onUpdate:modelValue"?: ((rows: EditableRow[]) => any) | undefined;
61
+ onRemove?: ((row: EditableRow, index: number) => any) | undefined;
62
+ onAdd?: (() => any) | undefined;
63
+ }>, {
64
+ modelValue: EditableRow[];
65
+ disabled: boolean;
66
+ columns: EditableColumnDef[];
67
+ expandable: boolean;
68
+ emptyMessage: string;
69
+ removable: boolean;
70
+ footerLabel: string;
71
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
72
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
73
+ export default _default;
74
+ type __VLS_WithTemplateSlots<T, S> = T & {
75
+ new (): {
76
+ $slots: S;
77
+ };
78
+ };
@@ -1,4 +1,4 @@
1
- import { FieldDef } from '../../types/field';
1
+ import { FieldDef, FieldSubRowsFetch } from '../../types/field';
2
2
  import { ColumnDef } from '../../types/column';
3
3
  interface ColumnMeta {
4
4
  field: string;
@@ -26,6 +26,10 @@ type __VLS_Props = {
26
26
  * (0 = mostrar todos). Útil em campo estreito, tipo filtro de painel. */
27
27
  maxChips?: number;
28
28
  optionLabel?: string;
29
+ /** Chave de uma segunda linha, em texto de apoio, dentro de cada sugestão — para
30
+ * o dado que **decide** a escolha aparecer antes dela (ex.: saldo em estoque).
31
+ * Vazia ou ausente na linha, a sugestão volta a ter uma linha só. */
32
+ optionDescription?: string;
29
33
  optionValue?: string;
30
34
  placeholder?: string;
31
35
  /** Placeholder exibido enquanto uma cascata obrigatória não estiver preenchida. */
@@ -41,6 +45,10 @@ type __VLS_Props = {
41
45
  canDelete?: boolean;
42
46
  crudFields?: FieldDef[];
43
47
  crudColumns?: ColumnDef[];
48
+ /** Sub-linhas do grid do modal: recebe as linhas da página e devolve o mapa
49
+ * `id → sub-linhas` + as colunas (dinâmicas) do mini-grid. Linha com entrada
50
+ * no mapa abre expandida — ex.: lote (linha) com suas análises (sub-linhas). */
51
+ subRows?: FieldSubRowsFetch;
44
52
  dialogWidth?: string;
45
53
  /** Foca o campo ao montar. Marca o input com o atributo nativo `autofocus`
46
54
  * para que o `focus()` do PrimeVue Dialog (em onAfterEnter) o encontre e
@@ -0,0 +1,124 @@
1
+ import { TreeSelectId, TreeSelectNode, TreeSelectOption } from '../../utils/treeSelect';
2
+ /**
3
+ * Seleção múltipla em árvore com checkbox, alimentada por uma lista PLANA + um
4
+ * campo de agrupamento. O `v-model` é um array de ids de FOLHA — nunca o mapa de
5
+ * chaves do PrimeVue, e nunca com id de grupo dentro (grupo é só visual).
6
+ *
7
+ * ---------------------------------------------------------------------------
8
+ * POR QUE A SELEÇÃO É DERIVADA AQUI E NÃO DELEGADA AO `Tree` — NÃO "SIMPLIFIQUE"
9
+ * ---------------------------------------------------------------------------
10
+ * O `Tree` com `selectionMode="checkbox"` sabe manter sozinho o mapa
11
+ * `{ chave: { checked, partialChecked } }`, propagando para pais e filhos. Trocar
12
+ * o que está aqui por um `v-model:selectionKeys` parece uma simplificação óbvia.
13
+ * Não é: existe um bug ABERTO que quebra exatamente a combinação que usamos
14
+ * (checkbox + filtro).
15
+ *
16
+ * https://github.com/primefaces/primevue/issues/6928 (aberta, "Help Wanted")
17
+ *
18
+ * Com o filtro ativo, o `partialChecked` dos ancestrais passa a se referir à
19
+ * árvore FILTRADA em vez da árvore inteira. O mecanismo está no código do
20
+ * PrimeVue 4.5: `TreeNode.propagateUp()` conta `this.node.children`, e sob filtro
21
+ * `this.node` é uma CÓPIA que o `findFilteredNodes()` produziu contendo só os
22
+ * filhos que casaram com a busca. Um grupo com 12 telas, 3 marcadas e filtro
23
+ * mostrando só essas 3 aparece como totalmente marcado — e ao salvar o usuário
24
+ * marca o que não queria.
25
+ *
26
+ * O repositório do PrimeVue foi arquivado em junho/2026 e está read-only: não vai
27
+ * ser corrigido upstream.
28
+ *
29
+ * Por isso, aqui:
30
+ * 1. a fonte da verdade é o `modelValue` (ids de folha) — sem estado espelhado;
31
+ * 2. o `selectionKeys` é DERIVADO sobre a árvore INTEIRA (`fullTree`), nunca
32
+ * sobre a visão filtrada, então é correto por construção;
33
+ * 3. o `Tree` recebe `:selection-keys` como prop CONTROLADA (não `v-model:`) —
34
+ * o mapa que ele calcularia é simplesmente descartado.
35
+ *
36
+ * Escolha do evento: `node-select` / `node-unselect`, e não `update:selectionKeys`.
37
+ * Os dois saem do mesmo `onCheckboxChange` do `Tree`, mas carregam coisas
38
+ * diferentes: `update:selectionKeys` entrega o mapa JÁ PROPAGADO (o resultado do
39
+ * `propagateUp` bugado), enquanto `node-select`/`node-unselect` entregam só o nó
40
+ * clicado e a direção do clique — a intenção crua do usuário, que nenhuma conta
41
+ * do PrimeVue tocou. É o único ponto estável da API para este caso.
42
+ *
43
+ * Detalhe que fecha o cerco: sob filtro o nó do evento é uma cópia podada, então
44
+ * ler `event.node.children` alternaria só as folhas VISÍVEIS. Resolvemos o nó
45
+ * pela `key` dentro do índice da árvore inteira (`fullIndex`) e alternamos todas
46
+ * as folhas dele — o mesmo resultado com ou sem filtro na tela.
47
+ */
48
+ type __VLS_Props = {
49
+ /** Ids das folhas selecionadas (`v-model`). Nunca contém id de grupo. */
50
+ modelValue?: TreeSelectId[];
51
+ /** Lista PLANA de registros. O agrupamento é feito aqui, por `groupBy`. */
52
+ options?: TreeSelectOption[];
53
+ /** Campo do id da folha (default: `id`). */
54
+ optionValue?: string;
55
+ /** Campo do rótulo visível (default: `nome`). */
56
+ optionLabel?: string;
57
+ /** Campo que agrupa os registros. Sem ele, a lista sai rasa. */
58
+ groupBy?: string;
59
+ /** Rótulo do nó-pai a partir do valor bruto do agrupamento. */
60
+ groupLabel?: (chave: string) => string;
61
+ /** Campo de busca interno. */
62
+ filter?: boolean;
63
+ filterPlaceholder?: string;
64
+ /** Campos extras do registro considerados na busca (além do rótulo). */
65
+ filterFields?: string[];
66
+ loading?: boolean;
67
+ disabled?: boolean;
68
+ /** Texto quando não há nenhuma opção. */
69
+ emptyMessage?: string;
70
+ /** Texto quando a busca não encontrou nada. */
71
+ filterEmptyMessage?: string;
72
+ /** Contador `N de M selecionados` acima da árvore. */
73
+ showCount?: boolean;
74
+ /** Atalhos "Marcar todos" / "Limpar". */
75
+ showToggleAll?: boolean;
76
+ /** Abre todos os grupos na montagem. */
77
+ defaultExpanded?: boolean;
78
+ ariaLabel?: string;
79
+ };
80
+ declare function __VLS_template(): {
81
+ attrs: Partial<{}>;
82
+ slots: {
83
+ header?(_: {
84
+ selectedCount: number;
85
+ total: number;
86
+ }): any;
87
+ node?(_: {
88
+ node: TreeSelectNode;
89
+ }): any;
90
+ empty?(_: {
91
+ filtering: boolean;
92
+ }): any;
93
+ };
94
+ refs: {};
95
+ rootEl: HTMLDivElement;
96
+ };
97
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
98
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
99
+ "update:modelValue": (ids: TreeSelectId[]) => any;
100
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
101
+ "onUpdate:modelValue"?: ((ids: TreeSelectId[]) => any) | undefined;
102
+ }>, {
103
+ filter: boolean;
104
+ modelValue: TreeSelectId[];
105
+ optionLabel: string;
106
+ optionValue: string;
107
+ disabled: boolean;
108
+ loading: boolean;
109
+ options: TreeSelectOption[];
110
+ filterPlaceholder: string;
111
+ filterFields: string[];
112
+ emptyMessage: string;
113
+ filterEmptyMessage: string;
114
+ showCount: boolean;
115
+ showToggleAll: boolean;
116
+ defaultExpanded: boolean;
117
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
118
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
119
+ export default _default;
120
+ type __VLS_WithTemplateSlots<T, S> = T & {
121
+ new (): {
122
+ $slots: S;
123
+ };
124
+ };
@@ -1,6 +1,7 @@
1
1
  export { default as WCrudView } from './crud/WCrudView.vue';
2
2
  export { default as WCrudFormDialog } from './crud/WCrudFormDialog.vue';
3
3
  export { default as WCrudColumnRenderer } from './crud/WCrudColumnRenderer.vue';
4
+ export { default as WEditableTable } from './crud/WEditableTable.vue';
4
5
  export { default as WAutoCompleteFK } from './form/WAutoCompleteFK.vue';
5
6
  export { default as WFormRenderer } from './form/WFormRenderer.vue';
6
7
  export { default as WImageCropper } from './form/WImageCropper.vue';
@@ -9,6 +10,7 @@ export { default as WDateRange } from './form/WDateRange.vue';
9
10
  export { default as WFileUpload } from './form/WFileUpload.vue';
10
11
  export { default as WMoneyInput } from './form/WMoneyInput.vue';
11
12
  export { default as WTransferList } from './form/WTransferList.vue';
13
+ export { default as WTreeSelect } from './form/WTreeSelect.vue';
12
14
  export { default as WStatusTag } from './ui/WStatusTag.vue';
13
15
  export { default as WPageHeader } from './ui/WPageHeader.vue';
14
16
  export { default as WEmptyState } from './ui/WEmptyState.vue';
@@ -20,3 +22,7 @@ export { default as WSectionHeader } from './ui/WSectionHeader.vue';
20
22
  export { default as WFormSection } from './ui/WFormSection.vue';
21
23
  export { default as WActionBar } from './ui/WActionBar.vue';
22
24
  export { default as WProgressFlow } from './ui/WProgressFlow.vue';
25
+ export { default as WStepFlow } from './ui/WStepFlow.vue';
26
+ export { default as WStepSection } from './ui/WStepSection.vue';
27
+ export { default as WCheckList } from './ui/WCheckList.vue';
28
+ export { default as WMapSelect } from './ui/WMapSelect.vue';
@@ -0,0 +1,36 @@
1
+ import { CheckListItem } from '../../types/checkList';
2
+ /**
3
+ * Lista de verificações de um documento (o aside "Verificações"): um ícone por
4
+ * nível e o contador `N/M` de quantas passaram, no cabeçalho.
5
+ *
6
+ * A avaliação é sempre do backend/serviço — o componente só desenha o que
7
+ * recebe. Ele não conhece regra de negócio nenhuma.
8
+ */
9
+ type __VLS_Props = {
10
+ title?: string;
11
+ items?: CheckListItem[];
12
+ /** Esconde o contador `N/M` do cabeçalho. */
13
+ showCount?: boolean;
14
+ emptyMessage?: string;
15
+ };
16
+ declare function __VLS_template(): {
17
+ attrs: Partial<{}>;
18
+ slots: {
19
+ empty?(_: {}): any;
20
+ };
21
+ refs: {};
22
+ rootEl: HTMLDivElement;
23
+ };
24
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
25
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
26
+ emptyMessage: string;
27
+ showCount: boolean;
28
+ items: CheckListItem[];
29
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
30
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
31
+ export default _default;
32
+ type __VLS_WithTemplateSlots<T, S> = T & {
33
+ new (): {
34
+ $slots: S;
35
+ };
36
+ };
@@ -2,10 +2,20 @@ export interface InfoField {
2
2
  label: string;
3
3
  value: string | number | null | undefined;
4
4
  format?: 'currency' | 'date' | 'datetime' | 'number' | 'text';
5
+ /** Unidade colada ao valor — usada na variante `metric` (ex.: `ha`, `kg`, `L`). */
6
+ suffix?: string;
7
+ /** Casas decimais do `format: 'number'` (default 2). */
8
+ decimals?: number;
5
9
  }
6
10
  type __VLS_Props = {
7
11
  title?: string;
8
12
  fields: InfoField[];
13
+ /** `default`: grade de rótulo em cima e valor embaixo.
14
+ * `metric`: uma linha por campo — rótulo à esquerda, número grande à
15
+ * direita, divisória entre as linhas (o aside "Resumo" de um documento). */
16
+ variant?: 'default' | 'metric';
9
17
  };
10
- declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
18
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
19
+ variant: "default" | "metric";
20
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
11
21
  export default _default;
@@ -0,0 +1,133 @@
1
+ import { MapSelectFeature, MapSelectGeometry, MapSelectId, MapSelectPolygonStyle } from '../../types/mapSelect';
2
+ /**
3
+ * Seleção múltipla de polígonos num mapa de satélite, com painel lateral de busca.
4
+ *
5
+ * O componente NÃO é dono da seleção: `modelValue` é a fonte da verdade e todo
6
+ * clique (no polígono ou na lista) sai como `update:modelValue`. Isso mantém o
7
+ * mapa e a lista sempre coerentes — os dois leem o mesmo array.
8
+ *
9
+ * O Leaflet entra por `import()` dinâmico: o mapa costuma viver dentro de um
10
+ * Dialog, e carregar ~150 kB de biblioteca de mapa no bundle de quem só abre um
11
+ * CRUD é desperdício. Se o `import()` falhar (offline, CSP), o mapa é substituído
12
+ * por um aviso e o painel lateral continua funcionando — selecionar talhão pela
13
+ * lista nunca depende do mapa ter subido.
14
+ *
15
+ * `layout` só troca POSICIONAMENTO (CSS): a marcação é a mesma nos dois modos.
16
+ * No `'sobreposto'` o mapa ocupa tudo e o painel/rodapé flutuam por cima em
17
+ * vidro. Eles continuam FORA do container do Leaflet (irmãos, não filhos), então
18
+ * o mapa nunca vê os cliques do painel e o painel nunca precisa de
19
+ * `L.DomEvent.disableClickPropagation` — arrastar/zoom por baixo segue intacto.
20
+ */
21
+ type __VLS_Props = {
22
+ /** Ids selecionados (`v-model`). */
23
+ modelValue?: MapSelectId[];
24
+ /** Itens selecionáveis. Sem `geometria` o item some do mapa, não da lista. */
25
+ features?: MapSelectFeature[];
26
+ /** Geometria do escopo (ex.: o setor) usada no `fitBounds` inicial.
27
+ * Sem ela, o enquadramento é a união das geometrias das `features`. */
28
+ scopeGeometry?: MapSelectGeometry | null;
29
+ /** Tiles. Default: satélite World_Imagery (ArcGIS/Esri). */
30
+ tileUrl?: string;
31
+ tileAttribution?: string;
32
+ /** Zoom máximo do tile layer (o World_Imagery vai até 19). */
33
+ maxZoom?: number;
34
+ searchPlaceholder?: string;
35
+ /** Rótulo do rodapé, à esquerda da área somada. */
36
+ areaLabel?: string;
37
+ /** Unidade da área, no rodapé e no tooltip do polígono. */
38
+ areaSuffix?: string;
39
+ /** Casas decimais da área. */
40
+ areaDecimals?: number;
41
+ /** Altura do mapa (qualquer unidade CSS). */
42
+ height?: string;
43
+ /** Arranjo do componente.
44
+ * - `'lado-a-lado'`: mapa à esquerda, painel de 300 px à direita, rodapé embaixo.
45
+ * - `'sobreposto'`: o mapa ocupa tudo; painel e rodapé flutuam sobre ele em vidro. */
46
+ layout?: 'lado-a-lado' | 'sobreposto';
47
+ /** Texto do contador. Default em pt-BR: "N talhões selecionados". */
48
+ selectionLabel?: (count: number) => string;
49
+ clearLabel?: string;
50
+ /** `layout="sobreposto"`: rótulo acessível do botão que recolhe o painel. */
51
+ collapseLabel?: string;
52
+ /** `layout="sobreposto"`: rótulo acessível do botão que reabre o painel. */
53
+ expandLabel?: string;
54
+ /** Selo sobre o mapa (canto superior direito). `''` esconde. */
55
+ badgeLabel?: string;
56
+ emptyMessage?: string;
57
+ /** Mensagem quando o Leaflet não carregou. */
58
+ mapErrorMessage?: string;
59
+ disabled?: boolean;
60
+ /** Estilo do polígono não selecionado. */
61
+ polygonStyle?: MapSelectPolygonStyle;
62
+ /** Estilo do polígono selecionado. */
63
+ polygonSelectedStyle?: MapSelectPolygonStyle;
64
+ };
65
+ declare function setCollapsed(value: boolean): void;
66
+ /** O mapa costuma nascer escondido (dentro de um Dialog): sem isto o Leaflet
67
+ * calcula 0×0 e desenha só um pedaço quando o container aparece. */
68
+ declare function refreshSize(): void;
69
+ declare function __VLS_template(): {
70
+ attrs: Partial<{}>;
71
+ slots: {
72
+ item?(_: {
73
+ feature: MapSelectFeature;
74
+ selected: boolean;
75
+ }): any;
76
+ empty?(_: {}): any;
77
+ footer?(_: {
78
+ area: number;
79
+ features: MapSelectFeature[];
80
+ }): any;
81
+ };
82
+ refs: {
83
+ root: HTMLDivElement;
84
+ container: HTMLDivElement;
85
+ footer: HTMLDivElement;
86
+ };
87
+ rootEl: HTMLDivElement;
88
+ };
89
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
90
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {
91
+ refreshSize: typeof refreshSize;
92
+ /** Painel flutuante recolhido? (só faz sentido no `layout="sobreposto"`.) */
93
+ collapsed: Readonly<import('vue').Ref<boolean, boolean>>;
94
+ setCollapsed: typeof setCollapsed;
95
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
96
+ "update:modelValue": (ids: MapSelectId[]) => any;
97
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
98
+ "onUpdate:modelValue"?: ((ids: MapSelectId[]) => any) | undefined;
99
+ }>, {
100
+ modelValue: MapSelectId[];
101
+ disabled: boolean;
102
+ height: string;
103
+ emptyMessage: string;
104
+ features: MapSelectFeature[];
105
+ scopeGeometry: MapSelectGeometry | null;
106
+ tileUrl: string;
107
+ tileAttribution: string;
108
+ maxZoom: number;
109
+ searchPlaceholder: string;
110
+ areaLabel: string;
111
+ areaSuffix: string;
112
+ areaDecimals: number;
113
+ layout: "lado-a-lado" | "sobreposto";
114
+ selectionLabel: (count: number) => string;
115
+ clearLabel: string;
116
+ collapseLabel: string;
117
+ expandLabel: string;
118
+ badgeLabel: string;
119
+ mapErrorMessage: string;
120
+ polygonStyle: MapSelectPolygonStyle;
121
+ polygonSelectedStyle: MapSelectPolygonStyle;
122
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
123
+ root: HTMLDivElement;
124
+ container: HTMLDivElement;
125
+ footer: HTMLDivElement;
126
+ }, HTMLDivElement>;
127
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
128
+ export default _default;
129
+ type __VLS_WithTemplateSlots<T, S> = T & {
130
+ new (): {
131
+ $slots: S;
132
+ };
133
+ };
@@ -0,0 +1,51 @@
1
+ import { StepFlowOrientation } from '../../utils/stepFlow';
2
+ /**
3
+ * Etapas numeradas e colapsáveis (a espinha do editor de documento).
4
+ * Diferente do WProgressFlow, que só ILUSTRA o progresso: aqui cada etapa é um
5
+ * bloco de conteúdo que abre e fecha, e o `v-model` diz qual está aberta.
6
+ *
7
+ * `0` = todas fechadas. É estado do consumidor de propósito: "continuar para a
8
+ * próxima etapa" é uma decisão da tela, não do componente.
9
+ */
10
+ type __VLS_Props = {
11
+ /** Número da etapa aberta (`v-model`). `0` fecha todas. */
12
+ modelValue?: number;
13
+ /**
14
+ * `vertical` empilha as etapas numa coluna (cada uma é um card).
15
+ * `horizontal` põe os cabeçalhos lado a lado numa régua e abre só o corpo da
16
+ * etapa ativa embaixo, na largura inteira — abaixo de 768px cai sozinho
17
+ * para o empilhamento vertical (a régua não cabe).
18
+ */
19
+ orientation?: StepFlowOrientation;
20
+ /** Trava o clique no cabeçalho de todas as etapas. */
21
+ disabled?: boolean;
22
+ };
23
+ declare function __VLS_template(): {
24
+ attrs: Partial<{}>;
25
+ slots: {
26
+ default?(_: {}): any;
27
+ };
28
+ refs: {
29
+ root: HTMLDivElement;
30
+ };
31
+ rootEl: HTMLDivElement;
32
+ };
33
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
34
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
35
+ "update:modelValue": (step: number) => any;
36
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
37
+ "onUpdate:modelValue"?: ((step: number) => any) | undefined;
38
+ }>, {
39
+ modelValue: number;
40
+ disabled: boolean;
41
+ orientation: StepFlowOrientation;
42
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
43
+ root: HTMLDivElement;
44
+ }, HTMLDivElement>;
45
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
46
+ export default _default;
47
+ type __VLS_WithTemplateSlots<T, S> = T & {
48
+ new (): {
49
+ $slots: S;
50
+ };
51
+ };
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Uma etapa do WStepFlow: badge numerada + linha conectora, cabeçalho clicável
3
+ * (título, contador e resumo) e corpo colapsável com rodapé de ação.
4
+ *
5
+ * A orientação NÃO é prop daqui: vem do contexto do flow. Na vertical a etapa é
6
+ * um card na coluna; na horizontal o cabeçalho vira um trecho da régua e só o
7
+ * corpo da etapa ativa é desenhado, embaixo, na largura inteira.
8
+ *
9
+ * Fora de um WStepFlow o componente ainda funciona: ele cai num estado local
10
+ * aberto (e em vertical), para poder ser usado como card colapsável avulso.
11
+ */
12
+ type __VLS_Props = {
13
+ /** Número da etapa (1-based) — é o valor que o `v-model` do flow carrega. */
14
+ step: number;
15
+ title: string;
16
+ /** Texto à direita do título (o "resumo" da etapa fechada). */
17
+ summary?: string;
18
+ /** Badge de contagem entre o título e o resumo. */
19
+ count?: number | string;
20
+ disabled?: boolean;
21
+ };
22
+ declare function __VLS_template(): {
23
+ attrs: Partial<{}>;
24
+ slots: {
25
+ actions?(_: {
26
+ open: boolean;
27
+ }): any;
28
+ actions?(_: {
29
+ open: boolean;
30
+ }): any;
31
+ default?(_: {}): any;
32
+ default?(_: {}): any;
33
+ footer?(_: {}): any;
34
+ footer?(_: {}): any;
35
+ };
36
+ refs: {};
37
+ rootEl: any;
38
+ };
39
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
40
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
41
+ disabled: boolean;
42
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
43
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
44
+ export default _default;
45
+ type __VLS_WithTemplateSlots<T, S> = T & {
46
+ new (): {
47
+ $slots: S;
48
+ };
49
+ };
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./WProgressFlow.vue_vue_type_script_setup_true_lang-Cc0DJRIy.cjs"),e=require("vue"),m=require("primevue/button"),g={class:"w-fileupload",style:{display:"flex","flex-direction":"column",gap:"0.5rem"}},W=["accept","multiple"],v={key:0,style:{"list-style":"none",margin:"0",padding:"0",display:"flex","flex-direction":"column",gap:"0.35rem"}},k={style:{flex:"1",overflow:"hidden","text-overflow":"ellipsis","white-space":"nowrap"}},B={style:{opacity:"0.6"}},x=e.defineComponent({__name:"WFileUpload",props:{modelValue:{default:null},multiple:{type:Boolean,default:!1},accept:{default:void 0},maxSize:{default:10485760},disabled:{type:Boolean,default:!1},chooseLabel:{default:"Selecionar arquivo"}},emits:["update:modelValue","error"],setup(a,{emit:p}){const o=a,s=p,d=e.ref(null),c=e.computed(()=>{const l=o.modelValue;return l?Array.isArray(l)?l:[l]:[]});function f(){var l;(l=d.value)==null||l.click()}function _(l){const n=l.target,r=Array.from(n.files||[]);n.value="";const i=[];for(const u of r){if(u.size>o.maxSize){s("error",`"${u.name}" acima do limite de ${(o.maxSize/1048576).toFixed(1)}MB.`);continue}i.push(u)}i.length&&s("update:modelValue",o.multiple?[...c.value,...i]:i[0])}function y(l){if(!o.multiple){s("update:modelValue",null);return}const n=c.value.slice();n.splice(l,1),s("update:modelValue",n.length?n:null)}function $(l){return l<1024?`${l} B`:l<1048576?`${(l/1024).toFixed(0)} KB`:`${(l/1048576).toFixed(1)} MB`}return(l,n)=>(e.openBlock(),e.createElementBlock("div",g,[e.createElementVNode("div",null,[e.createVNode(e.unref(m),{type:"button",label:a.chooseLabel,icon:"pi pi-upload",outlined:"",size:"small",disabled:a.disabled,onClick:f},null,8,["label","disabled"])]),e.createElementVNode("input",{ref_key:"input",ref:d,type:"file",accept:a.accept,multiple:a.multiple,style:{display:"none"},onChange:_},null,40,W),c.value.length?(e.openBlock(),e.createElementBlock("ul",v,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(c.value,(r,i)=>(e.openBlock(),e.createElementBlock("li",{key:`${r.name}-${i}`,style:{display:"flex","align-items":"center",gap:"0.5rem","font-size":"0.85rem"}},[n[0]||(n[0]=e.createElementVNode("i",{class:"pi pi-file",style:{opacity:"0.6"}},null,-1)),e.createElementVNode("span",k,e.toDisplayString(r.name),1),e.createElementVNode("span",B,e.toDisplayString($(r.size)),1),e.createVNode(e.unref(m),{type:"button",icon:"pi pi-times",text:"",rounded:"",size:"small",severity:"danger",disabled:a.disabled,onClick:u=>y(i)},null,8,["disabled","onClick"])]))),128))])):e.renderSlot(l.$slots,"empty",{},()=>[n[1]||(n[1]=e.createElementVNode("span",{style:{"font-size":"0.8rem",opacity:"0.6"}},"Nenhum arquivo selecionado",-1))],void 0,1)]))}});exports.WActionBar=t._sfc_main;exports.WAutoCompleteFK=t._sfc_main$1;exports.WCrudColumnRenderer=t._sfc_main$2;exports.WCrudFormDialog=t._sfc_main$3;exports.WCrudView=t._sfc_main$4;exports.WDatePicker=t._sfc_main$5;exports.WDateRange=t._sfc_main$6;exports.WDetailHeader=t._sfc_main$7;exports.WEmptyState=t._sfc_main$8;exports.WFormRenderer=t._sfc_main$9;exports.WFormSection=t._sfc_main$10;exports.WImageCropper=t.WImageCropper;exports.WInfoCard=t._sfc_main$11;exports.WKpiCard=t._sfc_main$12;exports.WKpiGrid=t._sfc_main$13;exports.WMoneyInput=t._sfc_main$14;exports.WPageHeader=t._sfc_main$15;exports.WProgressFlow=t._sfc_main$16;exports.WSectionHeader=t._sfc_main$17;exports.WStatusTag=t._sfc_main$18;exports.WTransferList=t._sfc_main$19;exports.WFileUpload=x;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const _=require("./WMapSelect.vue_vue_type_script_setup_true_lang-BkZhQ_LO.cjs");exports.WActionBar=_._sfc_main;exports.WAutoCompleteFK=_._sfc_main$1;exports.WCheckList=_._sfc_main$2;exports.WCrudColumnRenderer=_._sfc_main$3;exports.WCrudFormDialog=_._sfc_main$4;exports.WCrudView=_._sfc_main$5;exports.WDatePicker=_._sfc_main$6;exports.WDateRange=_._sfc_main$7;exports.WDetailHeader=_._sfc_main$8;exports.WEditableTable=_._sfc_main$9;exports.WEmptyState=_._sfc_main$10;exports.WFileUpload=_._sfc_main$11;exports.WFormRenderer=_._sfc_main$12;exports.WFormSection=_._sfc_main$13;exports.WImageCropper=_.WImageCropper;exports.WInfoCard=_._sfc_main$14;exports.WKpiCard=_._sfc_main$15;exports.WKpiGrid=_._sfc_main$16;exports.WMapSelect=_._sfc_main$17;exports.WMoneyInput=_._sfc_main$18;exports.WPageHeader=_._sfc_main$19;exports.WProgressFlow=_._sfc_main$20;exports.WSectionHeader=_._sfc_main$21;exports.WStatusTag=_._sfc_main$22;exports.WStepFlow=_._sfc_main$23;exports.WStepSection=_._sfc_main$24;exports.WTransferList=_._sfc_main$25;exports.WTreeSelect=_._sfc_main$26;
2
2
  //# sourceMappingURL=components.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"components.cjs","sources":["../src/components/form/WFileUpload.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed } from 'vue'\nimport Button from 'primevue/button'\n\n/**\n * Upload de arquivo(s) genérico (single ou multiple), sem dependência pesada.\n * O `v-model` guarda `File` (single) ou `File[]` (multiple). Valida tamanho por\n * arquivo e emite `error` para os que excederem.\n */\nconst props = withDefaults(\n defineProps<{\n modelValue?: File | File[] | null\n multiple?: boolean\n accept?: string\n /** Tamanho máximo por arquivo em bytes (default 10MB). */\n maxSize?: number\n disabled?: boolean\n chooseLabel?: string\n }>(),\n {\n modelValue: null,\n multiple: false,\n accept: undefined,\n maxSize: 10_485_760,\n disabled: false,\n chooseLabel: 'Selecionar arquivo',\n },\n)\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: File | File[] | null]\n error: [message: string]\n}>()\n\nconst input = ref<HTMLInputElement | null>(null)\nconst files = computed<File[]>(() => {\n const v = props.modelValue\n if (!v) return []\n return Array.isArray(v) ? v : [v]\n})\n\nfunction open() {\n input.value?.click()\n}\n\nfunction onChange(e: Event) {\n const el = e.target as HTMLInputElement\n const picked = Array.from(el.files || [])\n el.value = ''\n const valid: File[] = []\n for (const f of picked) {\n if (f.size > props.maxSize) {\n emit('error', `\"${f.name}\" acima do limite de ${(props.maxSize / 1_048_576).toFixed(1)}MB.`)\n continue\n }\n valid.push(f)\n }\n if (!valid.length) return\n emit('update:modelValue', props.multiple ? [...files.value, ...valid] : valid[0])\n}\n\nfunction removeAt(i: number) {\n if (!props.multiple) {\n emit('update:modelValue', null)\n return\n }\n const next = files.value.slice()\n next.splice(i, 1)\n emit('update:modelValue', next.length ? next : null)\n}\n\nfunction fmtSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1_048_576) return `${(bytes / 1024).toFixed(0)} KB`\n return `${(bytes / 1_048_576).toFixed(1)} MB`\n}\n</script>\n\n<template>\n <div class=\"w-fileupload\" style=\"display: flex; flex-direction: column; gap: 0.5rem\">\n <div>\n <Button\n type=\"button\"\n :label=\"chooseLabel\"\n icon=\"pi pi-upload\"\n outlined\n size=\"small\"\n :disabled=\"disabled\"\n @click=\"open\"\n />\n </div>\n <input\n ref=\"input\"\n type=\"file\"\n :accept=\"accept\"\n :multiple=\"multiple\"\n style=\"display: none\"\n @change=\"onChange\"\n />\n <ul\n v-if=\"files.length\"\n style=\"\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 0.35rem;\n \"\n >\n <li\n v-for=\"(f, i) in files\"\n :key=\"`${f.name}-${i}`\"\n style=\"display: flex; align-items: center; gap: 0.5rem; font-size: 0.85rem\"\n >\n <i class=\"pi pi-file\" style=\"opacity: 0.6\" />\n <span style=\"flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap\">\n {{ f.name }}\n </span>\n <span style=\"opacity: 0.6\">{{ fmtSize(f.size) }}</span>\n <Button\n type=\"button\"\n icon=\"pi pi-times\"\n text\n rounded\n size=\"small\"\n severity=\"danger\"\n :disabled=\"disabled\"\n @click=\"removeAt(i)\"\n />\n </li>\n </ul>\n <slot v-else name=\"empty\">\n <span style=\"font-size: 0.8rem; opacity: 0.6\">Nenhum arquivo selecionado</span>\n </slot>\n </div>\n</template>\n"],"names":["props","__props","emit","__emit","input","ref","files","computed","v","open","_a","onChange","e","el","picked","valid","f","removeAt","i","next","fmtSize","bytes","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_createVNode","_unref","Button","_hoisted_3","_Fragment","_renderList","_hoisted_4","_toDisplayString","_hoisted_5","$event","_renderSlot","_ctx","_cache"],"mappings":"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"}
1
+ {"version":3,"file":"components.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}