@liwe3/webcomponents 1.1.0 → 1.1.10
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/dist/AIMarkdownEditor.d.ts +35 -0
- package/dist/AIMarkdownEditor.d.ts.map +1 -0
- package/dist/AIMarkdownEditor.js +412 -0
- package/dist/AIMarkdownEditor.js.map +1 -0
- package/dist/AITextEditor.d.ts +10 -0
- package/dist/AITextEditor.d.ts.map +1 -1
- package/dist/AITextEditor.js +63 -27
- package/dist/AITextEditor.js.map +1 -1
- package/dist/ButtonToolbar.d.ts +35 -0
- package/dist/ButtonToolbar.d.ts.map +1 -0
- package/dist/ButtonToolbar.js +220 -0
- package/dist/ButtonToolbar.js.map +1 -0
- package/dist/CheckList.d.ts +31 -0
- package/dist/CheckList.d.ts.map +1 -0
- package/dist/CheckList.js +336 -0
- package/dist/CheckList.js.map +1 -0
- package/dist/ChunkUploader.d.ts +22 -0
- package/dist/ChunkUploader.d.ts.map +1 -1
- package/dist/ChunkUploader.js +245 -103
- package/dist/ChunkUploader.js.map +1 -1
- package/dist/ComicBalloon.d.ts +82 -0
- package/dist/ComicBalloon.d.ts.map +1 -0
- package/dist/ComicBalloon.js +346 -0
- package/dist/ComicBalloon.js.map +1 -0
- package/dist/Dialog.d.ts +102 -0
- package/dist/Dialog.d.ts.map +1 -0
- package/dist/Dialog.js +299 -0
- package/dist/Dialog.js.map +1 -0
- package/dist/MarkdownPreview.d.ts +25 -0
- package/dist/MarkdownPreview.d.ts.map +1 -0
- package/dist/MarkdownPreview.js +147 -0
- package/dist/MarkdownPreview.js.map +1 -0
- package/dist/ResizableCropper.d.ts +158 -0
- package/dist/ResizableCropper.d.ts.map +1 -0
- package/dist/ResizableCropper.js +562 -0
- package/dist/ResizableCropper.js.map +1 -0
- package/dist/SmartSelect.d.ts +1 -0
- package/dist/SmartSelect.d.ts.map +1 -1
- package/dist/SmartSelect.js +45 -2
- package/dist/SmartSelect.js.map +1 -1
- package/dist/index.d.ts +16 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +52 -29
- package/dist/index.js.map +1 -1
- package/package.json +33 -3
- package/src/AIMarkdownEditor.ts +568 -0
- package/src/AITextEditor.ts +97 -2
- package/src/ButtonToolbar.ts +302 -0
- package/src/CheckList.ts +438 -0
- package/src/ChunkUploader.ts +837 -623
- package/src/ComicBalloon.ts +709 -0
- package/src/Dialog.ts +510 -0
- package/src/MarkdownPreview.ts +213 -0
- package/src/ResizableCropper.ts +1099 -0
- package/src/SmartSelect.ts +48 -2
- package/src/index.ts +110 -47
package/dist/ChunkUploader.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class k extends HTMLElement {
|
|
2
2
|
constructor() {
|
|
3
3
|
super(), this.files = /* @__PURE__ */ new Map(), this.config = {
|
|
4
4
|
serverURL: "",
|
|
@@ -7,10 +7,10 @@ class v extends HTMLElement {
|
|
|
7
7
|
}, this.isUploading = !1, this.abortController = null, this.attachShadow({ mode: "open" }), this.render(), this.bindEvents();
|
|
8
8
|
}
|
|
9
9
|
static get observedAttributes() {
|
|
10
|
-
return ["server-url", "chunk-size", "auth-token", "valid-filetypes", "max-file-size"];
|
|
10
|
+
return ["server-url", "chunk-size", "auth-token", "valid-filetypes", "max-file-size", "label-drop-files", "label-browse", "folder", "compact"];
|
|
11
11
|
}
|
|
12
|
-
attributeChangedCallback(e,
|
|
13
|
-
if (
|
|
12
|
+
attributeChangedCallback(e, i, o) {
|
|
13
|
+
if (i !== o)
|
|
14
14
|
switch (e) {
|
|
15
15
|
case "server-url":
|
|
16
16
|
this.config.serverURL = o || "";
|
|
@@ -27,6 +27,18 @@ class v extends HTMLElement {
|
|
|
27
27
|
case "max-file-size":
|
|
28
28
|
this.config.maxFileSize = parseFloat(o || String(5120));
|
|
29
29
|
break;
|
|
30
|
+
case "label-drop-files":
|
|
31
|
+
this.config.labelDropFiles = o || void 0, this.updateLabels();
|
|
32
|
+
break;
|
|
33
|
+
case "label-browse":
|
|
34
|
+
this.config.labelBrowse = o || void 0, this.updateLabels();
|
|
35
|
+
break;
|
|
36
|
+
case "folder":
|
|
37
|
+
this.config.folder = o || void 0;
|
|
38
|
+
break;
|
|
39
|
+
case "compact":
|
|
40
|
+
this.config.compact = o !== null, this.updateCompactMode();
|
|
41
|
+
break;
|
|
30
42
|
}
|
|
31
43
|
}
|
|
32
44
|
// Property getters and setters
|
|
@@ -60,19 +72,60 @@ class v extends HTMLElement {
|
|
|
60
72
|
set maxFileSize(e) {
|
|
61
73
|
this.config.maxFileSize = e, this.setAttribute("max-file-size", e.toString());
|
|
62
74
|
}
|
|
75
|
+
get labelDropFiles() {
|
|
76
|
+
return this.config.labelDropFiles;
|
|
77
|
+
}
|
|
78
|
+
set labelDropFiles(e) {
|
|
79
|
+
this.config.labelDropFiles = e, e ? this.setAttribute("label-drop-files", e) : this.removeAttribute("label-drop-files"), this.updateLabels();
|
|
80
|
+
}
|
|
81
|
+
get labelBrowse() {
|
|
82
|
+
return this.config.labelBrowse;
|
|
83
|
+
}
|
|
84
|
+
set labelBrowse(e) {
|
|
85
|
+
this.config.labelBrowse = e, e ? this.setAttribute("label-browse", e) : this.removeAttribute("label-browse"), this.updateLabels();
|
|
86
|
+
}
|
|
87
|
+
get folder() {
|
|
88
|
+
return this.config.folder;
|
|
89
|
+
}
|
|
90
|
+
set folder(e) {
|
|
91
|
+
this.config.folder = e, e ? this.setAttribute("folder", e) : this.removeAttribute("folder");
|
|
92
|
+
}
|
|
93
|
+
get compact() {
|
|
94
|
+
return !!this.config.compact;
|
|
95
|
+
}
|
|
96
|
+
set compact(e) {
|
|
97
|
+
this.config.compact = e, e ? this.setAttribute("compact", "") : this.removeAttribute("compact"), this.updateCompactMode();
|
|
98
|
+
}
|
|
63
99
|
set onfilecomplete(e) {
|
|
64
100
|
this.config.onfilecomplete = e;
|
|
65
101
|
}
|
|
66
102
|
set onuploadcomplete(e) {
|
|
67
103
|
this.config.onuploadcomplete = e;
|
|
68
104
|
}
|
|
105
|
+
set parseResponse(e) {
|
|
106
|
+
this.config.parseResponse = e;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Updates labels in the DOM when properties change
|
|
110
|
+
*/
|
|
111
|
+
updateLabels() {
|
|
112
|
+
const e = this.shadowRoot.querySelector(".upload-text"), i = this.shadowRoot.querySelector("#browseBtn");
|
|
113
|
+
e && (e.textContent = this.config.labelDropFiles || "Drop files here"), i && (i.textContent = this.config.labelBrowse || "Browse Files");
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Updates compact mode styles and attributes
|
|
117
|
+
*/
|
|
118
|
+
updateCompactMode() {
|
|
119
|
+
const e = this.shadowRoot.querySelector(".container"), i = this.shadowRoot.querySelector("#fileInput");
|
|
120
|
+
this.config.compact ? (e?.classList.add("compact"), i?.removeAttribute("multiple")) : (e?.classList.remove("compact"), i?.setAttribute("multiple", ""));
|
|
121
|
+
}
|
|
69
122
|
/**
|
|
70
123
|
* Formats bytes to human readable string
|
|
71
124
|
*/
|
|
72
125
|
formatBytes(e) {
|
|
73
126
|
if (e === 0) return "0 Bytes";
|
|
74
|
-
const
|
|
75
|
-
return Math.round(e / Math.pow(
|
|
127
|
+
const i = 1024, o = ["Bytes", "KB", "MB", "GB"], t = Math.floor(Math.log(e) / Math.log(i));
|
|
128
|
+
return Math.round(e / Math.pow(i, t) * 100) / 100 + " " + o[t];
|
|
76
129
|
}
|
|
77
130
|
/**
|
|
78
131
|
* Generates a unique ID for a file
|
|
@@ -84,11 +137,11 @@ class v extends HTMLElement {
|
|
|
84
137
|
* Validates a file based on config
|
|
85
138
|
*/
|
|
86
139
|
validateFile(e) {
|
|
87
|
-
const
|
|
88
|
-
if (e.size >
|
|
140
|
+
const i = this.maxFileSize * 1024 * 1024;
|
|
141
|
+
if (e.size > i)
|
|
89
142
|
return {
|
|
90
143
|
valid: !1,
|
|
91
|
-
error: `File size exceeds maximum of ${this.formatBytes(
|
|
144
|
+
error: `File size exceeds maximum of ${this.formatBytes(i)}`
|
|
92
145
|
};
|
|
93
146
|
if (this.config.validFiletypes && this.config.validFiletypes.length > 0) {
|
|
94
147
|
const o = e.name.split(".").pop()?.toLowerCase();
|
|
@@ -105,25 +158,28 @@ class v extends HTMLElement {
|
|
|
105
158
|
*/
|
|
106
159
|
async generatePreview(e) {
|
|
107
160
|
if (e.type.startsWith("image/"))
|
|
108
|
-
return new Promise((
|
|
161
|
+
return new Promise((i) => {
|
|
109
162
|
const o = new FileReader();
|
|
110
|
-
o.onload = (t) =>
|
|
163
|
+
o.onload = (t) => i(t.target?.result), o.onerror = () => i(void 0), o.readAsDataURL(e);
|
|
111
164
|
});
|
|
112
165
|
}
|
|
113
166
|
/**
|
|
114
167
|
* Adds files to the upload queue
|
|
115
168
|
*/
|
|
116
169
|
async addFiles(e) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
170
|
+
this.config.compact && this.files.clear();
|
|
171
|
+
const i = Array.from(e), o = this.config.compact ? [i[0]] : i;
|
|
172
|
+
for (const t of o) {
|
|
173
|
+
if (!t) continue;
|
|
174
|
+
const r = this.validateFile(t), s = this.generateFileId(), a = {
|
|
175
|
+
id: s,
|
|
176
|
+
file: t,
|
|
177
|
+
status: r.valid ? "pending" : "error",
|
|
122
178
|
progress: 0,
|
|
123
179
|
uploadedBytes: 0,
|
|
124
|
-
error:
|
|
180
|
+
error: r.error
|
|
125
181
|
};
|
|
126
|
-
|
|
182
|
+
r.valid && t.type.startsWith("image/") && (a.preview = await this.generatePreview(t)), this.files.set(s, a);
|
|
127
183
|
}
|
|
128
184
|
this.renderFileCards();
|
|
129
185
|
}
|
|
@@ -139,64 +195,78 @@ class v extends HTMLElement {
|
|
|
139
195
|
async uploadFile(e) {
|
|
140
196
|
if (!this.config.serverURL)
|
|
141
197
|
throw new Error("Server URL is not configured");
|
|
142
|
-
const { file:
|
|
198
|
+
const i = this.config.serverURL.replace(/\/$/, ""), { file: o } = e;
|
|
143
199
|
e.status = "uploading", e.progress = 0, this.updateFileCard(e.id);
|
|
144
200
|
try {
|
|
145
|
-
const
|
|
201
|
+
const t = {
|
|
146
202
|
"Content-Type": "application/json"
|
|
147
203
|
};
|
|
148
|
-
this.config.authToken && (
|
|
149
|
-
const
|
|
204
|
+
this.config.authToken && (t.Authorization = `Bearer ${this.config.authToken}`);
|
|
205
|
+
const r = await fetch(`${i}/api/upload/initiate`, {
|
|
150
206
|
method: "POST",
|
|
151
|
-
|
|
207
|
+
mode: "cors",
|
|
208
|
+
headers: t,
|
|
152
209
|
body: JSON.stringify({
|
|
153
|
-
fileName:
|
|
154
|
-
fileType:
|
|
155
|
-
|
|
210
|
+
fileName: o.name,
|
|
211
|
+
fileType: o.type,
|
|
212
|
+
folder: this.config.folder
|
|
213
|
+
}),
|
|
214
|
+
signal: this.abortController?.signal
|
|
156
215
|
});
|
|
157
|
-
if (!
|
|
158
|
-
throw new Error(`Failed to initiate upload: ${await
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const
|
|
162
|
-
|
|
216
|
+
if (!r.ok)
|
|
217
|
+
throw new Error(`Failed to initiate upload: ${await r.text()}`);
|
|
218
|
+
let s = await r.json();
|
|
219
|
+
this.config.parseResponse && (s = this.config.parseResponse(s, "initiate"));
|
|
220
|
+
const { uploadId: a, key: d } = s;
|
|
221
|
+
e.uploadId = a, e.key = d;
|
|
222
|
+
const c = this.config.chunkSize * 1024 * 1024, y = Math.ceil(o.size / c), f = [];
|
|
223
|
+
for (let n = 1; n <= y; n++) {
|
|
163
224
|
if (this.abortController?.signal.aborted)
|
|
164
225
|
throw new Error("Upload aborted by user");
|
|
165
|
-
const
|
|
226
|
+
const g = (n - 1) * c, b = Math.min(g + c, o.size), x = o.slice(g, b), m = {
|
|
166
227
|
"Content-Type": "application/octet-stream",
|
|
167
|
-
"X-Upload-Id":
|
|
168
|
-
"X-Key":
|
|
169
|
-
"X-Part-Number":
|
|
228
|
+
"X-Upload-Id": a,
|
|
229
|
+
"X-Key": d,
|
|
230
|
+
"X-Part-Number": n.toString()
|
|
170
231
|
};
|
|
171
|
-
this.config.authToken && (
|
|
172
|
-
const
|
|
232
|
+
this.config.authToken && (m.Authorization = `Bearer ${this.config.authToken}`);
|
|
233
|
+
const v = await fetch(`${i}/api/upload/part`, {
|
|
173
234
|
method: "POST",
|
|
174
|
-
|
|
175
|
-
|
|
235
|
+
mode: "cors",
|
|
236
|
+
headers: m,
|
|
237
|
+
body: x,
|
|
176
238
|
signal: this.abortController?.signal
|
|
177
239
|
});
|
|
178
|
-
if (!
|
|
179
|
-
throw new Error(`Failed to upload part ${
|
|
180
|
-
|
|
181
|
-
|
|
240
|
+
if (!v.ok)
|
|
241
|
+
throw new Error(`Failed to upload part ${n}`);
|
|
242
|
+
let p = await v.json();
|
|
243
|
+
this.config.parseResponse && (p = this.config.parseResponse(p, "part"));
|
|
244
|
+
const { etag: w } = p;
|
|
245
|
+
f.push({ partNumber: n, etag: w }), e.uploadedBytes = b, e.progress = e.uploadedBytes / o.size * 100, this.updateFileCard(e.id);
|
|
182
246
|
}
|
|
183
|
-
|
|
247
|
+
const h = await fetch(`${i}/api/upload/complete`, {
|
|
184
248
|
method: "POST",
|
|
185
|
-
|
|
249
|
+
mode: "cors",
|
|
250
|
+
headers: t,
|
|
186
251
|
body: JSON.stringify({
|
|
187
|
-
uploadId:
|
|
188
|
-
key:
|
|
189
|
-
parts:
|
|
190
|
-
})
|
|
191
|
-
|
|
252
|
+
uploadId: a,
|
|
253
|
+
key: d,
|
|
254
|
+
parts: f
|
|
255
|
+
}),
|
|
256
|
+
signal: this.abortController?.signal
|
|
257
|
+
});
|
|
258
|
+
if (!h.ok)
|
|
192
259
|
throw new Error("Failed to complete upload");
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
260
|
+
let u = await h.json();
|
|
261
|
+
this.config.parseResponse && (u = this.config.parseResponse(u, "complete")), e.status = "completed", e.progress = 100, this.updateFileCard(e.id), this.dispatchEvent(
|
|
262
|
+
new CustomEvent("filecomplete", {
|
|
263
|
+
detail: e,
|
|
264
|
+
bubbles: !0,
|
|
265
|
+
composed: !0
|
|
266
|
+
})
|
|
267
|
+
), this.config.onfilecomplete && this.config.onfilecomplete(e);
|
|
268
|
+
} catch (t) {
|
|
269
|
+
throw t instanceof Error && (t.name === "AbortError" || t.message === "Upload aborted by user") || (e.status = "error", e.error = t instanceof Error ? t.message : "Unknown error", this.updateFileCard(e.id)), t;
|
|
200
270
|
}
|
|
201
271
|
}
|
|
202
272
|
/**
|
|
@@ -207,23 +277,25 @@ class v extends HTMLElement {
|
|
|
207
277
|
const e = Array.from(this.files.values()).filter((t) => t.status === "pending");
|
|
208
278
|
if (e.length === 0) return;
|
|
209
279
|
this.isUploading = !0, this.abortController = new AbortController();
|
|
210
|
-
const
|
|
211
|
-
|
|
280
|
+
const i = this.shadowRoot.querySelector("#uploadBtn"), o = this.shadowRoot.querySelector("#abortBtn");
|
|
281
|
+
i && (i.disabled = !0, i.textContent = "Uploading..."), o && (o.style.display = "inline-block");
|
|
212
282
|
try {
|
|
213
283
|
for (const t of e) {
|
|
214
284
|
if (this.abortController.signal.aborted)
|
|
215
285
|
break;
|
|
216
286
|
await this.uploadFile(t);
|
|
217
287
|
}
|
|
218
|
-
this.dispatchEvent(
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
288
|
+
this.dispatchEvent(
|
|
289
|
+
new CustomEvent("uploadcomplete", {
|
|
290
|
+
detail: Array.from(this.files.values()),
|
|
291
|
+
bubbles: !0,
|
|
292
|
+
composed: !0
|
|
293
|
+
})
|
|
294
|
+
), this.config.onuploadcomplete && this.config.onuploadcomplete(Array.from(this.files.values()));
|
|
223
295
|
} catch (t) {
|
|
224
296
|
t instanceof Error && t.message !== "Upload aborted by user" && console.error("Upload error:", t);
|
|
225
297
|
} finally {
|
|
226
|
-
this.isUploading = !1,
|
|
298
|
+
this.isUploading = !1, i && (i.disabled = !1, i.textContent = "Upload Files"), o && (o.style.display = "none");
|
|
227
299
|
}
|
|
228
300
|
}
|
|
229
301
|
/**
|
|
@@ -232,34 +304,38 @@ class v extends HTMLElement {
|
|
|
232
304
|
async abortAllUploads() {
|
|
233
305
|
this.abortController && this.abortController.abort();
|
|
234
306
|
const e = Array.from(this.files.values()).filter(
|
|
235
|
-
(
|
|
307
|
+
(r) => r.status === "pending" || r.status === "uploading"
|
|
236
308
|
);
|
|
237
309
|
if (e.length === 0) return;
|
|
238
|
-
const
|
|
310
|
+
const i = {
|
|
239
311
|
"Content-Type": "application/json"
|
|
240
312
|
};
|
|
241
|
-
this.config.authToken && (
|
|
242
|
-
for (const
|
|
243
|
-
if (
|
|
313
|
+
this.config.authToken && (i.Authorization = `Bearer ${this.config.authToken}`);
|
|
314
|
+
for (const r of e) {
|
|
315
|
+
if (r.uploadId && r.key)
|
|
244
316
|
try {
|
|
245
|
-
|
|
317
|
+
const s = this.config.serverURL.replace(/\/$/, "");
|
|
318
|
+
await fetch(`${s}/api/upload/abort`, {
|
|
246
319
|
method: "POST",
|
|
247
|
-
|
|
320
|
+
mode: "cors",
|
|
321
|
+
headers: i,
|
|
248
322
|
body: JSON.stringify({
|
|
249
|
-
uploadId:
|
|
250
|
-
key:
|
|
323
|
+
uploadId: r.uploadId,
|
|
324
|
+
key: r.key
|
|
251
325
|
})
|
|
252
326
|
});
|
|
253
327
|
} catch (s) {
|
|
254
|
-
console.error(`Failed to abort upload for ${
|
|
328
|
+
console.error(`Failed to abort upload for ${r.file.name}:`, s);
|
|
255
329
|
}
|
|
256
|
-
|
|
330
|
+
r.status = "aborted", r.error = "Upload aborted by user", this.updateFileCard(r.id);
|
|
257
331
|
}
|
|
258
|
-
this.dispatchEvent(
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
332
|
+
this.dispatchEvent(
|
|
333
|
+
new CustomEvent("uploadaborted", {
|
|
334
|
+
detail: e,
|
|
335
|
+
bubbles: !0,
|
|
336
|
+
composed: !0
|
|
337
|
+
})
|
|
338
|
+
), this.isUploading = !1;
|
|
263
339
|
const o = this.shadowRoot.querySelector("#uploadBtn"), t = this.shadowRoot.querySelector("#abortBtn");
|
|
264
340
|
o && (o.disabled = !1, o.textContent = "Upload Files"), t && (t.style.display = "none");
|
|
265
341
|
}
|
|
@@ -267,12 +343,12 @@ class v extends HTMLElement {
|
|
|
267
343
|
* Updates a single file card in the DOM
|
|
268
344
|
*/
|
|
269
345
|
updateFileCard(e) {
|
|
270
|
-
const
|
|
271
|
-
if (!
|
|
346
|
+
const i = this.files.get(e);
|
|
347
|
+
if (!i) return;
|
|
272
348
|
const o = this.shadowRoot.querySelector(`[data-file-id="${e}"]`);
|
|
273
349
|
if (!o) return;
|
|
274
|
-
const t = o.querySelector(".progress-bar"),
|
|
275
|
-
t && (t.style.width = `${
|
|
350
|
+
const t = o.querySelector(".progress-bar"), r = o.querySelector(".progress-text"), s = o.querySelector(".status");
|
|
351
|
+
t && (t.style.width = `${i.progress}%`, i.status === "completed" ? t.style.backgroundColor = "#22c55e" : i.status === "error" ? t.style.backgroundColor = "#ef4444" : i.status === "aborted" ? t.style.backgroundColor = "#f59e0b" : t.style.backgroundColor = "var(--color-primary)"), r && (r.textContent = `${Math.round(i.progress)}%`), s && i.error && (s.textContent = i.error, s.style.display = "block");
|
|
276
352
|
}
|
|
277
353
|
/**
|
|
278
354
|
* Renders all file cards
|
|
@@ -301,15 +377,15 @@ class v extends HTMLElement {
|
|
|
301
377
|
${t.error ? `<div class="status error">${t.error}</div>` : ""}
|
|
302
378
|
</div>
|
|
303
379
|
`).join(""), e.querySelectorAll(".remove-btn").forEach((t) => {
|
|
304
|
-
t.addEventListener("click", (
|
|
305
|
-
|
|
380
|
+
t.addEventListener("click", (r) => {
|
|
381
|
+
r.stopPropagation();
|
|
306
382
|
const s = t.dataset.fileId;
|
|
307
383
|
s && this.removeFile(s);
|
|
308
384
|
});
|
|
309
385
|
});
|
|
310
386
|
const o = this.shadowRoot.querySelector("#uploadBtn");
|
|
311
387
|
if (o) {
|
|
312
|
-
const t = Array.from(this.files.values()).some((
|
|
388
|
+
const t = Array.from(this.files.values()).some((r) => r.status === "pending");
|
|
313
389
|
o.style.display = t ? "block" : "none";
|
|
314
390
|
}
|
|
315
391
|
}
|
|
@@ -317,17 +393,17 @@ class v extends HTMLElement {
|
|
|
317
393
|
* Binds event listeners
|
|
318
394
|
*/
|
|
319
395
|
bindEvents() {
|
|
320
|
-
const e = this.shadowRoot.querySelector("#uploadZone"),
|
|
321
|
-
o?.addEventListener("click", () =>
|
|
396
|
+
const e = this.shadowRoot.querySelector("#uploadZone"), i = this.shadowRoot.querySelector("#fileInput"), o = this.shadowRoot.querySelector("#browseBtn"), t = this.shadowRoot.querySelector("#uploadBtn"), r = this.shadowRoot.querySelector("#abortBtn");
|
|
397
|
+
o?.addEventListener("click", () => i?.click()), e?.addEventListener("dragover", (s) => {
|
|
322
398
|
s.preventDefault(), e.classList.add("drag-over");
|
|
323
399
|
}), e?.addEventListener("dragleave", () => {
|
|
324
400
|
e.classList.remove("drag-over");
|
|
325
401
|
}), e?.addEventListener("drop", (s) => {
|
|
326
402
|
s.preventDefault(), e.classList.remove("drag-over"), s.dataTransfer?.files && this.addFiles(s.dataTransfer.files);
|
|
327
|
-
}),
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
}), t?.addEventListener("click", () => this.startUpload()),
|
|
403
|
+
}), i?.addEventListener("change", (s) => {
|
|
404
|
+
const a = s.target.files;
|
|
405
|
+
a && (this.addFiles(a), i.value = "");
|
|
406
|
+
}), t?.addEventListener("click", () => this.startUpload()), r?.addEventListener("click", () => this.abortAllUploads());
|
|
331
407
|
}
|
|
332
408
|
/**
|
|
333
409
|
* Renders the component
|
|
@@ -351,7 +427,7 @@ class v extends HTMLElement {
|
|
|
351
427
|
.upload-zone {
|
|
352
428
|
border: 2px dashed #ccc;
|
|
353
429
|
border-radius: 8px;
|
|
354
|
-
padding:
|
|
430
|
+
padding: 10px;
|
|
355
431
|
text-align: center;
|
|
356
432
|
cursor: pointer;
|
|
357
433
|
transition: all 0.3s ease;
|
|
@@ -580,6 +656,72 @@ class v extends HTMLElement {
|
|
|
580
656
|
display: flex;
|
|
581
657
|
align-items: center;
|
|
582
658
|
}
|
|
659
|
+
|
|
660
|
+
/* Compact Mode Styles */
|
|
661
|
+
.container.compact .upload-zone {
|
|
662
|
+
padding: 8px;
|
|
663
|
+
display: flex;
|
|
664
|
+
align-items: center;
|
|
665
|
+
justify-content: center;
|
|
666
|
+
gap: 8px;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
.container.compact .upload-icon,
|
|
670
|
+
.container.compact .upload-hint {
|
|
671
|
+
display: none;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
.container.compact .upload-text {
|
|
675
|
+
font-size: 14px;
|
|
676
|
+
margin-bottom: 0;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
.container.compact .browse-btn {
|
|
680
|
+
margin-top: 0;
|
|
681
|
+
padding: 6px 12px;
|
|
682
|
+
font-size: 14px;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
.container.compact .file-cards-container {
|
|
686
|
+
margin-top: 12px;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
.container.compact .file-card {
|
|
690
|
+
width: 100%;
|
|
691
|
+
display: flex;
|
|
692
|
+
align-items: center;
|
|
693
|
+
padding: 8px;
|
|
694
|
+
height: auto;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
.container.compact .preview {
|
|
698
|
+
display: none !important;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
.container.compact .file-info {
|
|
702
|
+
margin-bottom: 0;
|
|
703
|
+
display: flex;
|
|
704
|
+
align-items: center;
|
|
705
|
+
gap: 12px;
|
|
706
|
+
flex: 0 0 auto;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
.container.compact .file-name {
|
|
710
|
+
margin-bottom: 0;
|
|
711
|
+
max-width: 150px;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
.container.compact .progress-container {
|
|
715
|
+
margin-top: 0;
|
|
716
|
+
flex: 1;
|
|
717
|
+
margin-left: 12px;
|
|
718
|
+
margin-right: 32px;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
.container.compact .remove-btn {
|
|
722
|
+
top: 50%;
|
|
723
|
+
transform: translateY(-50%);
|
|
724
|
+
}
|
|
583
725
|
</style>
|
|
584
726
|
|
|
585
727
|
<div class="container">
|
|
@@ -587,9 +729,9 @@ class v extends HTMLElement {
|
|
|
587
729
|
<input type="file" id="fileInput" multiple>
|
|
588
730
|
<div class="upload-zone-content">
|
|
589
731
|
<div class="upload-icon">📁</div>
|
|
590
|
-
<div class="upload-text"
|
|
732
|
+
<div class="upload-text">${this.config.labelDropFiles || "Drop files here"}</div>
|
|
591
733
|
<div class="upload-hint">or</div>
|
|
592
|
-
<button class="browse-btn" id="browseBtn"
|
|
734
|
+
<button class="browse-btn" id="browseBtn">${this.config.labelBrowse || "Browse Files"}</button>
|
|
593
735
|
</div>
|
|
594
736
|
</div>
|
|
595
737
|
|
|
@@ -603,12 +745,12 @@ class v extends HTMLElement {
|
|
|
603
745
|
`;
|
|
604
746
|
}
|
|
605
747
|
}
|
|
606
|
-
const
|
|
607
|
-
typeof window < "u" && !customElements.get(l) && customElements.define(l,
|
|
748
|
+
const S = (l = "liwe3-chunk-uploader") => {
|
|
749
|
+
typeof window < "u" && !customElements.get(l) && customElements.define(l, k);
|
|
608
750
|
};
|
|
609
|
-
typeof window < "u" &&
|
|
751
|
+
typeof window < "u" && S();
|
|
610
752
|
export {
|
|
611
|
-
|
|
612
|
-
|
|
753
|
+
k as ChunkUploaderElement,
|
|
754
|
+
S as defineChunkUploader
|
|
613
755
|
};
|
|
614
756
|
//# sourceMappingURL=ChunkUploader.js.map
|