haiku-react-ui 1.0.0 → 1.0.1

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/index.js CHANGED
@@ -1,15 +1,1404 @@
1
1
  import { cva } from 'class-variance-authority';
2
2
  import { clsx } from 'clsx';
3
3
  import { twMerge } from 'tailwind-merge';
4
- import { Icon } from '@iconify/react';
5
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
6
4
  import * as React2 from 'react';
7
- import { useState, useId, useRef, useCallback, useEffect } from 'react';
5
+ import { forwardRef, useState, useEffect, createElement, useId, useRef, useCallback } from 'react';
6
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
8
7
 
9
8
  // src/components/Button/button.tsx
10
9
  function cn(...inputs) {
11
10
  return twMerge(clsx(inputs));
12
11
  }
12
+ function getIconsTree(data, names) {
13
+ const icons = data.icons;
14
+ const aliases = data.aliases || /* @__PURE__ */ Object.create(null);
15
+ const resolved = /* @__PURE__ */ Object.create(null);
16
+ function resolve(name) {
17
+ if (icons[name]) return resolved[name] = [];
18
+ if (!(name in resolved)) {
19
+ resolved[name] = null;
20
+ const parent = aliases[name] && aliases[name].parent;
21
+ const value = parent && resolve(parent);
22
+ if (value) resolved[name] = [parent].concat(value);
23
+ }
24
+ return resolved[name];
25
+ }
26
+ Object.keys(icons).concat(Object.keys(aliases)).forEach(resolve);
27
+ return resolved;
28
+ }
29
+ var defaultIconDimensions = Object.freeze({
30
+ left: 0,
31
+ top: 0,
32
+ width: 16,
33
+ height: 16
34
+ });
35
+ var defaultIconTransformations = Object.freeze({
36
+ rotate: 0,
37
+ vFlip: false,
38
+ hFlip: false
39
+ });
40
+ var defaultIconProps = Object.freeze({
41
+ ...defaultIconDimensions,
42
+ ...defaultIconTransformations
43
+ });
44
+ var defaultExtendedIconProps = Object.freeze({
45
+ ...defaultIconProps,
46
+ body: "",
47
+ hidden: false
48
+ });
49
+ function mergeIconTransformations(obj1, obj2) {
50
+ const result = {};
51
+ if (!obj1.hFlip !== !obj2.hFlip) result.hFlip = true;
52
+ if (!obj1.vFlip !== !obj2.vFlip) result.vFlip = true;
53
+ const rotate = ((obj1.rotate || 0) + (obj2.rotate || 0)) % 4;
54
+ if (rotate) result.rotate = rotate;
55
+ return result;
56
+ }
57
+ function mergeIconData(parent, child) {
58
+ const result = mergeIconTransformations(parent, child);
59
+ for (const key in defaultExtendedIconProps) if (key in defaultIconTransformations) {
60
+ if (key in parent && !(key in result)) result[key] = defaultIconTransformations[key];
61
+ } else if (key in child) result[key] = child[key];
62
+ else if (key in parent) result[key] = parent[key];
63
+ return result;
64
+ }
65
+ function internalGetIconData(data, name, tree) {
66
+ const icons = data.icons;
67
+ const aliases = data.aliases || /* @__PURE__ */ Object.create(null);
68
+ let currentProps = {};
69
+ function parse(name$1) {
70
+ currentProps = mergeIconData(icons[name$1] || aliases[name$1], currentProps);
71
+ }
72
+ parse(name);
73
+ tree.forEach(parse);
74
+ return mergeIconData(data, currentProps);
75
+ }
76
+ function parseIconSet(data, callback) {
77
+ const names = [];
78
+ if (typeof data !== "object" || typeof data.icons !== "object") return names;
79
+ if (data.not_found instanceof Array) data.not_found.forEach((name) => {
80
+ callback(name, null);
81
+ names.push(name);
82
+ });
83
+ const tree = getIconsTree(data);
84
+ for (const name in tree) {
85
+ const item = tree[name];
86
+ if (item) {
87
+ callback(name, internalGetIconData(data, name, item));
88
+ names.push(name);
89
+ }
90
+ }
91
+ return names;
92
+ }
93
+ var optionalPropertyDefaults = {
94
+ provider: "",
95
+ aliases: {},
96
+ not_found: {},
97
+ ...defaultIconDimensions
98
+ };
99
+ function checkOptionalProps(item, defaults) {
100
+ for (const prop in defaults) if (prop in item && typeof item[prop] !== typeof defaults[prop]) return false;
101
+ return true;
102
+ }
103
+ function quicklyValidateIconSet(obj) {
104
+ if (typeof obj !== "object" || obj === null) return null;
105
+ const data = obj;
106
+ if (typeof data.prefix !== "string" || !obj.icons || typeof obj.icons !== "object") return null;
107
+ if (!checkOptionalProps(obj, optionalPropertyDefaults)) return null;
108
+ const icons = data.icons;
109
+ for (const name in icons) {
110
+ const icon = icons[name];
111
+ if (!name || typeof icon.body !== "string" || !checkOptionalProps(icon, defaultExtendedIconProps)) return null;
112
+ }
113
+ const aliases = data.aliases || /* @__PURE__ */ Object.create(null);
114
+ for (const name in aliases) {
115
+ const icon = aliases[name];
116
+ const parent = icon.parent;
117
+ if (!name || typeof parent !== "string" || !icons[parent] && !aliases[parent] || !checkOptionalProps(icon, defaultExtendedIconProps)) return null;
118
+ }
119
+ return data;
120
+ }
121
+ var dataStorage = /* @__PURE__ */ Object.create(null);
122
+ function newStorage(provider, prefix) {
123
+ return {
124
+ provider,
125
+ prefix,
126
+ icons: /* @__PURE__ */ Object.create(null),
127
+ missing: /* @__PURE__ */ new Set()
128
+ };
129
+ }
130
+ function getStorage(provider, prefix) {
131
+ const providerStorage = dataStorage[provider] || (dataStorage[provider] = /* @__PURE__ */ Object.create(null));
132
+ return providerStorage[prefix] || (providerStorage[prefix] = newStorage(provider, prefix));
133
+ }
134
+ function addIconSet(storage2, data) {
135
+ if (!quicklyValidateIconSet(data)) return [];
136
+ return parseIconSet(data, (name, icon) => {
137
+ if (icon) storage2.icons[name] = icon;
138
+ else storage2.missing.add(name);
139
+ });
140
+ }
141
+ function addIconToStorage(storage2, name, icon) {
142
+ try {
143
+ if (typeof icon.body === "string") {
144
+ storage2.icons[name] = { ...icon };
145
+ return true;
146
+ }
147
+ } catch (err) {
148
+ }
149
+ return false;
150
+ }
151
+ var matchIconName = /^[a-z0-9]+(-[a-z0-9]+)*$/;
152
+ var stringToIcon = (value, validate, allowSimpleName, provider = "") => {
153
+ const colonSeparated = value.split(":");
154
+ if (value.slice(0, 1) === "@") {
155
+ if (colonSeparated.length < 2 || colonSeparated.length > 3) return null;
156
+ provider = colonSeparated.shift().slice(1);
157
+ }
158
+ if (colonSeparated.length > 3 || !colonSeparated.length) return null;
159
+ if (colonSeparated.length > 1) {
160
+ const name$1 = colonSeparated.pop();
161
+ const prefix = colonSeparated.pop();
162
+ const result = {
163
+ provider: colonSeparated.length > 0 ? colonSeparated[0] : provider,
164
+ prefix,
165
+ name: name$1
166
+ };
167
+ return validate && !validateIconName(result) ? null : result;
168
+ }
169
+ const name = colonSeparated[0];
170
+ const dashSeparated = name.split("-");
171
+ if (dashSeparated.length > 1) {
172
+ const result = {
173
+ provider,
174
+ prefix: dashSeparated.shift(),
175
+ name: dashSeparated.join("-")
176
+ };
177
+ return validate && !validateIconName(result) ? null : result;
178
+ }
179
+ if (allowSimpleName && provider === "") {
180
+ const result = {
181
+ provider,
182
+ prefix: "",
183
+ name
184
+ };
185
+ return validate && !validateIconName(result, allowSimpleName) ? null : result;
186
+ }
187
+ return null;
188
+ };
189
+ var validateIconName = (icon, allowSimpleName) => {
190
+ if (!icon) return false;
191
+ return !!((allowSimpleName && icon.prefix === "" || !!icon.prefix) && !!icon.name);
192
+ };
193
+ var simpleNames = false;
194
+ function allowSimpleNames(allow) {
195
+ if (typeof allow === "boolean") simpleNames = allow;
196
+ return simpleNames;
197
+ }
198
+ function getIconData(name) {
199
+ const icon = typeof name === "string" ? stringToIcon(name, true, simpleNames) : name;
200
+ if (icon) {
201
+ const storage2 = getStorage(icon.provider, icon.prefix);
202
+ const iconName = icon.name;
203
+ return storage2.icons[iconName] || (storage2.missing.has(iconName) ? null : void 0);
204
+ }
205
+ }
206
+ function addIcon(name, data) {
207
+ const icon = stringToIcon(name, true, simpleNames);
208
+ if (!icon) return false;
209
+ const storage2 = getStorage(icon.provider, icon.prefix);
210
+ if (data) return addIconToStorage(storage2, icon.name, data);
211
+ else {
212
+ storage2.missing.add(icon.name);
213
+ return true;
214
+ }
215
+ }
216
+ function addCollection(data, provider) {
217
+ if (typeof data !== "object") return false;
218
+ if (typeof provider !== "string") provider = data.provider || "";
219
+ if (simpleNames && !provider && !data.prefix) {
220
+ let added = false;
221
+ if (quicklyValidateIconSet(data)) {
222
+ data.prefix = "";
223
+ parseIconSet(data, (name, icon) => {
224
+ if (addIcon(name, icon)) added = true;
225
+ });
226
+ }
227
+ return added;
228
+ }
229
+ const prefix = data.prefix;
230
+ if (!validateIconName({
231
+ prefix,
232
+ name: "a"
233
+ })) return false;
234
+ const storage2 = getStorage(provider, prefix);
235
+ return !!addIconSet(storage2, data);
236
+ }
237
+ var defaultIconSizeCustomisations = Object.freeze({
238
+ width: null,
239
+ height: null
240
+ });
241
+ var defaultIconCustomisations = Object.freeze({
242
+ ...defaultIconSizeCustomisations,
243
+ ...defaultIconTransformations
244
+ });
245
+ var unitsSplit = /(-?[0-9.]*[0-9]+[0-9.]*)/g;
246
+ var unitsTest = /^-?[0-9.]*[0-9]+[0-9.]*$/g;
247
+ function calculateSize(size, ratio, precision) {
248
+ if (ratio === 1) return size;
249
+ precision = precision || 100;
250
+ if (typeof size === "number") return Math.ceil(size * ratio * precision) / precision;
251
+ if (typeof size !== "string") return size;
252
+ const oldParts = size.split(unitsSplit);
253
+ if (oldParts === null || !oldParts.length) return size;
254
+ const newParts = [];
255
+ let code = oldParts.shift();
256
+ let isNumber2 = unitsTest.test(code);
257
+ while (true) {
258
+ if (isNumber2) {
259
+ const num = parseFloat(code);
260
+ if (isNaN(num)) newParts.push(code);
261
+ else newParts.push(Math.ceil(num * ratio * precision) / precision);
262
+ } else newParts.push(code);
263
+ code = oldParts.shift();
264
+ if (code === void 0) return newParts.join("");
265
+ isNumber2 = !isNumber2;
266
+ }
267
+ }
268
+ function splitSVGDefs(content, tag = "defs") {
269
+ let defs = "";
270
+ const index = content.indexOf("<" + tag);
271
+ while (index >= 0) {
272
+ const start = content.indexOf(">", index);
273
+ const end = content.indexOf("</" + tag);
274
+ if (start === -1 || end === -1) break;
275
+ const endEnd = content.indexOf(">", end);
276
+ if (endEnd === -1) break;
277
+ defs += content.slice(start + 1, end).trim();
278
+ content = content.slice(0, index).trim() + content.slice(endEnd + 1);
279
+ }
280
+ return {
281
+ defs,
282
+ content
283
+ };
284
+ }
285
+ function mergeDefsAndContent(defs, content) {
286
+ return defs ? "<defs>" + defs + "</defs>" + content : content;
287
+ }
288
+ function wrapSVGContent(body, start, end) {
289
+ const split = splitSVGDefs(body);
290
+ return mergeDefsAndContent(split.defs, start + split.content + end);
291
+ }
292
+ var isUnsetKeyword = (value) => value === "unset" || value === "undefined" || value === "none";
293
+ function iconToSVG(icon, customisations) {
294
+ const fullIcon = {
295
+ ...defaultIconProps,
296
+ ...icon
297
+ };
298
+ const fullCustomisations = {
299
+ ...defaultIconCustomisations,
300
+ ...customisations
301
+ };
302
+ const box = {
303
+ left: fullIcon.left,
304
+ top: fullIcon.top,
305
+ width: fullIcon.width,
306
+ height: fullIcon.height
307
+ };
308
+ let body = fullIcon.body;
309
+ [fullIcon, fullCustomisations].forEach((props) => {
310
+ const transformations = [];
311
+ const hFlip = props.hFlip;
312
+ const vFlip = props.vFlip;
313
+ let rotation = props.rotate;
314
+ if (hFlip) if (vFlip) rotation += 2;
315
+ else {
316
+ transformations.push("translate(" + (box.width + box.left).toString() + " " + (0 - box.top).toString() + ")");
317
+ transformations.push("scale(-1 1)");
318
+ box.top = box.left = 0;
319
+ }
320
+ else if (vFlip) {
321
+ transformations.push("translate(" + (0 - box.left).toString() + " " + (box.height + box.top).toString() + ")");
322
+ transformations.push("scale(1 -1)");
323
+ box.top = box.left = 0;
324
+ }
325
+ let tempValue;
326
+ if (rotation < 0) rotation -= Math.floor(rotation / 4) * 4;
327
+ rotation = rotation % 4;
328
+ switch (rotation) {
329
+ case 1:
330
+ tempValue = box.height / 2 + box.top;
331
+ transformations.unshift("rotate(90 " + tempValue.toString() + " " + tempValue.toString() + ")");
332
+ break;
333
+ case 2:
334
+ transformations.unshift("rotate(180 " + (box.width / 2 + box.left).toString() + " " + (box.height / 2 + box.top).toString() + ")");
335
+ break;
336
+ case 3:
337
+ tempValue = box.width / 2 + box.left;
338
+ transformations.unshift("rotate(-90 " + tempValue.toString() + " " + tempValue.toString() + ")");
339
+ break;
340
+ }
341
+ if (rotation % 2 === 1) {
342
+ if (box.left !== box.top) {
343
+ tempValue = box.left;
344
+ box.left = box.top;
345
+ box.top = tempValue;
346
+ }
347
+ if (box.width !== box.height) {
348
+ tempValue = box.width;
349
+ box.width = box.height;
350
+ box.height = tempValue;
351
+ }
352
+ }
353
+ if (transformations.length) body = wrapSVGContent(body, '<g transform="' + transformations.join(" ") + '">', "</g>");
354
+ });
355
+ const customisationsWidth = fullCustomisations.width;
356
+ const customisationsHeight = fullCustomisations.height;
357
+ const boxWidth = box.width;
358
+ const boxHeight = box.height;
359
+ let width;
360
+ let height;
361
+ if (customisationsWidth === null) {
362
+ height = customisationsHeight === null ? "1em" : customisationsHeight === "auto" ? boxHeight : customisationsHeight;
363
+ width = calculateSize(height, boxWidth / boxHeight);
364
+ } else {
365
+ width = customisationsWidth === "auto" ? boxWidth : customisationsWidth;
366
+ height = customisationsHeight === null ? calculateSize(width, boxHeight / boxWidth) : customisationsHeight === "auto" ? boxHeight : customisationsHeight;
367
+ }
368
+ const attributes = {};
369
+ const setAttr = (prop, value) => {
370
+ if (!isUnsetKeyword(value)) attributes[prop] = value.toString();
371
+ };
372
+ setAttr("width", width);
373
+ setAttr("height", height);
374
+ const viewBox = [
375
+ box.left,
376
+ box.top,
377
+ boxWidth,
378
+ boxHeight
379
+ ];
380
+ attributes.viewBox = viewBox.join(" ");
381
+ return {
382
+ attributes,
383
+ viewBox,
384
+ body
385
+ };
386
+ }
387
+ var regex = /\sid="(\S+)"/g;
388
+ var randomPrefix = "IconifyId" + Date.now().toString(16) + (Math.random() * 16777216 | 0).toString(16);
389
+ var counter = 0;
390
+ function replaceIDs(body, prefix = randomPrefix) {
391
+ const ids = [];
392
+ let match;
393
+ while (match = regex.exec(body)) ids.push(match[1]);
394
+ if (!ids.length) return body;
395
+ const suffix = "suffix" + (Math.random() * 16777216 | Date.now()).toString(16);
396
+ ids.forEach((id) => {
397
+ const newID = typeof prefix === "function" ? prefix(id) : prefix + (counter++).toString();
398
+ const escapedID = id.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
399
+ body = body.replace(new RegExp('([#;"])(' + escapedID + ')([")]|\\.[a-z])', "g"), "$1" + newID + suffix + "$3");
400
+ });
401
+ body = body.replace(new RegExp(suffix, "g"), "");
402
+ return body;
403
+ }
404
+ var storage = /* @__PURE__ */ Object.create(null);
405
+ function setAPIModule(provider, item) {
406
+ storage[provider] = item;
407
+ }
408
+ function getAPIModule(provider) {
409
+ return storage[provider] || storage[""];
410
+ }
411
+ function createAPIConfig(source) {
412
+ let resources;
413
+ if (typeof source.resources === "string") resources = [source.resources];
414
+ else {
415
+ resources = source.resources;
416
+ if (!(resources instanceof Array) || !resources.length) return null;
417
+ }
418
+ const result = {
419
+ resources,
420
+ path: source.path || "/",
421
+ maxURL: source.maxURL || 500,
422
+ rotate: source.rotate || 750,
423
+ timeout: source.timeout || 5e3,
424
+ random: source.random === true,
425
+ index: source.index || 0,
426
+ dataAfterTimeout: source.dataAfterTimeout !== false
427
+ };
428
+ return result;
429
+ }
430
+ var configStorage = /* @__PURE__ */ Object.create(null);
431
+ var fallBackAPISources = ["https://api.simplesvg.com", "https://api.unisvg.com"];
432
+ var fallBackAPI = [];
433
+ while (fallBackAPISources.length > 0) if (fallBackAPISources.length === 1) fallBackAPI.push(fallBackAPISources.shift());
434
+ else if (Math.random() > 0.5) fallBackAPI.push(fallBackAPISources.shift());
435
+ else fallBackAPI.push(fallBackAPISources.pop());
436
+ configStorage[""] = createAPIConfig({ resources: ["https://api.iconify.design"].concat(fallBackAPI) });
437
+ function addAPIProvider(provider, customConfig) {
438
+ const config = createAPIConfig(customConfig);
439
+ if (config === null) return false;
440
+ configStorage[provider] = config;
441
+ return true;
442
+ }
443
+ function getAPIConfig(provider) {
444
+ return configStorage[provider];
445
+ }
446
+ var detectFetch = () => {
447
+ let callback;
448
+ try {
449
+ callback = fetch;
450
+ if (typeof callback === "function") return callback;
451
+ } catch (err) {
452
+ }
453
+ };
454
+ var fetchModule = detectFetch();
455
+ function calculateMaxLength(provider, prefix) {
456
+ const config = getAPIConfig(provider);
457
+ if (!config) return 0;
458
+ let result;
459
+ if (!config.maxURL) result = 0;
460
+ else {
461
+ let maxHostLength = 0;
462
+ config.resources.forEach((item) => {
463
+ const host = item;
464
+ maxHostLength = Math.max(maxHostLength, host.length);
465
+ });
466
+ const url = prefix + ".json?icons=";
467
+ result = config.maxURL - maxHostLength - config.path.length - url.length;
468
+ }
469
+ return result;
470
+ }
471
+ function shouldAbort(status) {
472
+ return status === 404;
473
+ }
474
+ var prepare = (provider, prefix, icons) => {
475
+ const results = [];
476
+ const maxLength = calculateMaxLength(provider, prefix);
477
+ const type = "icons";
478
+ let item = {
479
+ type,
480
+ provider,
481
+ prefix,
482
+ icons: []
483
+ };
484
+ let length = 0;
485
+ icons.forEach((name, index) => {
486
+ length += name.length + 1;
487
+ if (length >= maxLength && index > 0) {
488
+ results.push(item);
489
+ item = {
490
+ type,
491
+ provider,
492
+ prefix,
493
+ icons: []
494
+ };
495
+ length = name.length;
496
+ }
497
+ item.icons.push(name);
498
+ });
499
+ results.push(item);
500
+ return results;
501
+ };
502
+ function getPath(provider) {
503
+ if (typeof provider === "string") {
504
+ const config = getAPIConfig(provider);
505
+ if (config) return config.path;
506
+ }
507
+ return "/";
508
+ }
509
+ var send = (host, params, callback) => {
510
+ if (!fetchModule) {
511
+ callback("abort", 424);
512
+ return;
513
+ }
514
+ let path = getPath(params.provider);
515
+ switch (params.type) {
516
+ case "icons": {
517
+ const prefix = params.prefix;
518
+ const icons = params.icons;
519
+ const iconsList = icons.join(",");
520
+ const urlParams = new URLSearchParams({ icons: iconsList });
521
+ path += prefix + ".json?" + urlParams.toString();
522
+ break;
523
+ }
524
+ case "custom": {
525
+ const uri = params.uri;
526
+ path += uri.slice(0, 1) === "/" ? uri.slice(1) : uri;
527
+ break;
528
+ }
529
+ default:
530
+ callback("abort", 400);
531
+ return;
532
+ }
533
+ let defaultError = 503;
534
+ fetchModule(host + path).then((response) => {
535
+ const status = response.status;
536
+ if (status !== 200) {
537
+ setTimeout(() => {
538
+ callback(shouldAbort(status) ? "abort" : "next", status);
539
+ });
540
+ return;
541
+ }
542
+ defaultError = 501;
543
+ return response.json();
544
+ }).then((data) => {
545
+ if (typeof data !== "object" || data === null) {
546
+ setTimeout(() => {
547
+ if (data === 404) callback("abort", data);
548
+ else callback("next", defaultError);
549
+ });
550
+ return;
551
+ }
552
+ setTimeout(() => {
553
+ callback("success", data);
554
+ });
555
+ }).catch(() => {
556
+ callback("next", defaultError);
557
+ });
558
+ };
559
+ var fetchAPIModule = {
560
+ prepare,
561
+ send
562
+ };
563
+ function removeCallback(storages, id) {
564
+ storages.forEach((storage2) => {
565
+ const items = storage2.loaderCallbacks;
566
+ if (items) storage2.loaderCallbacks = items.filter((row) => row.id !== id);
567
+ });
568
+ }
569
+ function updateCallbacks(storage2) {
570
+ if (!storage2.pendingCallbacksFlag) {
571
+ storage2.pendingCallbacksFlag = true;
572
+ setTimeout(() => {
573
+ storage2.pendingCallbacksFlag = false;
574
+ const items = storage2.loaderCallbacks ? storage2.loaderCallbacks.slice(0) : [];
575
+ if (!items.length) return;
576
+ let hasPending = false;
577
+ const provider = storage2.provider;
578
+ const prefix = storage2.prefix;
579
+ items.forEach((item) => {
580
+ const icons = item.icons;
581
+ const oldLength = icons.pending.length;
582
+ icons.pending = icons.pending.filter((icon) => {
583
+ if (icon.prefix !== prefix) return true;
584
+ const name = icon.name;
585
+ if (storage2.icons[name]) icons.loaded.push({
586
+ provider,
587
+ prefix,
588
+ name
589
+ });
590
+ else if (storage2.missing.has(name)) icons.missing.push({
591
+ provider,
592
+ prefix,
593
+ name
594
+ });
595
+ else {
596
+ hasPending = true;
597
+ return true;
598
+ }
599
+ return false;
600
+ });
601
+ if (icons.pending.length !== oldLength) {
602
+ if (!hasPending) removeCallback([storage2], item.id);
603
+ item.callback(icons.loaded.slice(0), icons.missing.slice(0), icons.pending.slice(0), item.abort);
604
+ }
605
+ });
606
+ });
607
+ }
608
+ }
609
+ var idCounter = 0;
610
+ function storeCallback(callback, icons, pendingSources) {
611
+ const id = idCounter++;
612
+ const abort = removeCallback.bind(null, pendingSources, id);
613
+ if (!icons.pending.length) return abort;
614
+ const item = {
615
+ id,
616
+ icons,
617
+ callback,
618
+ abort
619
+ };
620
+ pendingSources.forEach((storage2) => {
621
+ (storage2.loaderCallbacks || (storage2.loaderCallbacks = [])).push(item);
622
+ });
623
+ return abort;
624
+ }
625
+ function sortIcons(icons) {
626
+ const result = {
627
+ loaded: [],
628
+ missing: [],
629
+ pending: []
630
+ };
631
+ const storage2 = /* @__PURE__ */ Object.create(null);
632
+ icons.sort((a, b) => {
633
+ if (a.provider !== b.provider) return a.provider.localeCompare(b.provider);
634
+ if (a.prefix !== b.prefix) return a.prefix.localeCompare(b.prefix);
635
+ return a.name.localeCompare(b.name);
636
+ });
637
+ let lastIcon = {
638
+ provider: "",
639
+ prefix: "",
640
+ name: ""
641
+ };
642
+ icons.forEach((icon) => {
643
+ if (lastIcon.name === icon.name && lastIcon.prefix === icon.prefix && lastIcon.provider === icon.provider) return;
644
+ lastIcon = icon;
645
+ const provider = icon.provider;
646
+ const prefix = icon.prefix;
647
+ const name = icon.name;
648
+ const providerStorage = storage2[provider] || (storage2[provider] = /* @__PURE__ */ Object.create(null));
649
+ const localStorage = providerStorage[prefix] || (providerStorage[prefix] = getStorage(provider, prefix));
650
+ let list;
651
+ if (name in localStorage.icons) list = result.loaded;
652
+ else if (prefix === "" || localStorage.missing.has(name)) list = result.missing;
653
+ else list = result.pending;
654
+ const item = {
655
+ provider,
656
+ prefix,
657
+ name
658
+ };
659
+ list.push(item);
660
+ });
661
+ return result;
662
+ }
663
+ function listToIcons(list, validate = true, simpleNames2 = false) {
664
+ const result = [];
665
+ list.forEach((item) => {
666
+ const icon = typeof item === "string" ? stringToIcon(item, validate, simpleNames2) : item;
667
+ if (icon) result.push(icon);
668
+ });
669
+ return result;
670
+ }
671
+ var defaultConfig = {
672
+ resources: [],
673
+ index: 0,
674
+ timeout: 2e3,
675
+ rotate: 750,
676
+ random: false,
677
+ dataAfterTimeout: false
678
+ };
679
+ function sendQuery(config, payload, query, done) {
680
+ const resourcesCount = config.resources.length;
681
+ const startIndex = config.random ? Math.floor(Math.random() * resourcesCount) : config.index;
682
+ let resources;
683
+ if (config.random) {
684
+ let list = config.resources.slice(0);
685
+ resources = [];
686
+ while (list.length > 1) {
687
+ const nextIndex = Math.floor(Math.random() * list.length);
688
+ resources.push(list[nextIndex]);
689
+ list = list.slice(0, nextIndex).concat(list.slice(nextIndex + 1));
690
+ }
691
+ resources = resources.concat(list);
692
+ } else resources = config.resources.slice(startIndex).concat(config.resources.slice(0, startIndex));
693
+ const startTime = Date.now();
694
+ let status = "pending";
695
+ let queriesSent = 0;
696
+ let lastError;
697
+ let timer = null;
698
+ let queue = [];
699
+ let doneCallbacks = [];
700
+ if (typeof done === "function") doneCallbacks.push(done);
701
+ function resetTimer() {
702
+ if (timer) {
703
+ clearTimeout(timer);
704
+ timer = null;
705
+ }
706
+ }
707
+ function abort() {
708
+ if (status === "pending") status = "aborted";
709
+ resetTimer();
710
+ queue.forEach((item) => {
711
+ if (item.status === "pending") item.status = "aborted";
712
+ });
713
+ queue = [];
714
+ }
715
+ function subscribe(callback, overwrite) {
716
+ if (overwrite) doneCallbacks = [];
717
+ if (typeof callback === "function") doneCallbacks.push(callback);
718
+ }
719
+ function getQueryStatus() {
720
+ return {
721
+ startTime,
722
+ payload,
723
+ status,
724
+ queriesSent,
725
+ queriesPending: queue.length,
726
+ subscribe,
727
+ abort
728
+ };
729
+ }
730
+ function failQuery() {
731
+ status = "failed";
732
+ doneCallbacks.forEach((callback) => {
733
+ callback(void 0, lastError);
734
+ });
735
+ }
736
+ function clearQueue() {
737
+ queue.forEach((item) => {
738
+ if (item.status === "pending") item.status = "aborted";
739
+ });
740
+ queue = [];
741
+ }
742
+ function moduleResponse(item, response, data) {
743
+ const isError = response !== "success";
744
+ queue = queue.filter((queued) => queued !== item);
745
+ switch (status) {
746
+ case "pending":
747
+ break;
748
+ case "failed":
749
+ if (isError || !config.dataAfterTimeout) return;
750
+ break;
751
+ default:
752
+ return;
753
+ }
754
+ if (response === "abort") {
755
+ lastError = data;
756
+ failQuery();
757
+ return;
758
+ }
759
+ if (isError) {
760
+ lastError = data;
761
+ if (!queue.length) if (!resources.length) failQuery();
762
+ else execNext();
763
+ return;
764
+ }
765
+ resetTimer();
766
+ clearQueue();
767
+ if (!config.random) {
768
+ const index = config.resources.indexOf(item.resource);
769
+ if (index !== -1 && index !== config.index) config.index = index;
770
+ }
771
+ status = "completed";
772
+ doneCallbacks.forEach((callback) => {
773
+ callback(data);
774
+ });
775
+ }
776
+ function execNext() {
777
+ if (status !== "pending") return;
778
+ resetTimer();
779
+ const resource = resources.shift();
780
+ if (resource === void 0) {
781
+ if (queue.length) {
782
+ timer = setTimeout(() => {
783
+ resetTimer();
784
+ if (status === "pending") {
785
+ clearQueue();
786
+ failQuery();
787
+ }
788
+ }, config.timeout);
789
+ return;
790
+ }
791
+ failQuery();
792
+ return;
793
+ }
794
+ const item = {
795
+ status: "pending",
796
+ resource,
797
+ callback: (status$1, data) => {
798
+ moduleResponse(item, status$1, data);
799
+ }
800
+ };
801
+ queue.push(item);
802
+ queriesSent++;
803
+ timer = setTimeout(execNext, config.rotate);
804
+ query(resource, payload, item.callback);
805
+ }
806
+ setTimeout(execNext);
807
+ return getQueryStatus;
808
+ }
809
+ function initRedundancy(cfg) {
810
+ const config = {
811
+ ...defaultConfig,
812
+ ...cfg
813
+ };
814
+ let queries = [];
815
+ function cleanup() {
816
+ queries = queries.filter((item) => item().status === "pending");
817
+ }
818
+ function query(payload, queryCallback, doneCallback) {
819
+ const query$1 = sendQuery(config, payload, queryCallback, (data, error) => {
820
+ cleanup();
821
+ if (doneCallback) doneCallback(data, error);
822
+ });
823
+ queries.push(query$1);
824
+ return query$1;
825
+ }
826
+ function find(callback) {
827
+ return queries.find((value) => {
828
+ return callback(value);
829
+ }) || null;
830
+ }
831
+ const instance = {
832
+ query,
833
+ find,
834
+ setIndex: (index) => {
835
+ config.index = index;
836
+ },
837
+ getIndex: () => config.index,
838
+ cleanup
839
+ };
840
+ return instance;
841
+ }
842
+ function emptyCallback$1() {
843
+ }
844
+ var redundancyCache = /* @__PURE__ */ Object.create(null);
845
+ function getRedundancyCache(provider) {
846
+ if (!redundancyCache[provider]) {
847
+ const config = getAPIConfig(provider);
848
+ if (!config) return;
849
+ const redundancy = initRedundancy(config);
850
+ const cachedReundancy = {
851
+ config,
852
+ redundancy
853
+ };
854
+ redundancyCache[provider] = cachedReundancy;
855
+ }
856
+ return redundancyCache[provider];
857
+ }
858
+ function sendAPIQuery(target, query, callback) {
859
+ let redundancy;
860
+ let send2;
861
+ if (typeof target === "string") {
862
+ const api = getAPIModule(target);
863
+ if (!api) {
864
+ callback(void 0, 424);
865
+ return emptyCallback$1;
866
+ }
867
+ send2 = api.send;
868
+ const cached = getRedundancyCache(target);
869
+ if (cached) redundancy = cached.redundancy;
870
+ } else {
871
+ const config = createAPIConfig(target);
872
+ if (config) {
873
+ redundancy = initRedundancy(config);
874
+ const moduleKey = target.resources ? target.resources[0] : "";
875
+ const api = getAPIModule(moduleKey);
876
+ if (api) send2 = api.send;
877
+ }
878
+ }
879
+ if (!redundancy || !send2) {
880
+ callback(void 0, 424);
881
+ return emptyCallback$1;
882
+ }
883
+ return redundancy.query(query, send2, callback)().abort;
884
+ }
885
+ function emptyCallback() {
886
+ }
887
+ function loadedNewIcons(storage2) {
888
+ if (!storage2.iconsLoaderFlag) {
889
+ storage2.iconsLoaderFlag = true;
890
+ setTimeout(() => {
891
+ storage2.iconsLoaderFlag = false;
892
+ updateCallbacks(storage2);
893
+ });
894
+ }
895
+ }
896
+ function checkIconNamesForAPI(icons) {
897
+ const valid = [];
898
+ const invalid = [];
899
+ icons.forEach((name) => {
900
+ (name.match(matchIconName) ? valid : invalid).push(name);
901
+ });
902
+ return {
903
+ valid,
904
+ invalid
905
+ };
906
+ }
907
+ function parseLoaderResponse(storage2, icons, data) {
908
+ function checkMissing() {
909
+ const pending = storage2.pendingIcons;
910
+ icons.forEach((name) => {
911
+ if (pending) pending.delete(name);
912
+ if (!storage2.icons[name]) storage2.missing.add(name);
913
+ });
914
+ }
915
+ if (data && typeof data === "object") try {
916
+ const parsed = addIconSet(storage2, data);
917
+ if (!parsed.length) {
918
+ checkMissing();
919
+ return;
920
+ }
921
+ } catch (err) {
922
+ console.error(err);
923
+ }
924
+ checkMissing();
925
+ loadedNewIcons(storage2);
926
+ }
927
+ function parsePossiblyAsyncResponse(response, callback) {
928
+ if (response instanceof Promise) response.then((data) => {
929
+ callback(data);
930
+ }).catch(() => {
931
+ callback(null);
932
+ });
933
+ else callback(response);
934
+ }
935
+ function loadNewIcons(storage2, icons) {
936
+ if (!storage2.iconsToLoad) storage2.iconsToLoad = icons;
937
+ else storage2.iconsToLoad = storage2.iconsToLoad.concat(icons).sort();
938
+ if (!storage2.iconsQueueFlag) {
939
+ storage2.iconsQueueFlag = true;
940
+ setTimeout(() => {
941
+ storage2.iconsQueueFlag = false;
942
+ const { provider, prefix } = storage2;
943
+ const icons$1 = storage2.iconsToLoad;
944
+ delete storage2.iconsToLoad;
945
+ if (!icons$1 || !icons$1.length) return;
946
+ const customIconLoader = storage2.loadIcon;
947
+ if (storage2.loadIcons && (icons$1.length > 1 || !customIconLoader)) {
948
+ parsePossiblyAsyncResponse(storage2.loadIcons(icons$1, prefix, provider), (data) => {
949
+ parseLoaderResponse(storage2, icons$1, data);
950
+ });
951
+ return;
952
+ }
953
+ if (customIconLoader) {
954
+ icons$1.forEach((name) => {
955
+ const response = customIconLoader(name, prefix, provider);
956
+ parsePossiblyAsyncResponse(response, (data) => {
957
+ const iconSet = data ? {
958
+ prefix,
959
+ icons: { [name]: data }
960
+ } : null;
961
+ parseLoaderResponse(storage2, [name], iconSet);
962
+ });
963
+ });
964
+ return;
965
+ }
966
+ const { valid, invalid } = checkIconNamesForAPI(icons$1);
967
+ if (invalid.length) parseLoaderResponse(storage2, invalid, null);
968
+ if (!valid.length) return;
969
+ const api = prefix.match(matchIconName) ? getAPIModule(provider) : null;
970
+ if (!api) {
971
+ parseLoaderResponse(storage2, valid, null);
972
+ return;
973
+ }
974
+ const params = api.prepare(provider, prefix, valid);
975
+ params.forEach((item) => {
976
+ sendAPIQuery(provider, item, (data) => {
977
+ parseLoaderResponse(storage2, item.icons, data);
978
+ });
979
+ });
980
+ });
981
+ }
982
+ }
983
+ var loadIcons = (icons, callback) => {
984
+ const cleanedIcons = listToIcons(icons, true, allowSimpleNames());
985
+ const sortedIcons = sortIcons(cleanedIcons);
986
+ if (!sortedIcons.pending.length) {
987
+ let callCallback = true;
988
+ if (callback) setTimeout(() => {
989
+ if (callCallback) callback(sortedIcons.loaded, sortedIcons.missing, sortedIcons.pending, emptyCallback);
990
+ });
991
+ return () => {
992
+ callCallback = false;
993
+ };
994
+ }
995
+ const newIcons = /* @__PURE__ */ Object.create(null);
996
+ const sources = [];
997
+ let lastProvider, lastPrefix;
998
+ sortedIcons.pending.forEach((icon) => {
999
+ const { provider, prefix } = icon;
1000
+ if (prefix === lastPrefix && provider === lastProvider) return;
1001
+ lastProvider = provider;
1002
+ lastPrefix = prefix;
1003
+ sources.push(getStorage(provider, prefix));
1004
+ const providerNewIcons = newIcons[provider] || (newIcons[provider] = /* @__PURE__ */ Object.create(null));
1005
+ if (!providerNewIcons[prefix]) providerNewIcons[prefix] = [];
1006
+ });
1007
+ sortedIcons.pending.forEach((icon) => {
1008
+ const { provider, prefix, name } = icon;
1009
+ const storage2 = getStorage(provider, prefix);
1010
+ const pendingQueue = storage2.pendingIcons || (storage2.pendingIcons = /* @__PURE__ */ new Set());
1011
+ if (!pendingQueue.has(name)) {
1012
+ pendingQueue.add(name);
1013
+ newIcons[provider][prefix].push(name);
1014
+ }
1015
+ });
1016
+ sources.forEach((storage2) => {
1017
+ const list = newIcons[storage2.provider][storage2.prefix];
1018
+ if (list.length) loadNewIcons(storage2, list);
1019
+ });
1020
+ return callback ? storeCallback(callback, sortedIcons, sources) : emptyCallback;
1021
+ };
1022
+ function mergeCustomisations(defaults, item) {
1023
+ const result = { ...defaults };
1024
+ for (const key in item) {
1025
+ const value = item[key];
1026
+ const valueType = typeof value;
1027
+ if (key in defaultIconSizeCustomisations) {
1028
+ if (value === null || value && (valueType === "string" || valueType === "number")) result[key] = value;
1029
+ } else if (valueType === typeof result[key]) result[key] = key === "rotate" ? value % 4 : value;
1030
+ }
1031
+ return result;
1032
+ }
1033
+ var separator = /[\s,]+/;
1034
+ function flipFromString(custom, flip) {
1035
+ flip.split(separator).forEach((str) => {
1036
+ const value = str.trim();
1037
+ switch (value) {
1038
+ case "horizontal":
1039
+ custom.hFlip = true;
1040
+ break;
1041
+ case "vertical":
1042
+ custom.vFlip = true;
1043
+ break;
1044
+ }
1045
+ });
1046
+ }
1047
+ function rotateFromString(value, defaultValue = 0) {
1048
+ const units = value.replace(/^-?[0-9.]*/, "");
1049
+ function cleanup(value$1) {
1050
+ while (value$1 < 0) value$1 += 4;
1051
+ return value$1 % 4;
1052
+ }
1053
+ if (units === "") {
1054
+ const num = parseInt(value);
1055
+ return isNaN(num) ? 0 : cleanup(num);
1056
+ } else if (units !== value) {
1057
+ let split = 0;
1058
+ switch (units) {
1059
+ case "%":
1060
+ split = 25;
1061
+ break;
1062
+ case "deg":
1063
+ split = 90;
1064
+ }
1065
+ if (split) {
1066
+ let num = parseFloat(value.slice(0, value.length - units.length));
1067
+ if (isNaN(num)) return 0;
1068
+ num = num / split;
1069
+ return num % 1 === 0 ? cleanup(num) : 0;
1070
+ }
1071
+ }
1072
+ return defaultValue;
1073
+ }
1074
+ function iconToHTML(body, attributes) {
1075
+ let renderAttribsHTML = body.indexOf("xlink:") === -1 ? "" : ' xmlns:xlink="http://www.w3.org/1999/xlink"';
1076
+ for (const attr in attributes) renderAttribsHTML += " " + attr + '="' + attributes[attr] + '"';
1077
+ return '<svg xmlns="http://www.w3.org/2000/svg"' + renderAttribsHTML + ">" + body + "</svg>";
1078
+ }
1079
+ function encodeSVGforURL(svg) {
1080
+ return svg.replace(/"/g, "'").replace(/%/g, "%25").replace(/#/g, "%23").replace(/</g, "%3C").replace(/>/g, "%3E").replace(/\s+/g, " ");
1081
+ }
1082
+ function svgToData(svg) {
1083
+ return "data:image/svg+xml," + encodeSVGforURL(svg);
1084
+ }
1085
+ function svgToURL(svg) {
1086
+ return 'url("' + svgToData(svg) + '")';
1087
+ }
1088
+ var policy;
1089
+ function createPolicy() {
1090
+ try {
1091
+ policy = window.trustedTypes.createPolicy("iconify", { createHTML: (s) => s });
1092
+ } catch (err) {
1093
+ policy = null;
1094
+ }
1095
+ }
1096
+ function cleanUpInnerHTML(html) {
1097
+ if (policy === void 0) createPolicy();
1098
+ return policy ? policy.createHTML(html) : html;
1099
+ }
1100
+ var defaultExtendedIconCustomisations = {
1101
+ ...defaultIconCustomisations,
1102
+ inline: false
1103
+ };
1104
+ var svgDefaults = {
1105
+ "xmlns": "http://www.w3.org/2000/svg",
1106
+ "xmlnsXlink": "http://www.w3.org/1999/xlink",
1107
+ "aria-hidden": true,
1108
+ "role": "img"
1109
+ };
1110
+ var commonProps = {
1111
+ display: "inline-block"
1112
+ };
1113
+ var monotoneProps = {
1114
+ backgroundColor: "currentColor"
1115
+ };
1116
+ var coloredProps = {
1117
+ backgroundColor: "transparent"
1118
+ };
1119
+ var propsToAdd = {
1120
+ Image: "var(--svg)",
1121
+ Repeat: "no-repeat",
1122
+ Size: "100% 100%"
1123
+ };
1124
+ var propsToAddTo = {
1125
+ WebkitMask: monotoneProps,
1126
+ mask: monotoneProps,
1127
+ background: coloredProps
1128
+ };
1129
+ for (const prefix in propsToAddTo) {
1130
+ const list = propsToAddTo[prefix];
1131
+ for (const prop in propsToAdd) {
1132
+ list[prefix + prop] = propsToAdd[prop];
1133
+ }
1134
+ }
1135
+ var inlineDefaults = {
1136
+ ...defaultExtendedIconCustomisations,
1137
+ inline: true
1138
+ };
1139
+ function fixSize(value) {
1140
+ return value + (value.match(/^[-0-9.]+$/) ? "px" : "");
1141
+ }
1142
+ var render = (icon, props, name) => {
1143
+ const defaultProps = props.inline ? inlineDefaults : defaultExtendedIconCustomisations;
1144
+ const customisations = mergeCustomisations(defaultProps, props);
1145
+ const mode = props.mode || "svg";
1146
+ const style = {};
1147
+ const customStyle = props.style || {};
1148
+ const componentProps = {
1149
+ ...mode === "svg" ? svgDefaults : {}
1150
+ };
1151
+ if (name) {
1152
+ const iconName = stringToIcon(name, false, true);
1153
+ if (iconName) {
1154
+ const classNames = ["iconify"];
1155
+ const props2 = [
1156
+ "provider",
1157
+ "prefix"
1158
+ ];
1159
+ for (const prop of props2) {
1160
+ if (iconName[prop]) {
1161
+ classNames.push("iconify--" + iconName[prop]);
1162
+ }
1163
+ }
1164
+ componentProps.className = classNames.join(" ");
1165
+ }
1166
+ }
1167
+ for (let key in props) {
1168
+ const value = props[key];
1169
+ if (value === void 0) {
1170
+ continue;
1171
+ }
1172
+ switch (key) {
1173
+ // Properties to ignore
1174
+ case "icon":
1175
+ case "style":
1176
+ case "children":
1177
+ case "onLoad":
1178
+ case "mode":
1179
+ case "ssr":
1180
+ case "fallback":
1181
+ break;
1182
+ // Forward ref
1183
+ case "_ref":
1184
+ componentProps.ref = value;
1185
+ break;
1186
+ // Merge class names
1187
+ case "className":
1188
+ componentProps[key] = (componentProps[key] ? componentProps[key] + " " : "") + value;
1189
+ break;
1190
+ // Boolean attributes
1191
+ case "inline":
1192
+ case "hFlip":
1193
+ case "vFlip":
1194
+ customisations[key] = value === true || value === "true" || value === 1;
1195
+ break;
1196
+ // Flip as string: 'horizontal,vertical'
1197
+ case "flip":
1198
+ if (typeof value === "string") {
1199
+ flipFromString(customisations, value);
1200
+ }
1201
+ break;
1202
+ // Color: copy to style
1203
+ case "color":
1204
+ style.color = value;
1205
+ break;
1206
+ // Rotation as string
1207
+ case "rotate":
1208
+ if (typeof value === "string") {
1209
+ customisations[key] = rotateFromString(value);
1210
+ } else if (typeof value === "number") {
1211
+ customisations[key] = value;
1212
+ }
1213
+ break;
1214
+ // Remove aria-hidden
1215
+ case "ariaHidden":
1216
+ case "aria-hidden":
1217
+ if (value !== true && value !== "true") {
1218
+ delete componentProps["aria-hidden"];
1219
+ }
1220
+ break;
1221
+ // Copy missing property if it does not exist in customisations
1222
+ default:
1223
+ if (defaultProps[key] === void 0) {
1224
+ componentProps[key] = value;
1225
+ }
1226
+ }
1227
+ }
1228
+ const item = iconToSVG(icon, customisations);
1229
+ const renderAttribs = item.attributes;
1230
+ if (customisations.inline) {
1231
+ style.verticalAlign = "-0.125em";
1232
+ }
1233
+ if (mode === "svg") {
1234
+ componentProps.style = {
1235
+ ...style,
1236
+ ...customStyle
1237
+ };
1238
+ Object.assign(componentProps, renderAttribs);
1239
+ let localCounter = 0;
1240
+ let id = props.id;
1241
+ if (typeof id === "string") {
1242
+ id = id.replace(/-/g, "_");
1243
+ }
1244
+ componentProps.dangerouslySetInnerHTML = {
1245
+ __html: cleanUpInnerHTML(replaceIDs(item.body, id ? () => id + "ID" + localCounter++ : "iconifyReact"))
1246
+ };
1247
+ return createElement("svg", componentProps);
1248
+ }
1249
+ const { body, width, height } = icon;
1250
+ const useMask = mode === "mask" || (mode === "bg" ? false : body.indexOf("currentColor") !== -1);
1251
+ const html = iconToHTML(body, {
1252
+ ...renderAttribs,
1253
+ width: width + "",
1254
+ height: height + ""
1255
+ });
1256
+ componentProps.style = {
1257
+ ...style,
1258
+ "--svg": svgToURL(html),
1259
+ "width": fixSize(renderAttribs.width),
1260
+ "height": fixSize(renderAttribs.height),
1261
+ ...commonProps,
1262
+ ...useMask ? monotoneProps : coloredProps,
1263
+ ...customStyle
1264
+ };
1265
+ return createElement("span", componentProps);
1266
+ };
1267
+ allowSimpleNames(true);
1268
+ setAPIModule("", fetchAPIModule);
1269
+ if (typeof document !== "undefined" && typeof window !== "undefined") {
1270
+ const _window = window;
1271
+ if (_window.IconifyPreload !== void 0) {
1272
+ const preload = _window.IconifyPreload;
1273
+ const err = "Invalid IconifyPreload syntax.";
1274
+ if (typeof preload === "object" && preload !== null) {
1275
+ (preload instanceof Array ? preload : [preload]).forEach((item) => {
1276
+ try {
1277
+ if (
1278
+ // Check if item is an object and not null/array
1279
+ typeof item !== "object" || item === null || item instanceof Array || // Check for 'icons' and 'prefix'
1280
+ typeof item.icons !== "object" || typeof item.prefix !== "string" || // Add icon set
1281
+ !addCollection(item)
1282
+ ) {
1283
+ console.error(err);
1284
+ }
1285
+ } catch (e) {
1286
+ console.error(err);
1287
+ }
1288
+ });
1289
+ }
1290
+ }
1291
+ if (_window.IconifyProviders !== void 0) {
1292
+ const providers = _window.IconifyProviders;
1293
+ if (typeof providers === "object" && providers !== null) {
1294
+ for (let key in providers) {
1295
+ const err = "IconifyProviders[" + key + "] is invalid.";
1296
+ try {
1297
+ const value = providers[key];
1298
+ if (typeof value !== "object" || !value || value.resources === void 0) {
1299
+ continue;
1300
+ }
1301
+ if (!addAPIProvider(key, value)) {
1302
+ console.error(err);
1303
+ }
1304
+ } catch (e) {
1305
+ console.error(err);
1306
+ }
1307
+ }
1308
+ }
1309
+ }
1310
+ }
1311
+ function IconComponent(props) {
1312
+ const [mounted, setMounted] = useState(!!props.ssr);
1313
+ const [abort, setAbort] = useState({});
1314
+ function getInitialState(mounted2) {
1315
+ if (mounted2) {
1316
+ const name2 = props.icon;
1317
+ if (typeof name2 === "object") {
1318
+ return {
1319
+ name: "",
1320
+ data: name2
1321
+ };
1322
+ }
1323
+ const data2 = getIconData(name2);
1324
+ if (data2) {
1325
+ return {
1326
+ name: name2,
1327
+ data: data2
1328
+ };
1329
+ }
1330
+ }
1331
+ return {
1332
+ name: ""
1333
+ };
1334
+ }
1335
+ const [state, setState] = useState(getInitialState(!!props.ssr));
1336
+ function cleanup() {
1337
+ const callback = abort.callback;
1338
+ if (callback) {
1339
+ callback();
1340
+ setAbort({});
1341
+ }
1342
+ }
1343
+ function changeState(newState) {
1344
+ if (JSON.stringify(state) !== JSON.stringify(newState)) {
1345
+ cleanup();
1346
+ setState(newState);
1347
+ return true;
1348
+ }
1349
+ }
1350
+ function updateState() {
1351
+ var _a;
1352
+ const name2 = props.icon;
1353
+ if (typeof name2 === "object") {
1354
+ changeState({
1355
+ name: "",
1356
+ data: name2
1357
+ });
1358
+ return;
1359
+ }
1360
+ const data2 = getIconData(name2);
1361
+ if (changeState({
1362
+ name: name2,
1363
+ data: data2
1364
+ })) {
1365
+ if (data2 === void 0) {
1366
+ const callback = loadIcons([name2], updateState);
1367
+ setAbort({
1368
+ callback
1369
+ });
1370
+ } else if (data2) {
1371
+ (_a = props.onLoad) === null || _a === void 0 ? void 0 : _a.call(props, name2);
1372
+ }
1373
+ }
1374
+ }
1375
+ useEffect(() => {
1376
+ setMounted(true);
1377
+ return cleanup;
1378
+ }, []);
1379
+ useEffect(() => {
1380
+ if (mounted) {
1381
+ updateState();
1382
+ }
1383
+ }, [props.icon, mounted]);
1384
+ const { name, data } = state;
1385
+ if (!data) {
1386
+ return props.children ? props.children : props.fallback ? props.fallback : createElement("span", {});
1387
+ }
1388
+ return render({
1389
+ ...defaultIconProps,
1390
+ ...data
1391
+ }, props, name);
1392
+ }
1393
+ var Icon = forwardRef((props, ref) => IconComponent({
1394
+ ...props,
1395
+ _ref: ref
1396
+ }));
1397
+ forwardRef((props, ref) => IconComponent({
1398
+ inline: true,
1399
+ ...props,
1400
+ _ref: ref
1401
+ }));
13
1402
  var buttonVariants = cva(
14
1403
  "inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-300 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-primary-700 dark:focus-visible:ring-offset-zinc-950",
15
1404
  {
@@ -833,6 +2222,138 @@ var uploadFile = ({
833
2222
  }
834
2223
  xhr.send(formData);
835
2224
  });
2225
+ var splitFileIntoChunks = (file, chunkSize) => {
2226
+ const chunks = [];
2227
+ let start = 0;
2228
+ let index = 0;
2229
+ while (start < file.size) {
2230
+ const end = Math.min(start + chunkSize, file.size);
2231
+ const blob = file.slice(start, end);
2232
+ chunks.push({
2233
+ blob,
2234
+ index,
2235
+ start,
2236
+ end
2237
+ });
2238
+ start = end;
2239
+ index++;
2240
+ }
2241
+ return chunks;
2242
+ };
2243
+ var uploadChunk = ({
2244
+ action,
2245
+ chunk,
2246
+ chunkIndex,
2247
+ totalChunks,
2248
+ fileName,
2249
+ fileSize,
2250
+ method = "post",
2251
+ headers,
2252
+ onProgress,
2253
+ signal
2254
+ }) => new Promise((resolve, reject) => {
2255
+ const xhr = new XMLHttpRequest();
2256
+ xhr.open(method.toUpperCase(), action, true);
2257
+ const handleAbort = () => {
2258
+ xhr.abort();
2259
+ };
2260
+ if (headers) {
2261
+ Object.entries(headers).forEach(([key, value]) => {
2262
+ xhr.setRequestHeader(key, value);
2263
+ });
2264
+ }
2265
+ xhr.upload.onprogress = (event) => {
2266
+ onProgress == null ? void 0 : onProgress(event);
2267
+ };
2268
+ xhr.onload = () => {
2269
+ signal == null ? void 0 : signal.removeEventListener("abort", handleAbort);
2270
+ if (xhr.status >= 200 && xhr.status < 300) {
2271
+ resolve(xhr.responseText);
2272
+ } else {
2273
+ reject(new Error(`Chunk upload failed: ${xhr.statusText}`));
2274
+ }
2275
+ };
2276
+ xhr.onerror = (event) => {
2277
+ signal == null ? void 0 : signal.removeEventListener("abort", handleAbort);
2278
+ reject(event);
2279
+ };
2280
+ xhr.onabort = () => {
2281
+ signal == null ? void 0 : signal.removeEventListener("abort", handleAbort);
2282
+ reject(new DOMException("Chunk upload aborted", "AbortError"));
2283
+ };
2284
+ if (signal == null ? void 0 : signal.aborted) {
2285
+ reject(new DOMException("Chunk upload aborted", "AbortError"));
2286
+ return;
2287
+ }
2288
+ signal == null ? void 0 : signal.addEventListener("abort", handleAbort);
2289
+ const formData = new FormData();
2290
+ formData.append("file", chunk);
2291
+ formData.append("chunkIndex", String(chunkIndex));
2292
+ formData.append("totalChunks", String(totalChunks));
2293
+ formData.append("fileName", fileName);
2294
+ formData.append("fileSize", String(fileSize));
2295
+ xhr.send(formData);
2296
+ });
2297
+ var checkUploadedChunks = (action, file, chunkSize, headers) => new Promise((resolve, _reject) => {
2298
+ const xhr = new XMLHttpRequest();
2299
+ const params = new URLSearchParams({
2300
+ fileName: file.name,
2301
+ fileSize: String(file.size),
2302
+ chunkSize: String(chunkSize)
2303
+ });
2304
+ xhr.open("GET", `${action}?${params}`, true);
2305
+ if (headers) {
2306
+ Object.entries(headers).forEach(([key, value]) => {
2307
+ xhr.setRequestHeader(key, value);
2308
+ });
2309
+ }
2310
+ xhr.onload = () => {
2311
+ if (xhr.status >= 200 && xhr.status < 300) {
2312
+ resolve(xhr.responseText);
2313
+ } else {
2314
+ resolve("[]");
2315
+ }
2316
+ };
2317
+ xhr.onerror = () => {
2318
+ resolve("[]");
2319
+ };
2320
+ xhr.ontimeout = () => {
2321
+ resolve("[]");
2322
+ };
2323
+ xhr.send();
2324
+ }).then((responseText) => {
2325
+ try {
2326
+ const data = JSON.parse(responseText);
2327
+ return data.uploadedChunks || [];
2328
+ } catch (e) {
2329
+ return [];
2330
+ }
2331
+ });
2332
+ var mergeChunks = (action, fileName, totalChunks, method = "post", headers) => new Promise((resolve, reject) => {
2333
+ const xhr = new XMLHttpRequest();
2334
+ xhr.open(method.toUpperCase(), action, true);
2335
+ if (headers) {
2336
+ Object.entries(headers).forEach(([key, value]) => {
2337
+ xhr.setRequestHeader(key, value);
2338
+ });
2339
+ }
2340
+ xhr.setRequestHeader("Content-Type", "application/json");
2341
+ xhr.onload = () => {
2342
+ if (xhr.status >= 200 && xhr.status < 300) {
2343
+ resolve(xhr.responseText);
2344
+ } else {
2345
+ reject(new Error(`Merge chunks failed: ${xhr.statusText}`));
2346
+ }
2347
+ };
2348
+ xhr.onerror = (event) => {
2349
+ reject(event);
2350
+ };
2351
+ const body = JSON.stringify({
2352
+ fileName,
2353
+ totalChunks
2354
+ });
2355
+ xhr.send(body);
2356
+ });
836
2357
  var uploadTriggerVariants = cva(
837
2358
  "flex cursor-pointer select-none items-center justify-center gap-2 whitespace-nowrap text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-300 focus-visible:ring-offset-2 focus-visible:ring-offset-white",
838
2359
  {
@@ -1084,7 +2605,97 @@ function ImageUpload({
1084
2605
  }
1085
2606
  );
1086
2607
  }
1087
- function FileItem({ file, onRemove, onCancel }) {
2608
+ function ChunkItem({ index, progress, isCompleted, isUploading, isPending }) {
2609
+ const getStatusColor = () => {
2610
+ if (isCompleted) return "bg-green-500";
2611
+ if (isUploading) return "bg-blue-500";
2612
+ return "bg-gray-300";
2613
+ };
2614
+ return /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", children: /* @__PURE__ */ jsx(
2615
+ "div",
2616
+ {
2617
+ className: `w-2 h-2 rounded-full ${getStatusColor()} transition-all duration-200`,
2618
+ title: `\u5206\u7247 ${index + 1}: ${isCompleted ? "\u5DF2\u5B8C\u6210" : isUploading ? `${progress}%` : "\u7B49\u5F85\u4E2D"}`,
2619
+ children: isUploading && /* @__PURE__ */ jsxs("svg", { className: "w-2 h-2 -rotate-90", viewBox: "0 0 8 8", children: [
2620
+ /* @__PURE__ */ jsx(
2621
+ "circle",
2622
+ {
2623
+ cx: "4",
2624
+ cy: "4",
2625
+ r: "3",
2626
+ fill: "none",
2627
+ stroke: "#e5e7eb",
2628
+ strokeWidth: "1"
2629
+ }
2630
+ ),
2631
+ /* @__PURE__ */ jsx(
2632
+ "circle",
2633
+ {
2634
+ cx: "4",
2635
+ cy: "4",
2636
+ r: "3",
2637
+ fill: "none",
2638
+ stroke: "#3b82f6",
2639
+ strokeWidth: "1",
2640
+ strokeDasharray: `${progress * 0.188} 18.8`,
2641
+ strokeLinecap: "round"
2642
+ }
2643
+ )
2644
+ ] })
2645
+ }
2646
+ ) });
2647
+ }
2648
+ function ChunkList({ chunkProgress, totalChunks }) {
2649
+ if (!chunkProgress || totalChunks <= 1) {
2650
+ return null;
2651
+ }
2652
+ const { uploadedChunks, chunkIndex, chunkProgress: currentProgress } = chunkProgress;
2653
+ const chunks = Array.from({ length: totalChunks }, (_, i) => {
2654
+ if (i < uploadedChunks) {
2655
+ return { index: i, status: "completed" };
2656
+ } else if (i === chunkIndex) {
2657
+ return { index: i, status: "uploading", progress: currentProgress };
2658
+ } else {
2659
+ return { index: i, status: "pending" };
2660
+ }
2661
+ });
2662
+ if (totalChunks > 20) {
2663
+ return /* @__PURE__ */ jsx("div", { className: "mt-1 text-xs text-gray-400", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
2664
+ /* @__PURE__ */ jsxs("span", { children: [
2665
+ uploadedChunks,
2666
+ "/",
2667
+ totalChunks,
2668
+ " \u5206\u7247\u5DF2\u4E0A\u4F20"
2669
+ ] }),
2670
+ chunkIndex !== void 0 && /* @__PURE__ */ jsxs("span", { className: "text-blue-500", children: [
2671
+ "\u5F53\u524D: \u5206\u7247 ",
2672
+ chunkIndex + 1,
2673
+ " (",
2674
+ currentProgress,
2675
+ "%)"
2676
+ ] })
2677
+ ] }) });
2678
+ }
2679
+ return /* @__PURE__ */ jsxs("div", { className: "mt-1 flex items-center gap-0.5 flex-wrap", children: [
2680
+ chunks.map((chunk) => /* @__PURE__ */ jsx(
2681
+ ChunkItem,
2682
+ {
2683
+ index: chunk.index,
2684
+ progress: chunk.progress || 0,
2685
+ isCompleted: chunk.status === "completed",
2686
+ isUploading: chunk.status === "uploading",
2687
+ isPending: chunk.status === "pending"
2688
+ },
2689
+ chunk.index
2690
+ )),
2691
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-400 ml-1", children: [
2692
+ uploadedChunks,
2693
+ "/",
2694
+ totalChunks
2695
+ ] })
2696
+ ] });
2697
+ }
2698
+ function FileItem({ file, onRemove, onCancel, chunkProgress }) {
1088
2699
  const { id, file: fileData, status, progress, error } = file;
1089
2700
  const iconMap = {
1090
2701
  idle: { icon: "lucide:file", className: "text-gray-400" },
@@ -1106,17 +2717,26 @@ function FileItem({ file, onRemove, onCancel }) {
1106
2717
  /* @__PURE__ */ jsx("span", { className: "text-xs text-gray-500 ml-2", children: formatSize(fileData.size) })
1107
2718
  ] }),
