@wrrdev/fenix-ui 1.0.17 → 1.1.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.
- package/README.md +2 -2
- package/dist/_virtual/preload-helper.js +68 -0
- package/dist/_virtual/preload-helper.js.map +1 -0
- package/dist/assets/base-css-BifSeW2H.js +31 -0
- package/dist/assets/base-css-BifSeW2H.js.map +1 -0
- package/dist/components/alert/alert.d.ts +2 -1
- package/dist/components/alert/alert.d.ts.map +1 -1
- package/dist/components/alert/alert.js +10 -2
- package/dist/components/alert/alert.js.map +1 -1
- package/dist/components/avatar/avatar.d.ts +21 -0
- package/dist/components/avatar/avatar.d.ts.map +1 -0
- package/dist/components/avatar/avatar.js +91 -0
- package/dist/components/avatar/avatar.js.map +1 -0
- package/dist/components/avatar/index.d.ts +8 -0
- package/dist/components/avatar/index.d.ts.map +1 -0
- package/dist/components/avatar/index.js +7 -0
- package/dist/components/avatar/index.js.map +1 -0
- package/dist/components/breadcrumb/breadcrumb.d.ts +35 -0
- package/dist/components/breadcrumb/breadcrumb.d.ts.map +1 -0
- package/dist/components/breadcrumb/breadcrumb.js +113 -0
- package/dist/components/breadcrumb/breadcrumb.js.map +1 -0
- package/dist/components/breadcrumb/index.d.ts +8 -0
- package/dist/components/breadcrumb/index.d.ts.map +1 -0
- package/dist/components/breadcrumb/index.js +7 -0
- package/dist/components/breadcrumb/index.js.map +1 -0
- package/dist/components/card/card.d.ts +15 -0
- package/dist/components/card/card.d.ts.map +1 -0
- package/dist/components/card/card.js +80 -0
- package/dist/components/card/card.js.map +1 -0
- package/dist/components/card/index.d.ts +8 -0
- package/dist/components/card/index.d.ts.map +1 -0
- package/dist/components/card/index.js +7 -0
- package/dist/components/card/index.js.map +1 -0
- package/dist/components/carousel/carousel.d.ts +28 -0
- package/dist/components/carousel/carousel.d.ts.map +1 -0
- package/dist/components/carousel/carousel.js +176 -0
- package/dist/components/carousel/carousel.js.map +1 -0
- package/dist/components/carousel/index.d.ts +8 -0
- package/dist/components/carousel/index.d.ts.map +1 -0
- package/dist/components/carousel/index.js +7 -0
- package/dist/components/carousel/index.js.map +1 -0
- package/dist/components/chip/chip.d.ts +19 -0
- package/dist/components/chip/chip.d.ts.map +1 -0
- package/dist/components/chip/chip.js +126 -0
- package/dist/components/chip/chip.js.map +1 -0
- package/dist/components/chip/index.d.ts +8 -0
- package/dist/components/chip/index.d.ts.map +1 -0
- package/dist/components/chip/index.js +7 -0
- package/dist/components/chip/index.js.map +1 -0
- package/dist/components/confirmpopup/confirmpopup.d.ts +44 -0
- package/dist/components/confirmpopup/confirmpopup.d.ts.map +1 -0
- package/dist/components/confirmpopup/confirmpopup.js +233 -0
- package/dist/components/confirmpopup/confirmpopup.js.map +1 -0
- package/dist/components/confirmpopup/index.d.ts +8 -0
- package/dist/components/confirmpopup/index.d.ts.map +1 -0
- package/dist/components/confirmpopup/index.js +7 -0
- package/dist/components/confirmpopup/index.js.map +1 -0
- package/dist/components/empty-state/empty-state.d.ts +14 -0
- package/dist/components/empty-state/empty-state.d.ts.map +1 -0
- package/dist/components/empty-state/empty-state.js +71 -0
- package/dist/components/empty-state/empty-state.js.map +1 -0
- package/dist/components/empty-state/index.d.ts +8 -0
- package/dist/components/empty-state/index.d.ts.map +1 -0
- package/dist/components/empty-state/index.js +7 -0
- package/dist/components/empty-state/index.js.map +1 -0
- package/dist/components/fileupload/fileupload.d.ts +42 -0
- package/dist/components/fileupload/fileupload.d.ts.map +1 -0
- package/dist/components/fileupload/fileupload.js +284 -0
- package/dist/components/fileupload/fileupload.js.map +1 -0
- package/dist/components/fileupload/index.d.ts +8 -0
- package/dist/components/fileupload/index.d.ts.map +1 -0
- package/dist/components/fileupload/index.js +7 -0
- package/dist/components/fileupload/index.js.map +1 -0
- package/dist/components/menu/index.d.ts +8 -0
- package/dist/components/menu/index.d.ts.map +1 -0
- package/dist/components/menu/index.js +7 -0
- package/dist/components/menu/index.js.map +1 -0
- package/dist/components/menu/menu.d.ts +23 -0
- package/dist/components/menu/menu.d.ts.map +1 -0
- package/dist/components/menu/menu.js +155 -0
- package/dist/components/menu/menu.js.map +1 -0
- package/dist/components/orderlist/orderlist.d.ts +1 -1
- package/dist/components/orderlist/orderlist.d.ts.map +1 -1
- package/dist/components/orderlist/orderlist.js +2 -2
- package/dist/components/orderlist/orderlist.js.map +1 -1
- package/dist/components/password-strength/index.d.ts +8 -0
- package/dist/components/password-strength/index.d.ts.map +1 -0
- package/dist/components/password-strength/index.js +7 -0
- package/dist/components/password-strength/index.js.map +1 -0
- package/dist/components/password-strength/password-strength.d.ts +23 -0
- package/dist/components/password-strength/password-strength.d.ts.map +1 -0
- package/dist/components/password-strength/password-strength.js +109 -0
- package/dist/components/password-strength/password-strength.js.map +1 -0
- package/dist/components/picklist/picklist.d.ts +1 -1
- package/dist/components/picklist/picklist.d.ts.map +1 -1
- package/dist/components/picklist/picklist.js +2 -2
- package/dist/components/picklist/picklist.js.map +1 -1
- package/dist/components/popover/index.d.ts +8 -0
- package/dist/components/popover/index.d.ts.map +1 -0
- package/dist/components/popover/index.js +7 -0
- package/dist/components/popover/index.js.map +1 -0
- package/dist/components/popover/popover.d.ts +39 -0
- package/dist/components/popover/popover.d.ts.map +1 -0
- package/dist/components/popover/popover.js +228 -0
- package/dist/components/popover/popover.js.map +1 -0
- package/dist/components/rating/index.d.ts +8 -0
- package/dist/components/rating/index.d.ts.map +1 -0
- package/dist/components/rating/index.js +7 -0
- package/dist/components/rating/index.js.map +1 -0
- package/dist/components/rating/rating.d.ts +25 -0
- package/dist/components/rating/rating.d.ts.map +1 -0
- package/dist/components/rating/rating.js +119 -0
- package/dist/components/rating/rating.js.map +1 -0
- package/dist/components/slider/index.d.ts +8 -0
- package/dist/components/slider/index.d.ts.map +1 -0
- package/dist/components/slider/index.js +7 -0
- package/dist/components/slider/index.js.map +1 -0
- package/dist/components/slider/slider.d.ts +33 -0
- package/dist/components/slider/slider.d.ts.map +1 -0
- package/dist/components/slider/slider.js +260 -0
- package/dist/components/slider/slider.js.map +1 -0
- package/dist/components/stepper/index.d.ts +8 -0
- package/dist/components/stepper/index.d.ts.map +1 -0
- package/dist/components/stepper/index.js +7 -0
- package/dist/components/stepper/index.js.map +1 -0
- package/dist/components/stepper/stepper.d.ts +33 -0
- package/dist/components/stepper/stepper.d.ts.map +1 -0
- package/dist/components/stepper/stepper.js +162 -0
- package/dist/components/stepper/stepper.js.map +1 -0
- package/dist/components/timeline/index.d.ts +8 -0
- package/dist/components/timeline/index.d.ts.map +1 -0
- package/dist/components/timeline/index.js +7 -0
- package/dist/components/timeline/index.js.map +1 -0
- package/dist/components/timeline/timeline.d.ts +30 -0
- package/dist/components/timeline/timeline.d.ts.map +1 -0
- package/dist/components/timeline/timeline.js +146 -0
- package/dist/components/timeline/timeline.js.map +1 -0
- package/dist/components/toast/toast.d.ts.map +1 -1
- package/dist/components/toast/toast.js +21 -2
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/components/toggle-button-group/index.d.ts +8 -0
- package/dist/components/toggle-button-group/index.d.ts.map +1 -0
- package/dist/components/toggle-button-group/index.js +7 -0
- package/dist/components/toggle-button-group/index.js.map +1 -0
- package/dist/components/toggle-button-group/toggle-button-group.d.ts +21 -0
- package/dist/components/toggle-button-group/toggle-button-group.d.ts.map +1 -0
- package/dist/components/toggle-button-group/toggle-button-group.js +103 -0
- package/dist/components/toggle-button-group/toggle-button-group.js.map +1 -0
- package/dist/components/tree/index.d.ts +8 -0
- package/dist/components/tree/index.d.ts.map +1 -0
- package/dist/components/tree/index.js +7 -0
- package/dist/components/tree/index.js.map +1 -0
- package/dist/components/tree/tree.d.ts +34 -0
- package/dist/components/tree/tree.d.ts.map +1 -0
- package/dist/components/tree/tree.js +149 -0
- package/dist/components/tree/tree.js.map +1 -0
- package/dist/core/base.d.ts +1 -1
- package/dist/core/base.d.ts.map +1 -1
- package/dist/core/base.js +1 -1
- package/dist/core/base.js.map +1 -1
- package/dist/docs/app.d.ts.map +1 -1
- package/dist/docs/componentes/avatar.doc.d.ts +6 -0
- package/dist/docs/componentes/avatar.doc.d.ts.map +1 -0
- package/dist/docs/componentes/breadcrumb.doc.d.ts +6 -0
- package/dist/docs/componentes/breadcrumb.doc.d.ts.map +1 -0
- package/dist/docs/componentes/card.doc.d.ts +6 -0
- package/dist/docs/componentes/card.doc.d.ts.map +1 -0
- package/dist/docs/componentes/carousel.doc.d.ts +6 -0
- package/dist/docs/componentes/carousel.doc.d.ts.map +1 -0
- package/dist/docs/componentes/chip.doc.d.ts +6 -0
- package/dist/docs/componentes/chip.doc.d.ts.map +1 -0
- package/dist/docs/componentes/confirmpopup.doc.d.ts +6 -0
- package/dist/docs/componentes/confirmpopup.doc.d.ts.map +1 -0
- package/dist/docs/componentes/empty-state.doc.d.ts +6 -0
- package/dist/docs/componentes/empty-state.doc.d.ts.map +1 -0
- package/dist/docs/componentes/fileupload.doc.d.ts +6 -0
- package/dist/docs/componentes/fileupload.doc.d.ts.map +1 -0
- package/dist/docs/componentes/index.d.ts.map +1 -1
- package/dist/docs/componentes/menu.doc.d.ts +6 -0
- package/dist/docs/componentes/menu.doc.d.ts.map +1 -0
- package/dist/docs/componentes/password-strength.doc.d.ts +6 -0
- package/dist/docs/componentes/password-strength.doc.d.ts.map +1 -0
- package/dist/docs/componentes/popover.doc.d.ts +6 -0
- package/dist/docs/componentes/popover.doc.d.ts.map +1 -0
- package/dist/docs/componentes/rating.doc.d.ts +6 -0
- package/dist/docs/componentes/rating.doc.d.ts.map +1 -0
- package/dist/docs/componentes/slider.doc.d.ts +6 -0
- package/dist/docs/componentes/slider.doc.d.ts.map +1 -0
- package/dist/docs/componentes/stepper.doc.d.ts +6 -0
- package/dist/docs/componentes/stepper.doc.d.ts.map +1 -0
- package/dist/docs/componentes/timeline.doc.d.ts +6 -0
- package/dist/docs/componentes/timeline.doc.d.ts.map +1 -0
- package/dist/docs/componentes/toggle-button-group.doc.d.ts +6 -0
- package/dist/docs/componentes/toggle-button-group.doc.d.ts.map +1 -0
- package/dist/docs/componentes/tree.doc.d.ts +6 -0
- package/dist/docs/componentes/tree.doc.d.ts.map +1 -0
- package/dist/fenix-icons.woff2 +0 -0
- package/dist/fenix-ui.umd.min.js +1317 -160
- package/dist/fenix-ui2.esm.js +4317 -7816
- package/dist/fenix-ui2.esm.js.map +1 -1
- package/dist/fenix-ui3.esm.js +10396 -84
- package/dist/fenix-ui3.esm.js.map +1 -1
- package/dist/fenix-ui4.esm.js +110 -0
- package/dist/fenix-ui4.esm.js.map +1 -0
- package/dist/icons/base-css.d.ts +21 -0
- package/dist/icons/base-css.d.ts.map +1 -0
- package/dist/icons/base-css.js +32 -0
- package/dist/icons/base-css.js.map +1 -0
- package/dist/icons/fenix-icons.woff2 +0 -0
- package/dist/icons/index.d.ts +31 -0
- package/dist/icons/index.d.ts.map +1 -0
- package/dist/icons/index.js +47 -0
- package/dist/icons/index.js.map +1 -0
- package/dist/icons/names.d.ts +11 -0
- package/dist/icons/names.d.ts.map +1 -0
- package/dist/icons/names.js +4283 -0
- package/dist/icons/names.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -1
- package/dist/plugins/auto-import.d.ts +2 -0
- package/dist/plugins/auto-import.d.ts.map +1 -1
- package/dist/plugins/auto-import.js +23 -0
- package/dist/plugins/auto-import.js.map +1 -1
- package/package.json +74 -1
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { FxElement } from "../../core/base.js";
|
|
2
|
+
import { css } from "../../core/css.js";
|
|
3
|
+
import { defineElement } from "../../core/define.js";
|
|
4
|
+
import { esc } from "../../core/sanitize.js";
|
|
5
|
+
const _FxFileUpload = class _FxFileUpload extends FxElement {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this._files = [];
|
|
9
|
+
this._done = false;
|
|
10
|
+
}
|
|
11
|
+
static get observedAttributes() {
|
|
12
|
+
return ["mode", "size", "severity", "label", "icon", "accept", "multiple", "disabled", "show-progress", "progress", "value"];
|
|
13
|
+
}
|
|
14
|
+
get size() {
|
|
15
|
+
const s = this.getAttr("size", "md");
|
|
16
|
+
return s === "sm" || s === "lg" ? s : "md";
|
|
17
|
+
}
|
|
18
|
+
set size(value) {
|
|
19
|
+
this.setAttribute("size", value);
|
|
20
|
+
}
|
|
21
|
+
/** Nomes dos arquivos selecionados (espelho em `value`). */
|
|
22
|
+
get value() {
|
|
23
|
+
return this.getAttr("value");
|
|
24
|
+
}
|
|
25
|
+
set value(v) {
|
|
26
|
+
this.setAttribute("value", v);
|
|
27
|
+
}
|
|
28
|
+
get progress() {
|
|
29
|
+
return Math.min(100, Math.max(0, Number(this.getAttr("progress", "0")) || 0));
|
|
30
|
+
}
|
|
31
|
+
set progress(v) {
|
|
32
|
+
this.setAttribute("progress", String(v));
|
|
33
|
+
}
|
|
34
|
+
/** Arquivos selecionados (não serializável em atributo). */
|
|
35
|
+
get files() {
|
|
36
|
+
return this._files;
|
|
37
|
+
}
|
|
38
|
+
set files(files) {
|
|
39
|
+
this._files = Array.from(files);
|
|
40
|
+
this.value = this._files.map((f) => f.name).join(", ");
|
|
41
|
+
this._syncFilesArea();
|
|
42
|
+
}
|
|
43
|
+
render() {
|
|
44
|
+
const mode = this.getAttr("mode", "basic");
|
|
45
|
+
const advanced = mode === "advanced";
|
|
46
|
+
const label = this.getAttr("label", "Escolher arquivo");
|
|
47
|
+
const icon = this.getAttr("icon");
|
|
48
|
+
const accept = this.getAttr("accept");
|
|
49
|
+
const multiple = this.hasAttr("multiple");
|
|
50
|
+
const disabled = this.hasAttr("disabled");
|
|
51
|
+
const showProgress = this.hasAttr("show-progress");
|
|
52
|
+
const pct = this.progress;
|
|
53
|
+
const fileInput = `<input type="file" class="picker" ${accept ? `accept="${esc(accept)}"` : ""} ${multiple ? "multiple" : ""} ${disabled ? "disabled" : ""} />`;
|
|
54
|
+
this.setTemplate(`
|
|
55
|
+
${advanced ? `<div class="drop" part="dropzone" role="button" tabindex="0" aria-label="${esc(label)}">
|
|
56
|
+
${icon ? `<span class="icon" aria-hidden="true">${esc(icon)}</span>` : ""}
|
|
57
|
+
<span>${esc(label)}</span>
|
|
58
|
+
<span class="hint">ou arraste e solte aqui</span>
|
|
59
|
+
</div>` : `<button type="button" class="btn" part="button">
|
|
60
|
+
${icon ? `<span class="icon" aria-hidden="true">${esc(icon)}</span>` : ""}
|
|
61
|
+
<span>${esc(label)}</span>
|
|
62
|
+
</button>`}
|
|
63
|
+
${fileInput}
|
|
64
|
+
<div class="files" part="files"></div>
|
|
65
|
+
${showProgress ? `
|
|
66
|
+
<div class="progress-row" part="progress">
|
|
67
|
+
<div class="track" role="progressbar" aria-valuenow="${pct}" aria-valuemin="0" aria-valuemax="100">
|
|
68
|
+
<div class="bar" style="width: ${pct}%"></div>
|
|
69
|
+
</div>
|
|
70
|
+
<span class="pct">${pct}%</span>
|
|
71
|
+
</div>` : ""}
|
|
72
|
+
`);
|
|
73
|
+
this._bindPicker();
|
|
74
|
+
this._syncFilesArea();
|
|
75
|
+
if (!this._done && showProgress && pct >= 100 && this._files.length) {
|
|
76
|
+
this._done = true;
|
|
77
|
+
this.dispatchEvent(new CustomEvent("complete", { bubbles: true, composed: true }));
|
|
78
|
+
}
|
|
79
|
+
if (pct < 100) this._done = false;
|
|
80
|
+
}
|
|
81
|
+
_picker() {
|
|
82
|
+
return this.root.querySelector(".picker");
|
|
83
|
+
}
|
|
84
|
+
_bindPicker() {
|
|
85
|
+
const picker = this._picker();
|
|
86
|
+
if (!picker) return;
|
|
87
|
+
const trigger = this.root.querySelector(".btn") ?? this.root.querySelector(".drop");
|
|
88
|
+
trigger?.addEventListener("click", () => picker.click());
|
|
89
|
+
trigger?.addEventListener("keydown", (e) => {
|
|
90
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
91
|
+
e.preventDefault();
|
|
92
|
+
picker.click();
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
picker.addEventListener("change", () => this._acceptFiles(picker.files ?? []));
|
|
96
|
+
const drop = this.root.querySelector(".drop");
|
|
97
|
+
if (!drop) return;
|
|
98
|
+
drop.addEventListener("dragover", (e) => {
|
|
99
|
+
e.preventDefault();
|
|
100
|
+
drop.classList.add("over");
|
|
101
|
+
});
|
|
102
|
+
drop.addEventListener("dragleave", () => drop.classList.remove("over"));
|
|
103
|
+
drop.addEventListener("drop", (e) => {
|
|
104
|
+
e.preventDefault();
|
|
105
|
+
drop.classList.remove("over");
|
|
106
|
+
if (e.dataTransfer?.files.length) this._acceptFiles(e.dataTransfer.files);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
_acceptFiles(list) {
|
|
110
|
+
const picked = this.hasAttr("multiple") ? Array.from(list) : [list[0]].filter(Boolean);
|
|
111
|
+
this.files = picked;
|
|
112
|
+
const picker = this._picker();
|
|
113
|
+
if (picker) picker.value = "";
|
|
114
|
+
this.dispatchEvent(
|
|
115
|
+
new CustomEvent("select", { bubbles: true, composed: true, detail: { files: picked } })
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
_fmtSize(bytes) {
|
|
119
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
120
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
121
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
122
|
+
}
|
|
123
|
+
/** Renderiza a lista de arquivos sem re-renderizar o template (mantém estado). */
|
|
124
|
+
_syncFilesArea() {
|
|
125
|
+
const area = this.root?.querySelector?.(".files");
|
|
126
|
+
if (!area) return;
|
|
127
|
+
area.innerHTML = this._files.map(
|
|
128
|
+
(f, i) => `
|
|
129
|
+
<div class="file" part="file">
|
|
130
|
+
<span class="name">${esc(f.name)}</span>
|
|
131
|
+
<span class="size">${this._fmtSize(f.size)}</span>
|
|
132
|
+
<button type="button" class="remove" data-i="${i}" part="remove" aria-label="Remover ${esc(f.name)}">×</button>
|
|
133
|
+
</div>`
|
|
134
|
+
).join("");
|
|
135
|
+
area.querySelectorAll(".remove").forEach(
|
|
136
|
+
(btn) => btn.addEventListener("click", () => {
|
|
137
|
+
const removed = this._files.splice(Number(btn.dataset.i), 1)[0];
|
|
138
|
+
this.value = this._files.map((f) => f.name).join(", ");
|
|
139
|
+
this.progress = 0;
|
|
140
|
+
this._syncFilesArea();
|
|
141
|
+
this.dispatchEvent(
|
|
142
|
+
new CustomEvent("remove", { bubbles: true, composed: true, detail: { file: removed } })
|
|
143
|
+
);
|
|
144
|
+
})
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
_FxFileUpload.styles = css`
|
|
149
|
+
:host {
|
|
150
|
+
display: inline-block;
|
|
151
|
+
font-family: var(--fx-font-family);
|
|
152
|
+
font-size: var(--fx-font-size);
|
|
153
|
+
}
|
|
154
|
+
:host([disabled]) { opacity: 0.55; pointer-events: none; }
|
|
155
|
+
input[type='file'] { display: none; }
|
|
156
|
+
|
|
157
|
+
/* ---- botão (basic) ---- */
|
|
158
|
+
.btn {
|
|
159
|
+
display: inline-flex;
|
|
160
|
+
align-items: center;
|
|
161
|
+
justify-content: center;
|
|
162
|
+
gap: var(--fx-space-sm);
|
|
163
|
+
min-height: var(--fx-size-md);
|
|
164
|
+
padding: var(--fx-space-md) var(--fx-space-lg);
|
|
165
|
+
font-family: inherit;
|
|
166
|
+
font-size: inherit;
|
|
167
|
+
font-weight: var(--fx-font-weight);
|
|
168
|
+
color: var(--fx-text-default);
|
|
169
|
+
background-color: var(--fx-surface-background);
|
|
170
|
+
border: 1px solid var(--fx-border-default);
|
|
171
|
+
border-radius: var(--fx-radius-md);
|
|
172
|
+
cursor: pointer;
|
|
173
|
+
box-sizing: border-box;
|
|
174
|
+
transition:
|
|
175
|
+
border-color var(--fx-motion-duration-normal) var(--fx-motion-easing),
|
|
176
|
+
box-shadow var(--fx-motion-duration-normal) var(--fx-motion-easing),
|
|
177
|
+
background var(--fx-motion-duration-normal) var(--fx-motion-easing);
|
|
178
|
+
}
|
|
179
|
+
.btn:hover { border-color: var(--fx-border-hover); background: var(--fx-surface-surface-hover, rgba(0,0,0,0.03)); }
|
|
180
|
+
.btn:focus-visible {
|
|
181
|
+
outline: none;
|
|
182
|
+
border-color: var(--fx-color-primary);
|
|
183
|
+
box-shadow: var(--fx-effect-focus-ring, none);
|
|
184
|
+
}
|
|
185
|
+
/* Severities (como no <fx-button>) — aplicam-se ao botão do modo basic */
|
|
186
|
+
:host([severity='primary']) .btn { background: var(--fx-color-primary); border-color: transparent; color: #fff; }
|
|
187
|
+
:host([severity='secondary']) .btn { background: var(--fx-color-secondary); border-color: transparent; color: #fff; }
|
|
188
|
+
:host([severity='success']) .btn { background: var(--fx-color-success); border-color: transparent; color: #fff; }
|
|
189
|
+
:host([severity='warning']) .btn { background: var(--fx-color-warning); border-color: transparent; color: #fff; }
|
|
190
|
+
:host([severity='danger']) .btn { background: var(--fx-color-danger); border-color: transparent; color: #fff; }
|
|
191
|
+
:host([severity='info']) .btn { background: var(--fx-color-info); border-color: transparent; color: #fff; }
|
|
192
|
+
:host([severity]) .btn:hover { filter: brightness(0.88); }
|
|
193
|
+
:host([severity]) .btn:focus-visible { border-color: transparent; }
|
|
194
|
+
:host([size='sm']) .btn { min-height: var(--fx-size-sm); padding: var(--fx-space-sm) var(--fx-space-md); font-size: calc(var(--fx-font-size) - 2px); }
|
|
195
|
+
:host([size='lg']) .btn { min-height: var(--fx-size-lg); padding: var(--fx-space-lg) var(--fx-space-xl); font-size: calc(var(--fx-font-size) + 4px); }
|
|
196
|
+
:host([size='sm']) .drop { min-height: 72px; }
|
|
197
|
+
:host([size='lg']) .drop { min-height: 132px; }
|
|
198
|
+
|
|
199
|
+
/* ---- dropzone (advanced) ---- */
|
|
200
|
+
.drop {
|
|
201
|
+
display: flex;
|
|
202
|
+
flex-direction: column;
|
|
203
|
+
align-items: center;
|
|
204
|
+
justify-content: center;
|
|
205
|
+
gap: var(--fx-space-sm);
|
|
206
|
+
min-height: 100px;
|
|
207
|
+
padding: var(--fx-space-lg);
|
|
208
|
+
border: 2px dashed var(--fx-border-default);
|
|
209
|
+
border-radius: var(--fx-radius-md);
|
|
210
|
+
color: var(--fx-text-muted);
|
|
211
|
+
cursor: pointer;
|
|
212
|
+
text-align: center;
|
|
213
|
+
transition: border-color var(--fx-motion-duration-normal) var(--fx-motion-easing), background var(--fx-motion-duration-normal) var(--fx-motion-easing);
|
|
214
|
+
}
|
|
215
|
+
.drop:hover, .drop.over {
|
|
216
|
+
border-color: var(--fx-color-primary);
|
|
217
|
+
background: color-mix(in srgb, var(--fx-color-primary) 6%, transparent);
|
|
218
|
+
}
|
|
219
|
+
.drop .icon { font-size: calc(var(--fx-font-size) + 12px); line-height: 1; }
|
|
220
|
+
.drop .hint { font-size: calc(var(--fx-font-size) - 2px); }
|
|
221
|
+
|
|
222
|
+
/* ---- ícone comum ---- */
|
|
223
|
+
.icon { line-height: 1; }
|
|
224
|
+
|
|
225
|
+
/* ---- arquivo(s) selecionado(s) ---- */
|
|
226
|
+
.files { display: flex; flex-direction: column; gap: var(--fx-space-xs); margin-top: var(--fx-space-sm); }
|
|
227
|
+
.file {
|
|
228
|
+
display: flex;
|
|
229
|
+
align-items: center;
|
|
230
|
+
gap: var(--fx-space-sm);
|
|
231
|
+
padding: var(--fx-space-xs) var(--fx-space-sm);
|
|
232
|
+
border: 1px solid var(--fx-border-default);
|
|
233
|
+
border-radius: var(--fx-radius-sm);
|
|
234
|
+
font-size: calc(var(--fx-font-size) - 2px);
|
|
235
|
+
color: var(--fx-text-default);
|
|
236
|
+
}
|
|
237
|
+
.file .name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
238
|
+
.file .size { color: var(--fx-text-muted); white-space: nowrap; }
|
|
239
|
+
.file .remove {
|
|
240
|
+
border: none;
|
|
241
|
+
background: transparent;
|
|
242
|
+
color: var(--fx-text-muted);
|
|
243
|
+
cursor: pointer;
|
|
244
|
+
font-size: calc(var(--fx-font-size) + 2px);
|
|
245
|
+
line-height: 1;
|
|
246
|
+
padding: 0 var(--fx-space-xs);
|
|
247
|
+
border-radius: var(--fx-radius-full);
|
|
248
|
+
}
|
|
249
|
+
.file .remove:hover { color: var(--fx-color-danger); }
|
|
250
|
+
|
|
251
|
+
/* ---- progresso ---- */
|
|
252
|
+
.progress-row { display: flex; align-items: center; gap: var(--fx-space-sm); margin-top: var(--fx-space-sm); }
|
|
253
|
+
.track {
|
|
254
|
+
flex: 1;
|
|
255
|
+
height: 6px;
|
|
256
|
+
background: var(--fx-surface-surface-hover);
|
|
257
|
+
border-radius: var(--fx-radius-full);
|
|
258
|
+
overflow: hidden;
|
|
259
|
+
}
|
|
260
|
+
.bar {
|
|
261
|
+
height: 100%;
|
|
262
|
+
width: 0%;
|
|
263
|
+
background: var(--fx-color-primary);
|
|
264
|
+
border-radius: var(--fx-radius-full);
|
|
265
|
+
transition: width var(--fx-motion-duration-normal) var(--fx-motion-easing);
|
|
266
|
+
}
|
|
267
|
+
:host([progress='100']) .bar { background: var(--fx-color-success); }
|
|
268
|
+
.pct {
|
|
269
|
+
font-size: calc(var(--fx-font-size) - 2px);
|
|
270
|
+
font-weight: 600;
|
|
271
|
+
color: var(--fx-text-default);
|
|
272
|
+
min-width: 34px;
|
|
273
|
+
text-align: right;
|
|
274
|
+
}
|
|
275
|
+
`;
|
|
276
|
+
let FxFileUpload = _FxFileUpload;
|
|
277
|
+
function defineFxFileUpload() {
|
|
278
|
+
return defineElement("fx-fileupload", FxFileUpload);
|
|
279
|
+
}
|
|
280
|
+
export {
|
|
281
|
+
FxFileUpload,
|
|
282
|
+
defineFxFileUpload
|
|
283
|
+
};
|
|
284
|
+
//# sourceMappingURL=fileupload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileupload.js","sources":["../../../src/components/fileupload/fileupload.ts"],"sourcesContent":["import { FxElement } from '../../core/base';\nimport { css } from '../../core/css';\nimport { defineElement } from '../../core/define';\nimport { esc } from '../../core/sanitize';\n\n/**\n * <fx-fileupload> — Seletor de arquivos com upload e progresso (estilo FileUpload do PrimeVue).\n *\n * Atributos:\n * - mode (basic|advanced — `basic`: botão; `advanced`: dropzone com drag & drop);\n * - size (sm|md|lg, padrão md);\n * - severity (primary|secondary|success|warning|danger|info — cor do botão no modo basic);\n * - label (texto do botão/área, padrão 'Escolher arquivo');\n * - icon (glifo/emoji exibido antes do texto — sem o atributo, sem ícone);\n * - accept, multiple, disabled (como no <input type=\"file\">);\n * - show-progress (exibe barra + % de upload);\n * - progress (0-100 — o consumidor atualiza durante o upload real);\n * - value (nome(s) do(s) arquivo(s) carregado(s), somente leitura/espelho).\n *\n * Eventos (composed): `select` (detail: { files: File[] }), `remove`, `complete`.\n */\nexport class FxFileUpload extends FxElement {\n static override styles = css`\n :host {\n display: inline-block;\n font-family: var(--fx-font-family);\n font-size: var(--fx-font-size);\n }\n :host([disabled]) { opacity: 0.55; pointer-events: none; }\n input[type='file'] { display: none; }\n\n /* ---- botão (basic) ---- */\n .btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--fx-space-sm);\n min-height: var(--fx-size-md);\n padding: var(--fx-space-md) var(--fx-space-lg);\n font-family: inherit;\n font-size: inherit;\n font-weight: var(--fx-font-weight);\n color: var(--fx-text-default);\n background-color: var(--fx-surface-background);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-md);\n cursor: pointer;\n box-sizing: border-box;\n transition:\n border-color var(--fx-motion-duration-normal) var(--fx-motion-easing),\n box-shadow var(--fx-motion-duration-normal) var(--fx-motion-easing),\n background var(--fx-motion-duration-normal) var(--fx-motion-easing);\n }\n .btn:hover { border-color: var(--fx-border-hover); background: var(--fx-surface-surface-hover, rgba(0,0,0,0.03)); }\n .btn:focus-visible {\n outline: none;\n border-color: var(--fx-color-primary);\n box-shadow: var(--fx-effect-focus-ring, none);\n }\n /* Severities (como no <fx-button>) — aplicam-se ao botão do modo basic */\n :host([severity='primary']) .btn { background: var(--fx-color-primary); border-color: transparent; color: #fff; }\n :host([severity='secondary']) .btn { background: var(--fx-color-secondary); border-color: transparent; color: #fff; }\n :host([severity='success']) .btn { background: var(--fx-color-success); border-color: transparent; color: #fff; }\n :host([severity='warning']) .btn { background: var(--fx-color-warning); border-color: transparent; color: #fff; }\n :host([severity='danger']) .btn { background: var(--fx-color-danger); border-color: transparent; color: #fff; }\n :host([severity='info']) .btn { background: var(--fx-color-info); border-color: transparent; color: #fff; }\n :host([severity]) .btn:hover { filter: brightness(0.88); }\n :host([severity]) .btn:focus-visible { border-color: transparent; }\n :host([size='sm']) .btn { min-height: var(--fx-size-sm); padding: var(--fx-space-sm) var(--fx-space-md); font-size: calc(var(--fx-font-size) - 2px); }\n :host([size='lg']) .btn { min-height: var(--fx-size-lg); padding: var(--fx-space-lg) var(--fx-space-xl); font-size: calc(var(--fx-font-size) + 4px); }\n :host([size='sm']) .drop { min-height: 72px; }\n :host([size='lg']) .drop { min-height: 132px; }\n\n /* ---- dropzone (advanced) ---- */\n .drop {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--fx-space-sm);\n min-height: 100px;\n padding: var(--fx-space-lg);\n border: 2px dashed var(--fx-border-default);\n border-radius: var(--fx-radius-md);\n color: var(--fx-text-muted);\n cursor: pointer;\n text-align: center;\n transition: border-color var(--fx-motion-duration-normal) var(--fx-motion-easing), background var(--fx-motion-duration-normal) var(--fx-motion-easing);\n }\n .drop:hover, .drop.over {\n border-color: var(--fx-color-primary);\n background: color-mix(in srgb, var(--fx-color-primary) 6%, transparent);\n }\n .drop .icon { font-size: calc(var(--fx-font-size) + 12px); line-height: 1; }\n .drop .hint { font-size: calc(var(--fx-font-size) - 2px); }\n\n /* ---- ícone comum ---- */\n .icon { line-height: 1; }\n\n /* ---- arquivo(s) selecionado(s) ---- */\n .files { display: flex; flex-direction: column; gap: var(--fx-space-xs); margin-top: var(--fx-space-sm); }\n .file {\n display: flex;\n align-items: center;\n gap: var(--fx-space-sm);\n padding: var(--fx-space-xs) var(--fx-space-sm);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-sm);\n font-size: calc(var(--fx-font-size) - 2px);\n color: var(--fx-text-default);\n }\n .file .name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .file .size { color: var(--fx-text-muted); white-space: nowrap; }\n .file .remove {\n border: none;\n background: transparent;\n color: var(--fx-text-muted);\n cursor: pointer;\n font-size: calc(var(--fx-font-size) + 2px);\n line-height: 1;\n padding: 0 var(--fx-space-xs);\n border-radius: var(--fx-radius-full);\n }\n .file .remove:hover { color: var(--fx-color-danger); }\n\n /* ---- progresso ---- */\n .progress-row { display: flex; align-items: center; gap: var(--fx-space-sm); margin-top: var(--fx-space-sm); }\n .track {\n flex: 1;\n height: 6px;\n background: var(--fx-surface-surface-hover);\n border-radius: var(--fx-radius-full);\n overflow: hidden;\n }\n .bar {\n height: 100%;\n width: 0%;\n background: var(--fx-color-primary);\n border-radius: var(--fx-radius-full);\n transition: width var(--fx-motion-duration-normal) var(--fx-motion-easing);\n }\n :host([progress='100']) .bar { background: var(--fx-color-success); }\n .pct {\n font-size: calc(var(--fx-font-size) - 2px);\n font-weight: 600;\n color: var(--fx-text-default);\n min-width: 34px;\n text-align: right;\n }\n `;\n\n static override get observedAttributes(): string[] {\n return ['mode', 'size', 'severity', 'label', 'icon', 'accept', 'multiple', 'disabled', 'show-progress', 'progress', 'value'];\n }\n\n get size(): string {\n const s = this.getAttr('size', 'md');\n return s === 'sm' || s === 'lg' ? s : 'md';\n }\n set size(value: string) { this.setAttribute('size', value); }\n\n /** Nomes dos arquivos selecionados (espelho em `value`). */\n get value(): string { return this.getAttr('value'); }\n set value(v: string) { this.setAttribute('value', v); }\n\n get progress(): number { return Math.min(100, Math.max(0, Number(this.getAttr('progress', '0')) || 0)); }\n set progress(v: number) { this.setAttribute('progress', String(v)); }\n\n /** Arquivos selecionados (não serializável em atributo). */\n get files(): File[] { return this._files; }\n set files(files: File[]) {\n this._files = Array.from(files);\n this.value = this._files.map((f) => f.name).join(', ');\n this._syncFilesArea();\n }\n\n protected override render(): void {\n const mode = this.getAttr('mode', 'basic');\n const advanced = mode === 'advanced';\n const label = this.getAttr('label', 'Escolher arquivo');\n const icon = this.getAttr('icon');\n const accept = this.getAttr('accept');\n const multiple = this.hasAttr('multiple');\n const disabled = this.hasAttr('disabled');\n const showProgress = this.hasAttr('show-progress');\n const pct = this.progress;\n\n const fileInput = `<input type=\"file\" class=\"picker\" ${accept ? `accept=\"${esc(accept)}\"` : ''} ${multiple ? 'multiple' : ''} ${disabled ? 'disabled' : ''} />`;\n\n this.setTemplate(`\n ${advanced\n ? `<div class=\"drop\" part=\"dropzone\" role=\"button\" tabindex=\"0\" aria-label=\"${esc(label)}\">\n ${icon ? `<span class=\"icon\" aria-hidden=\"true\">${esc(icon)}</span>` : ''}\n <span>${esc(label)}</span>\n <span class=\"hint\">ou arraste e solte aqui</span>\n </div>`\n : `<button type=\"button\" class=\"btn\" part=\"button\">\n ${icon ? `<span class=\"icon\" aria-hidden=\"true\">${esc(icon)}</span>` : ''}\n <span>${esc(label)}</span>\n </button>`}\n ${fileInput}\n <div class=\"files\" part=\"files\"></div>\n ${showProgress ? `\n <div class=\"progress-row\" part=\"progress\">\n <div class=\"track\" role=\"progressbar\" aria-valuenow=\"${pct}\" aria-valuemin=\"0\" aria-valuemax=\"100\">\n <div class=\"bar\" style=\"width: ${pct}%\"></div>\n </div>\n <span class=\"pct\">${pct}%</span>\n </div>` : ''}\n `);\n\n this._bindPicker();\n this._syncFilesArea();\n\n if (!this._done && showProgress && pct >= 100 && this._files.length) {\n this._done = true;\n this.dispatchEvent(new CustomEvent('complete', { bubbles: true, composed: true }));\n }\n if (pct < 100) this._done = false;\n }\n\n private _files: File[] = [];\n private _done = false;\n\n private _picker(): HTMLInputElement | null {\n return this.root.querySelector<HTMLInputElement>('.picker');\n }\n\n private _bindPicker(): void {\n const picker = this._picker();\n if (!picker) return;\n const trigger = this.root.querySelector('.btn') ?? this.root.querySelector('.drop');\n trigger?.addEventListener('click', () => picker.click());\n trigger?.addEventListener('keydown', (e) => {\n if ((e as KeyboardEvent).key === 'Enter' || (e as KeyboardEvent).key === ' ') {\n e.preventDefault();\n picker.click();\n }\n });\n picker.addEventListener('change', () => this._acceptFiles(picker.files ?? []));\n\n // drag & drop (advanced)\n const drop = this.root.querySelector<HTMLElement>('.drop');\n if (!drop) return;\n drop.addEventListener('dragover', (e) => { e.preventDefault(); drop.classList.add('over'); });\n drop.addEventListener('dragleave', () => drop.classList.remove('over'));\n drop.addEventListener('drop', (e) => {\n e.preventDefault();\n drop.classList.remove('over');\n if (e.dataTransfer?.files.length) this._acceptFiles(e.dataTransfer.files);\n });\n }\n\n private _acceptFiles(list: FileList | File[]): void {\n const picked = this.hasAttr('multiple') ? Array.from(list) : [list[0]].filter(Boolean);\n this.files = picked;\n const picker = this._picker();\n if (picker) picker.value = '';\n this.dispatchEvent(\n new CustomEvent('select', { bubbles: true, composed: true, detail: { files: picked } }),\n );\n }\n\n private _fmtSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n }\n\n /** Renderiza a lista de arquivos sem re-renderizar o template (mantém estado). */\n private _syncFilesArea(): void {\n const area = this.root?.querySelector?.('.files') as HTMLElement | null;\n if (!area) return;\n area.innerHTML = this._files\n .map(\n (f, i) => `\n <div class=\"file\" part=\"file\">\n <span class=\"name\">${esc(f.name)}</span>\n <span class=\"size\">${this._fmtSize(f.size)}</span>\n <button type=\"button\" class=\"remove\" data-i=\"${i}\" part=\"remove\" aria-label=\"Remover ${esc(f.name)}\">×</button>\n </div>`,\n )\n .join('');\n area.querySelectorAll<HTMLButtonElement>('.remove').forEach((btn) =>\n btn.addEventListener('click', () => {\n const removed = this._files.splice(Number(btn.dataset.i), 1)[0];\n this.value = this._files.map((f) => f.name).join(', ');\n this.progress = 0;\n this._syncFilesArea();\n this.dispatchEvent(\n new CustomEvent('remove', { bubbles: true, composed: true, detail: { file: removed } }),\n );\n }),\n );\n }\n}\n\nexport function defineFxFileUpload(): typeof FxFileUpload {\n return defineElement('fx-fileupload', FxFileUpload);\n}\n\n\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/fileupload/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAsB,MAAM,cAAc,CAAC;AAEhE,OAAO,EAAE,YAAY,EAAE,CAAC;AAIxB,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,eAAe,EAAE,YAAY,CAAC;KAC/B;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/fileupload/index.ts"],"sourcesContent":["import { FxFileUpload, defineFxFileUpload } from './fileupload';\n\nexport { FxFileUpload };\n\ndefineFxFileUpload();\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'fx-fileupload': FxFileUpload;\n }\n}\n"],"names":[],"mappings":";;AAIA,mBAAA;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/menu/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAgB,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,MAAM,EAAE,CAAC;AAIlB,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,MAAM,CAAC;KACnB;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/menu/index.ts"],"sourcesContent":["import { FxMenu, defineFxMenu } from './menu';\n\nexport { FxMenu };\n\ndefineFxMenu();\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'fx-menu': FxMenu;\n }\n}"],"names":[],"mappings":";;AAIA,aAAA;"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { FxElement } from '../../core/base';
|
|
2
|
+
/**
|
|
3
|
+
* <fx-menu> — Menú de navegación (horizontal o vertical) con ítems y submenús.
|
|
4
|
+
*
|
|
5
|
+
* Atributos: orientation (horizontal|vertical), size (sm|md|lg),
|
|
6
|
+
* dense (reduce el alto), titles (separado por `,` para navegación).
|
|
7
|
+
* Slots `item`: cada ítem de menú con [slot="item"].
|
|
8
|
+
* Evento (composed): `select` (detail: { index, label }).
|
|
9
|
+
*/
|
|
10
|
+
export declare class FxMenu extends FxElement {
|
|
11
|
+
static styles: string;
|
|
12
|
+
static get observedAttributes(): string[];
|
|
13
|
+
get orientation(): string;
|
|
14
|
+
get items(): HTMLElement[];
|
|
15
|
+
protected render(): void;
|
|
16
|
+
private _bindItems;
|
|
17
|
+
protected connectedCallback(): void;
|
|
18
|
+
protected disconnectedCallback(): void;
|
|
19
|
+
private _onOutside;
|
|
20
|
+
private _setActive;
|
|
21
|
+
}
|
|
22
|
+
export declare function defineFxMenu(): typeof FxMenu;
|
|
23
|
+
//# sourceMappingURL=menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../../src/components/menu/menu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAK5C;;;;;;;GAOG;AACH,qBAAa,MAAO,SAAQ,SAAS;IACnC,OAAgB,MAAM,SAmDpB;IAEF,WAAoB,kBAAkB,IAAI,MAAM,EAAE,CAEjD;IAED,IAAI,WAAW,IAAI,MAAM,CAAsD;IAE/E,IAAI,KAAK,IAAI,WAAW,EAAE,CAEzB;cAEkB,MAAM,IAAI,IAAI;IAgCjC,OAAO,CAAC,UAAU;cAgCC,iBAAiB,IAAI,IAAI;cAKzB,oBAAoB,IAAI,IAAI;IAK/C,OAAO,CAAC,UAAU,CAKhB;IAEF,OAAO,CAAC,UAAU;CAKnB;AAED,wBAAgB,YAAY,IAAI,OAAO,MAAM,CAE5C"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { FxElement } from "../../core/base.js";
|
|
2
|
+
import { css } from "../../core/css.js";
|
|
3
|
+
import { defineElement } from "../../core/define.js";
|
|
4
|
+
import { esc } from "../../core/sanitize.js";
|
|
5
|
+
const _FxMenu = class _FxMenu extends FxElement {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this._onOutside = (e) => {
|
|
9
|
+
const path = e.composedPath();
|
|
10
|
+
this.root.querySelectorAll(".dropdown.open").forEach((d) => {
|
|
11
|
+
if (!path.includes(d)) d.classList.remove("open");
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
static get observedAttributes() {
|
|
16
|
+
return ["orientation", "size", "dense", "titles"];
|
|
17
|
+
}
|
|
18
|
+
get orientation() {
|
|
19
|
+
return this.getAttr("orientation", "horizontal");
|
|
20
|
+
}
|
|
21
|
+
get items() {
|
|
22
|
+
return Array.from(this.children).filter((el) => el.matches('[slot="item"]')).map((el) => el);
|
|
23
|
+
}
|
|
24
|
+
render() {
|
|
25
|
+
const titleAttr = this.getAttr("titles");
|
|
26
|
+
const titles = titleAttr ? titleAttr.split(",").map((s) => s.trim()) : [];
|
|
27
|
+
const items = this.items;
|
|
28
|
+
const itemsHtml = items.map((it, i) => {
|
|
29
|
+
const label = titles[i] || it.textContent?.trim() || `Item ${i + 1}`;
|
|
30
|
+
const hasSub = it.matches("[submenu]");
|
|
31
|
+
const disabled = it.hasAttribute("disabled");
|
|
32
|
+
const item = `
|
|
33
|
+
<span class="item" part="item" data-i="${i}" ${disabled ? 'aria-disabled="true"' : ""}>
|
|
34
|
+
${esc(label)}${hasSub ? `<span class="caret">▾</span>` : ""}
|
|
35
|
+
</span>`;
|
|
36
|
+
if (!hasSub) return item;
|
|
37
|
+
return `
|
|
38
|
+
<span class="submenu-wrap" part="submenu-wrap">
|
|
39
|
+
${item}
|
|
40
|
+
<div class="dropdown" part="submenu"><slot name="submenu-${i}"></slot></div>
|
|
41
|
+
</span>`;
|
|
42
|
+
}).join("");
|
|
43
|
+
this.setTemplate(`
|
|
44
|
+
<nav part="menu" aria-label="Menu">
|
|
45
|
+
${itemsHtml}
|
|
46
|
+
</nav>
|
|
47
|
+
`);
|
|
48
|
+
this._bindItems();
|
|
49
|
+
}
|
|
50
|
+
_bindItems() {
|
|
51
|
+
const items = Array.from(this.root.querySelectorAll(".item"));
|
|
52
|
+
items.forEach((item) => {
|
|
53
|
+
const i = Number(item.dataset.i);
|
|
54
|
+
item.addEventListener("click", () => {
|
|
55
|
+
if (item.getAttribute("aria-disabled") === "true") return;
|
|
56
|
+
const source = this.items[i];
|
|
57
|
+
const hasSub = source?.hasAttribute("submenu");
|
|
58
|
+
if (hasSub) {
|
|
59
|
+
this.root.querySelectorAll(".dropdown.open").forEach((d) => {
|
|
60
|
+
if (d !== item.parentElement?.querySelector(".dropdown")) d.classList.remove("open");
|
|
61
|
+
});
|
|
62
|
+
item.parentElement?.querySelector(".dropdown")?.classList.toggle("open");
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
this._setActive(item);
|
|
66
|
+
this.dispatchEvent(new CustomEvent("select", {
|
|
67
|
+
bubbles: true,
|
|
68
|
+
composed: true,
|
|
69
|
+
detail: { index: i, label: item.textContent?.trim() ?? "" }
|
|
70
|
+
}));
|
|
71
|
+
});
|
|
72
|
+
item.addEventListener("keydown", (e) => {
|
|
73
|
+
const ev = e;
|
|
74
|
+
if (ev.key === "Enter" || ev.key === " ") {
|
|
75
|
+
ev.preventDefault();
|
|
76
|
+
item.click();
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
connectedCallback() {
|
|
82
|
+
super.connectedCallback();
|
|
83
|
+
document.addEventListener("pointerdown", this._onOutside);
|
|
84
|
+
}
|
|
85
|
+
disconnectedCallback() {
|
|
86
|
+
super.disconnectedCallback();
|
|
87
|
+
document.removeEventListener("pointerdown", this._onOutside);
|
|
88
|
+
}
|
|
89
|
+
_setActive(active) {
|
|
90
|
+
Array.from(this.root.querySelectorAll(".item")).forEach((it) => {
|
|
91
|
+
it.classList.toggle("active", it === active);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
_FxMenu.styles = css`
|
|
96
|
+
:host { display: block; font-family: var(--fx-font-family); font-size: var(--fx-font-size); }
|
|
97
|
+
:host([orientation='vertical']) { border: 1px solid var(--fx-border-default); border-radius: var(--fx-radius-md); }
|
|
98
|
+
nav {
|
|
99
|
+
display: flex;
|
|
100
|
+
align-items: center;
|
|
101
|
+
gap: var(--fx-space-xs);
|
|
102
|
+
flex-wrap: wrap;
|
|
103
|
+
background: var(--fx-surface-background);
|
|
104
|
+
}
|
|
105
|
+
:host([orientation='vertical']) nav { flex-direction: column; align-items: stretch; }
|
|
106
|
+
.item {
|
|
107
|
+
display: inline-flex;
|
|
108
|
+
align-items: center;
|
|
109
|
+
gap: var(--fx-space-xs);
|
|
110
|
+
padding: var(--fx-space-sm) var(--fx-space-md);
|
|
111
|
+
min-height: var(--fx-size-sm);
|
|
112
|
+
border-radius: var(--fx-radius-sm);
|
|
113
|
+
color: var(--fx-text-default);
|
|
114
|
+
cursor: pointer;
|
|
115
|
+
user-select: none;
|
|
116
|
+
white-space: nowrap;
|
|
117
|
+
transition: background var(--fx-motion-duration-fast) var(--fx-motion-easing), color var(--fx-motion-duration-fast) var(--fx-motion-easing);
|
|
118
|
+
}
|
|
119
|
+
:host([size='sm']) .item { min-height: var(--fx-size-sm); padding: var(--fx-space-xs) var(--fx-space-sm); font-size: calc(var(--fx-font-size) - 2px); }
|
|
120
|
+
:host([size='lg']) .item { min-height: var(--fx-size-lg); padding: var(--fx-space-md) var(--fx-space-lg); font-size: calc(var(--fx-font-size) + 1px); }
|
|
121
|
+
.item:hover { background: var(--fx-surface-surface-hover, rgba(0,0,0,0.06)); }
|
|
122
|
+
.item.active { background: var(--fx-color-primary); color: #fff; font-weight: 600; }
|
|
123
|
+
.item[aria-disabled='true'] { opacity: 0.5; cursor: not-allowed; }
|
|
124
|
+
.item[aria-disabled='true']:hover { background: none; }
|
|
125
|
+
.item .caret { font-size: calc(var(--fx-font-size) - 2px); color: var(--fx-text-muted); }
|
|
126
|
+
|
|
127
|
+
/* submenú ancorado ao item */
|
|
128
|
+
.submenu-wrap { position: relative; display: inline-flex; }
|
|
129
|
+
:host([orientation='vertical']) .submenu-wrap { width: 100%; }
|
|
130
|
+
.dropdown {
|
|
131
|
+
position: absolute;
|
|
132
|
+
left: 0;
|
|
133
|
+
top: calc(100% + 4px);
|
|
134
|
+
min-width: 180px;
|
|
135
|
+
background: var(--fx-surface-background);
|
|
136
|
+
border: 1px solid var(--fx-border-default);
|
|
137
|
+
border-radius: var(--fx-radius-sm);
|
|
138
|
+
box-shadow: var(--fx-shadow-lg);
|
|
139
|
+
padding: var(--fx-space-xs);
|
|
140
|
+
z-index: var(--fx-z-dropdown, 1060);
|
|
141
|
+
display: none;
|
|
142
|
+
flex-direction: column;
|
|
143
|
+
}
|
|
144
|
+
.dropdown.open { display: flex; }
|
|
145
|
+
:host([orientation='vertical']) .dropdown { left: 100%; top: 0; }
|
|
146
|
+
`;
|
|
147
|
+
let FxMenu = _FxMenu;
|
|
148
|
+
function defineFxMenu() {
|
|
149
|
+
return defineElement("fx-menu", FxMenu);
|
|
150
|
+
}
|
|
151
|
+
export {
|
|
152
|
+
FxMenu,
|
|
153
|
+
defineFxMenu
|
|
154
|
+
};
|
|
155
|
+
//# sourceMappingURL=menu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menu.js","sources":["../../../src/components/menu/menu.ts"],"sourcesContent":["import { FxElement } from '../../core/base';\nimport { css } from '../../core/css';\nimport { defineElement } from '../../core/define';\nimport { esc } from '../../core/sanitize';\n\n/**\n * <fx-menu> — Menú de navegación (horizontal o vertical) con ítems y submenús.\n *\n * Atributos: orientation (horizontal|vertical), size (sm|md|lg),\n * dense (reduce el alto), titles (separado por `,` para navegación).\n * Slots `item`: cada ítem de menú con [slot=\"item\"].\n * Evento (composed): `select` (detail: { index, label }).\n */\nexport class FxMenu extends FxElement {\n static override styles = css`\n :host { display: block; font-family: var(--fx-font-family); font-size: var(--fx-font-size); }\n :host([orientation='vertical']) { border: 1px solid var(--fx-border-default); border-radius: var(--fx-radius-md); }\n nav {\n display: flex;\n align-items: center;\n gap: var(--fx-space-xs);\n flex-wrap: wrap;\n background: var(--fx-surface-background);\n }\n :host([orientation='vertical']) nav { flex-direction: column; align-items: stretch; }\n .item {\n display: inline-flex;\n align-items: center;\n gap: var(--fx-space-xs);\n padding: var(--fx-space-sm) var(--fx-space-md);\n min-height: var(--fx-size-sm);\n border-radius: var(--fx-radius-sm);\n color: var(--fx-text-default);\n cursor: pointer;\n user-select: none;\n white-space: nowrap;\n transition: background var(--fx-motion-duration-fast) var(--fx-motion-easing), color var(--fx-motion-duration-fast) var(--fx-motion-easing);\n }\n :host([size='sm']) .item { min-height: var(--fx-size-sm); padding: var(--fx-space-xs) var(--fx-space-sm); font-size: calc(var(--fx-font-size) - 2px); }\n :host([size='lg']) .item { min-height: var(--fx-size-lg); padding: var(--fx-space-md) var(--fx-space-lg); font-size: calc(var(--fx-font-size) + 1px); }\n .item:hover { background: var(--fx-surface-surface-hover, rgba(0,0,0,0.06)); }\n .item.active { background: var(--fx-color-primary); color: #fff; font-weight: 600; }\n .item[aria-disabled='true'] { opacity: 0.5; cursor: not-allowed; }\n .item[aria-disabled='true']:hover { background: none; }\n .item .caret { font-size: calc(var(--fx-font-size) - 2px); color: var(--fx-text-muted); }\n\n /* submenú ancorado ao item */\n .submenu-wrap { position: relative; display: inline-flex; }\n :host([orientation='vertical']) .submenu-wrap { width: 100%; }\n .dropdown {\n position: absolute;\n left: 0;\n top: calc(100% + 4px);\n min-width: 180px;\n background: var(--fx-surface-background);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-sm);\n box-shadow: var(--fx-shadow-lg);\n padding: var(--fx-space-xs);\n z-index: var(--fx-z-dropdown, 1060);\n display: none;\n flex-direction: column;\n }\n .dropdown.open { display: flex; }\n :host([orientation='vertical']) .dropdown { left: 100%; top: 0; }\n `;\n\n static override get observedAttributes(): string[] {\n return ['orientation', 'size', 'dense', 'titles'];\n }\n\n get orientation(): string { return this.getAttr('orientation', 'horizontal'); }\n\n get items(): HTMLElement[] {\n return Array.from(this.children).filter((el) => el.matches('[slot=\"item\"]')).map((el) => el as HTMLElement);\n }\n\n protected override render(): void {\n const titleAttr = this.getAttr('titles');\n const titles = titleAttr ? titleAttr.split(',').map((s) => s.trim()) : [];\n\n const items = this.items;\n const itemsHtml = items\n .map((it, i) => {\n const label = titles[i] || it.textContent?.trim() || `Item ${i + 1}`;\n const hasSub = it.matches('[submenu]');\n const disabled = it.hasAttribute('disabled');\n const item = `\n <span class=\"item\" part=\"item\" data-i=\"${i}\" ${disabled ? 'aria-disabled=\"true\"' : ''}>\n ${esc(label)}${hasSub ? `<span class=\"caret\">▾</span>` : ''}\n </span>`;\n if (!hasSub) return item;\n return `\n <span class=\"submenu-wrap\" part=\"submenu-wrap\">\n ${item}\n <div class=\"dropdown\" part=\"submenu\"><slot name=\"submenu-${i}\"></slot></div>\n </span>`;\n })\n .join('');\n\n this.setTemplate(`\n <nav part=\"menu\" aria-label=\"Menu\">\n ${itemsHtml}\n </nav>\n `);\n\n this._bindItems();\n }\n\n private _bindItems(): void {\n const items = Array.from(this.root.querySelectorAll<HTMLElement>('.item'));\n items.forEach((item) => {\n const i = Number(item.dataset.i);\n item.addEventListener('click', () => {\n if (item.getAttribute('aria-disabled') === 'true') return;\n const source = this.items[i];\n const hasSub = source?.hasAttribute('submenu');\n if (hasSub) {\n // fecha outros dropdowns e alterna o deste item\n this.root.querySelectorAll<HTMLElement>('.dropdown.open').forEach((d) => {\n if (d !== item.parentElement?.querySelector('.dropdown')) d.classList.remove('open');\n });\n item.parentElement?.querySelector('.dropdown')?.classList.toggle('open');\n return;\n }\n this._setActive(item);\n this.dispatchEvent(new CustomEvent('select', {\n bubbles: true, composed: true,\n detail: { index: i, label: item.textContent?.trim() ?? '' },\n }));\n });\n item.addEventListener('keydown', (e) => {\n const ev = e as KeyboardEvent;\n if (ev.key === 'Enter' || ev.key === ' ') {\n ev.preventDefault();\n item.click();\n }\n });\n });\n }\n\n protected override connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('pointerdown', this._onOutside);\n }\n\n protected override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('pointerdown', this._onOutside);\n }\n\n private _onOutside = (e: MouseEvent): void => {\n const path = e.composedPath();\n this.root.querySelectorAll<HTMLElement>('.dropdown.open').forEach((d) => {\n if (!path.includes(d)) d.classList.remove('open');\n });\n };\n\n private _setActive(active: HTMLElement): void {\n Array.from(this.root.querySelectorAll<HTMLElement>('.item')).forEach((it) => {\n it.classList.toggle('active', it === active);\n });\n }\n}\n\nexport function defineFxMenu(): typeof FxMenu {\n return defineElement('fx-menu', FxMenu);\n}"],"names":[],"mappings":"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"}
|
|
@@ -49,7 +49,7 @@ export declare class FxOrderList extends FxElement {
|
|
|
49
49
|
private _optionTemplate;
|
|
50
50
|
setOptionTemplate(template: (item: OrderListItem) => string): void;
|
|
51
51
|
protected connectedCallback(): void;
|
|
52
|
-
protected attributeChangedCallback(): void;
|
|
52
|
+
protected attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
53
53
|
private _parseDataAttribute;
|
|
54
54
|
private _applyFilter;
|
|
55
55
|
private _getDisplayData;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orderlist.d.ts","sourceRoot":"","sources":["../../../src/components/orderlist/orderlist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAK5C,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,WAAY,SAAQ,SAAS;IACxC,OAAgB,MAAM,SA2ElB;IAEJ,WAAoB,kBAAkB,IAAI,MAAM,EAAE,CAc7C;IAEL,IAAI,IAAI,CAAC,KAAK,EAAE,aAAa,EAAE,EAI9B;IACD,IAAI,IAAI,IAAI,aAAa,EAAE,CAE1B;IACD,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,aAAa,CAAgC;IAErD,IAAI,SAAS,CAAC,KAAK,EAAE,aAAa,EAAE,EAGnC;IACD,IAAI,SAAS,IAAI,aAAa,EAAE,CAE/B;IACC,OAAO,CAAC,UAAU,CAAuB;IAE3C,IAAI,OAAO,IAAI,MAAM,CAEpB;IACD,IAAI,OAAO,CAAC,CAAC,EAAE,MAAM,EAEpB;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IACC,IAAI,MAAM,CAAC,CAAC,EAAE,OAAO,EAEtB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IACD,IAAI,QAAQ,CAAC,CAAC,EAAE,MAAM,EAErB;IAED,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IACD,IAAI,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAE9B;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IACD,IAAI,UAAU,CAAC,CAAC,EAAE,MAAM,EAEvB;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IACD,IAAI,QAAQ,CAAC,CAAC,EAAE,OAAO,EAEtB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IACC,IAAI,OAAO,CAAC,CAAC,EAAE,OAAO,EAEvB;IAED,IAAI,aAAa,IAAI,MAAM,CAG1B;IACD,IAAI,aAAa,CAAC,CAAC,EAAE,MAAM,EAE1B;IAED,IAAI,aAAa,IAAI,OAAO,CAE3B;IACC,IAAI,aAAa,CAAC,CAAC,EAAE,OAAO,EAE7B;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IACD,IAAI,WAAW,CAAC,CAAC,EAAE,MAAM,EAIxB;IACD,OAAO,CAAC,YAAY,CAAM;IAE1B,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,eAAe,CAAkD;IAEzE,iBAAiB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,MAAM,GAAG,IAAI;cAK/C,iBAAiB,IAAI,IAAI;cAKzB,wBAAwB,IAAI,IAAI;
|
|
1
|
+
{"version":3,"file":"orderlist.d.ts","sourceRoot":"","sources":["../../../src/components/orderlist/orderlist.ts"],"names":[],"mappings":"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"}
|
|
@@ -114,11 +114,11 @@ const _FxOrderList = class _FxOrderList extends FxElement {
|
|
|
114
114
|
this._parseDataAttribute();
|
|
115
115
|
super.connectedCallback();
|
|
116
116
|
}
|
|
117
|
-
attributeChangedCallback() {
|
|
117
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
118
118
|
if (this.getAttr("data", "") !== "") {
|
|
119
119
|
this._parseDataAttribute();
|
|
120
120
|
}
|
|
121
|
-
super.attributeChangedCallback();
|
|
121
|
+
super.attributeChangedCallback(name, oldValue, newValue);
|
|
122
122
|
}
|
|
123
123
|
_parseDataAttribute() {
|
|
124
124
|
const dataAttr = this.getAttr("data", "");
|