1108
2719
  (status === "uploading" || status === "success") && /* @__PURE__ */ jsxs("div", { className: "mt-1", children: [
1109
- /* @__PURE__ */ jsx("div", { className: "h-1.5 w-full bg-gray-200 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx(
1110
- "div",
2720
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2721
+ /* @__PURE__ */ jsx("div", { className: "flex-1 h-1.5 bg-gray-200 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx(
2722
+ "div",
2723
+ {
2724
+ className: "h-full bg-blue-500 transition-all duration-300",
2725
+ style: { width: `${progress}%` }
2726
+ }
2727
+ ) }),
2728
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-500 whitespace-nowrap", children: [
2729
+ progress,
2730
+ "%"
2731
+ ] })
2732
+ ] }),
2733
+ chunkProgress && chunkProgress.totalChunks > 1 && /* @__PURE__ */ jsx(
2734
+ ChunkList,
1111
2735
  {
1112
- className: "h-full bg-blue-500 transition-all duration-300",
1113
- style: { width: `${progress}%` }
2736
+ chunkProgress,
2737
+ totalChunks: chunkProgress.totalChunks
1114
2738
  }
1115
- ) }),
1116
- /* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-500", children: [
1117
- progress,
1118
- "%"
1119
- ] })
2739
+ )
1120
2740
  ] }),
1121
2741
  status === "error" && error && /* @__PURE__ */ jsx("div", { className: "mt-1 text-xs text-red-500", children: error.message })
1122
2742
  ] }),
@@ -1144,7 +2764,7 @@ function FileItem({ file, onRemove, onCancel }) {
1144
2764
  ] })
1145
2765
  ] });
1146
2766
  }
1147
- function FileList({ files, onRemove, onCancel, show = true }) {
2767
+ function FileList({ files, onRemove, onCancel, show = true, chunkProgressMap }) {
1148
2768
  if (!show || files.length === 0) {
1149
2769
  return null;
1150
2770
  }
@@ -1153,7 +2773,8 @@ function FileList({ files, onRemove, onCancel, show = true }) {
1153
2773
  {
1154
2774
  file,
1155
2775
  onRemove,
1156
- onCancel
2776
+ onCancel,
2777
+ chunkProgress: chunkProgressMap == null ? void 0 : chunkProgressMap[file.id]
1157
2778
  },
1158
2779
  file.id
1159
2780
  )) });
@@ -1168,6 +2789,26 @@ var DEFAULT_OPTIONS = {
1168
2789
  method: "post",
1169
2790
  name: "file"
1170
2791
  };
2792
+ var DEFAULT_CHUNKED_CONFIG = {
2793
+ chunked: false,
2794
+ chunkSize: 2 * 1024 * 1024,
2795
+ // 2MB
2796
+ chunkConcurrency: 0,
2797
+ // 0 表示根据文件大小自动计算
2798
+ resumable: false,
2799
+ chunkedUrl: "",
2800
+ mergeUrl: "",
2801
+ chunkThreshold: 5 * 1024 * 1024
2802
+ // 5MB
2803
+ };
2804
+ var calculateConcurrency = (fileSize) => {
2805
+ const mb = fileSize / 1024 / 1024;
2806
+ if (mb < 10) return 2;
2807
+ if (mb < 50) return 3;
2808
+ if (mb < 100) return 4;
2809
+ if (mb < 500) return 5;
2810
+ return 6;
2811
+ };
1171
2812
  var createUploadError = (type, message, file, originalError) => ({
1172
2813
  type,
1173
2814
  message,
@@ -1180,6 +2821,10 @@ function Upload(config) {
1180
2821
  ...DEFAULT_OPTIONS,
1181
2822
  ...config
1182
2823
  };
2824
+ const chunkedConfig = {
2825
+ ...DEFAULT_CHUNKED_CONFIG,
2826
+ ...config.chunkedConfig
2827
+ };
1183
2828
  const {
1184
2829
  mode,
1185
2830
  autoUpload,
@@ -1203,11 +2848,21 @@ function Upload(config) {
1203
2848
  onError,
1204
2849
  onComplete
1205
2850
  } = options;
2851
+ const {
2852
+ chunked,
2853
+ chunkSize,
2854
+ chunkConcurrency,
2855
+ resumable,
2856
+ chunkedUrl,
2857
+ mergeUrl,
2858
+ chunkThreshold
2859
+ } = chunkedConfig;
1206
2860
  const [files, setFiles] = useState([]);
1207
2861
  const [isDragging, setIsDragging] = useState(false);
1208
2862
  const [previewUrl, setPreviewUrl] = useState(null);
1209
2863
  const [status, setStatus] = useState("idle");
1210
2864
  const [progress, setProgress] = useState(0);
2865
+ const [chunkProgress, setChunkProgress] = useState({});
1211
2866
  const inputId = useId();
1212
2867
  const abortRef = useRef(null);
1213
2868
  const cancelRef = useRef(false);
@@ -1257,6 +2912,24 @@ function Upload(config) {
1257
2912
  const { file } = fileItem;
1258
2913
  const controller = new AbortController();
1259
2914
  abortRef.current = controller;
2915
+ const useChunkedUpload = chunked && file.size > chunkThreshold;
2916
+ if (!useChunkedUpload) {
2917
+ return uploadWithNormalMode(
2918
+ fileItem,
2919
+ totalBytes,
2920
+ uploadedBytes,
2921
+ controller
2922
+ );
2923
+ }
2924
+ return uploadWithChunkedMode(
2925
+ fileItem,
2926
+ totalBytes,
2927
+ uploadedBytes,
2928
+ controller
2929
+ );
2930
+ };
2931
+ const uploadWithNormalMode = async (fileItem, totalBytes, uploadedBytes, controller) => {
2932
+ const { file } = fileItem;
1260
2933
  try {
1261
2934
  const formData = new FormData();
1262
2935
  formData.append(name, file);
@@ -1314,6 +2987,156 @@ function Upload(config) {
1314
2987
  return { ...fileItem, status: "error", error };
1315
2988
  }
1316
2989
  };
2990
+ const uploadWithChunkedMode = async (fileItem, totalBytes, uploadedBytes, controller) => {
2991
+ const { file } = fileItem;
2992
+ const fileId = fileItem.id;
2993
+ try {
2994
+ let uploadedChunkIndices = [];
2995
+ if (resumable && chunkedUrl) {
2996
+ uploadedChunkIndices = await checkUploadedChunks(
2997
+ chunkedUrl,
2998
+ file,
2999
+ chunkSize,
3000
+ headers
3001
+ );
3002
+ }
3003
+ const chunks = splitFileIntoChunks(file, chunkSize);
3004
+ const totalChunks = chunks.length;
3005
+ const actualConcurrency = chunkConcurrency > 0 ? Math.min(chunkConcurrency, totalChunks) : Math.min(calculateConcurrency(file.size), totalChunks);
3006
+ const chunksToUpload = chunks.filter(
3007
+ (chunk) => !uploadedChunkIndices.includes(chunk.index)
3008
+ );
3009
+ const completedChunksRef = { current: uploadedChunkIndices.length };
3010
+ const chunkProgressMapRef = { current: /* @__PURE__ */ new Map() };
3011
+ const uploadTasks = chunksToUpload.map((chunk) => async () => {
3012
+ if (cancelRef.current || controller.signal.aborted) {
3013
+ throw new DOMException("Upload aborted", "AbortError");
3014
+ }
3015
+ chunkProgressMapRef.current.set(chunk.index, 0);
3016
+ await uploadChunk({
3017
+ action,
3018
+ chunk: chunk.blob,
3019
+ chunkIndex: chunk.index,
3020
+ totalChunks,
3021
+ fileName: file.name,
3022
+ fileSize: file.size,
3023
+ method,
3024
+ headers,
3025
+ signal: controller.signal,
3026
+ onProgress: (event) => {
3027
+ if (!event.lengthComputable) {
3028
+ return;
3029
+ }
3030
+ const chunkLoaded = event.loaded;
3031
+ const chunkTotal = chunk.end - chunk.start;
3032
+ const chunkProgressPercent = Math.min(
3033
+ 100,
3034
+ Math.round(chunkLoaded / chunkTotal * 100)
3035
+ );
3036
+ chunkProgressMapRef.current.set(chunk.index, chunkProgressPercent);
3037
+ const completedCount = completedChunksRef.current;
3038
+ let inProgressProgress = 0;
3039
+ chunkProgressMapRef.current.forEach((progress2) => {
3040
+ inProgressProgress += progress2;
3041
+ });
3042
+ const totalProgress = Math.min(
3043
+ 100,
3044
+ Math.round(
3045
+ (completedCount * 100 + inProgressProgress) / totalChunks
3046
+ )
3047
+ );
3048
+ setChunkProgress((prev) => ({
3049
+ ...prev,
3050
+ [fileId]: {
3051
+ chunkIndex: chunk.index,
3052
+ chunkProgress: chunkProgressPercent,
3053
+ totalProgress,
3054
+ uploadedChunks: completedCount,
3055
+ totalChunks
3056
+ }
3057
+ }));
3058
+ setProgress(totalProgress);
3059
+ onProgress == null ? void 0 : onProgress(totalProgress, file);
3060
+ setFiles(
3061
+ (prev) => prev.map(
3062
+ (f) => f.id === fileItem.id ? { ...f, progress: totalProgress } : f
3063
+ )
3064
+ );
3065
+ }
3066
+ });
3067
+ completedChunksRef.current++;
3068
+ chunkProgressMapRef.current.delete(chunk.index);
3069
+ return chunk.index;
3070
+ });
3071
+ const executeWithConcurrency = async (tasks, limit) => {
3072
+ const results = [];
3073
+ const executing = [];
3074
+ let taskIndex = 0;
3075
+ const runTask = async (task) => {
3076
+ const result = await task();
3077
+ return result;
3078
+ };
3079
+ while (taskIndex < tasks.length || executing.length > 0) {
3080
+ while (taskIndex < tasks.length && executing.length < limit) {
3081
+ const task = tasks[taskIndex];
3082
+ taskIndex++;
3083
+ const promise = runTask(task).then((result) => {
3084
+ results.push(result);
3085
+ return result;
3086
+ });
3087
+ executing.push(promise);
3088
+ }
3089
+ if (executing.length > 0) {
3090
+ await Promise.race(executing);
3091
+ const completedIndex = executing.findIndex(
3092
+ (p) => p.then !== void 0
3093
+ );
3094
+ if (completedIndex !== -1) {
3095
+ executing.splice(completedIndex, 1);
3096
+ }
3097
+ }
3098
+ }
3099
+ return results;
3100
+ };
3101
+ await executeWithConcurrency(uploadTasks, actualConcurrency);
3102
+ let responseText = "";
3103
+ if (mergeUrl) {
3104
+ responseText = await mergeChunks(
3105
+ mergeUrl,
3106
+ file.name,
3107
+ totalChunks,
3108
+ method === "get" ? "post" : method,
3109
+ headers
3110
+ );
3111
+ }
3112
+ const updatedFile = {
3113
+ ...fileItem,
3114
+ status: "success",
3115
+ progress: 100,
3116
+ response: responseText || "Chunked upload completed"
3117
+ };
3118
+ setChunkProgress((prev) => {
3119
+ const newProgress = { ...prev };
3120
+ delete newProgress[fileId];
3121
+ return newProgress;
3122
+ });
3123
+ onSuccess == null ? void 0 : onSuccess(responseText || "Chunked upload completed", file);
3124
+ return updatedFile;
3125
+ } catch (event) {
3126
+ const isAbort = cancelRef.current || (event == null ? void 0 : event.name) === "AbortError";
3127
+ if (isAbort) {
3128
+ return { ...fileItem, status: "idle", progress: 0 };
3129
+ }
3130
+ const error = createUploadError(
3131
+ "NETWORK_ERROR",
3132
+ event instanceof Error ? event.message : "\u5206\u7247\u4E0A\u4F20\u5931\u8D25",
3133
+ file,
3134
+ event instanceof Error ? event : void 0
3135
+ );
3136
+ onError == null ? void 0 : onError(error, file);
3137
+ return { ...fileItem, status: "error", error };
3138
+ }
3139
+ };
1317
3140
  const uploadFiles = useCallback(async (filesToUpload) => {
1318
3141
  var _a;
1319
3142
  if (!action || filesToUpload.length === 0) {
@@ -1347,7 +3170,12 @@ function Upload(config) {
1347
3170
  uploadedFiles.push(result);
1348
3171
  setFiles(
1349
3172
  (prev) => prev.map(
1350
- (f) => f.id === fileItem.id ? { ...f, status: result.status, response: result.response } : f
3173
+ (f) => f.id === fileItem.id ? {
3174
+ ...f,
3175
+ status: result.status,
3176
+ response: result.response,
3177
+ progress: result.status === "success" ? 100 : f.progress
3178
+ } : f
1351
3179
  )
1352
3180
  );
1353
3181
  if (result.status === "success") {
@@ -1513,7 +3341,8 @@ function Upload(config) {
1513
3341
  files,
1514
3342
  show: showFileList,
1515
3343
  onRemove: handleRemoveFile,
1516
- onCancel: handleCancelFile
3344
+ onCancel: handleCancelFile,
3345
+ chunkProgressMap: chunkProgress
1517
3346
  }
1518
3347
  )
1519
3348
  ] });