@spark-ui/components 11.5.1 → 11.6.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.
@@ -20,15 +20,47 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/file-upload/index.ts
21
21
  var file_upload_exports = {};
22
22
  __export(file_upload_exports, {
23
+ FILE_UPLOAD_ERRORS: () => FILE_UPLOAD_ERRORS,
23
24
  FileUpload: () => FileUpload2
24
25
  });
25
26
  module.exports = __toCommonJS(file_upload_exports);
26
27
 
27
28
  // src/file-upload/FileUpload.tsx
28
29
  var import_form_field = require("@spark-ui/components/form-field");
30
+ var import_react3 = require("react");
31
+
32
+ // src/file-upload/useFileUploadState.tsx
29
33
  var import_use_combined_state = require("@spark-ui/hooks/use-combined-state");
30
34
  var import_react2 = require("react");
31
35
 
36
+ // src/file-upload/constants.ts
37
+ var FILE_UPLOAD_ERRORS = {
38
+ /**
39
+ * Exceeds the maxFiles limit
40
+ */
41
+ TOO_MANY_FILES: "TOO_MANY_FILES",
42
+ /**
43
+ * File type not in the accept list
44
+ */
45
+ FILE_INVALID_TYPE: "FILE_INVALID_TYPE",
46
+ /**
47
+ * File size exceeds maxFileSize
48
+ */
49
+ FILE_TOO_LARGE: "FILE_TOO_LARGE",
50
+ /**
51
+ * File size below minFileSize
52
+ */
53
+ FILE_TOO_SMALL: "FILE_TOO_SMALL",
54
+ /**
55
+ * Generic validation failure
56
+ */
57
+ FILE_INVALID: "FILE_INVALID",
58
+ /**
59
+ * Duplicate file detected
60
+ */
61
+ FILE_EXISTS: "FILE_EXISTS"
62
+ };
63
+
32
64
  // src/file-upload/utils.ts
33
65
  var import_CvOutline = require("@spark-ui/icons/CvOutline");
34
66
  var import_FilePdfOutline = require("@spark-ui/icons/FilePdfOutline");
@@ -128,13 +160,8 @@ function getFileIcon(file) {
128
160
  return (0, import_react.createElement)(import_CvOutline.CvOutline);
129
161
  }
130
162
 
131
- // src/file-upload/FileUpload.tsx
132
- var import_jsx_runtime = require("react/jsx-runtime");
133
- var FileUploadContext = (0, import_react2.createContext)(null);
134
- var ID_PREFIX = ":file-upload";
135
- var FileUpload = ({
136
- asChild: _asChild = false,
137
- children,
163
+ // src/file-upload/useFileUploadState.tsx
164
+ function useFileUploadState({
138
165
  defaultValue = [],
139
166
  value: controlledValue,
140
167
  onFileAccept,
@@ -145,32 +172,12 @@ var FileUpload = ({
145
172
  maxFiles,
146
173
  maxFileSize,
147
174
  minFileSize,
148
- disabled: disabledProp = false,
149
- readOnly: readOnlyProp = false,
175
+ disabled = false,
176
+ readOnly = false,
150
177
  locale
151
- }) => {
152
- const field = (0, import_form_field.useFormFieldControl)();
153
- const {
154
- id: fieldId,
155
- name: fieldName,
156
- isInvalid,
157
- isRequired,
158
- description,
159
- disabled: fieldDisabled,
160
- readOnly: fieldReadOnly,
161
- labelId
162
- } = field;
178
+ }) {
163
179
  const defaultLocale = locale || (typeof navigator !== "undefined" && navigator.language ? navigator.language : "en");
164
- const internalId = (0, import_react2.useId)();
165
- const inputId = fieldId || `${ID_PREFIX}-${internalId}`;
166
- const inputName = fieldName;
167
- const inputRef = (0, import_react2.useRef)(null);
168
- const triggerRef = (0, import_react2.useRef)(null);
169
- const dropzoneRef = (0, import_react2.useRef)(null);
170
- const deleteButtonRefs = (0, import_react2.useRef)([]);
171
- const disabled = fieldDisabled ?? disabledProp;
172
- const readOnly = fieldReadOnly ?? readOnlyProp;
173
- const [filesState, setFilesState, ,] = (0, import_use_combined_state.useCombinedState)(controlledValue, defaultValue);
180
+ const [filesState, setFilesState] = (0, import_use_combined_state.useCombinedState)(controlledValue, defaultValue);
174
181
  const files = filesState ?? [];
175
182
  const setFiles = setFilesState;
176
183
  const [rejectedFiles, setRejectedFiles] = (0, import_react2.useState)([]);
@@ -202,20 +209,17 @@ var FileUpload = ({
202
209
  };
203
210
  setFiles((prev) => {
204
211
  const currentFiles = prev ?? [];
205
- if (maxFiles !== void 0) {
206
- const currentCount = currentFiles.length;
207
- const remainingSlots = maxFiles - currentCount;
208
- if (remainingSlots <= 0) {
209
- newFiles.forEach((file) => {
210
- addRejectedFile(file, "TOO_MANY_FILES");
211
- });
212
- }
212
+ const remainingSlots = maxFiles !== void 0 ? maxFiles - currentFiles.length : void 0;
213
+ if (remainingSlots !== void 0 && remainingSlots <= 0) {
214
+ newFiles.forEach((file) => {
215
+ addRejectedFile(file, FILE_UPLOAD_ERRORS.TOO_MANY_FILES);
216
+ });
213
217
  }
214
218
  let filteredFiles = newFiles;
215
219
  if (accept) {
216
220
  const rejectedByAccept = newFiles.filter((file) => !validateFileAccept(file, accept));
217
221
  rejectedByAccept.forEach((file) => {
218
- addRejectedFile(file, "FILE_INVALID_TYPE");
222
+ addRejectedFile(file, FILE_UPLOAD_ERRORS.FILE_INVALID_TYPE);
219
223
  });
220
224
  filteredFiles = newFiles.filter((file) => validateFileAccept(file, accept));
221
225
  }
@@ -225,11 +229,11 @@ var FileUpload = ({
225
229
  const validation = validateFileSize(file, minFileSize, maxFileSize, defaultLocale);
226
230
  if (!validation.valid) {
227
231
  if (maxFileSize !== void 0 && file.size > maxFileSize) {
228
- addRejectedFile(file, "FILE_TOO_LARGE");
232
+ addRejectedFile(file, FILE_UPLOAD_ERRORS.FILE_TOO_LARGE);
229
233
  } else if (minFileSize !== void 0 && file.size < minFileSize) {
230
- addRejectedFile(file, "FILE_TOO_SMALL");
234
+ addRejectedFile(file, FILE_UPLOAD_ERRORS.FILE_TOO_SMALL);
231
235
  } else {
232
- addRejectedFile(file, "FILE_INVALID");
236
+ addRejectedFile(file, FILE_UPLOAD_ERRORS.FILE_INVALID);
233
237
  }
234
238
  return false;
235
239
  }
@@ -237,35 +241,27 @@ var FileUpload = ({
237
241
  });
238
242
  }
239
243
  const seenFiles = /* @__PURE__ */ new Map();
240
- const duplicateFiles = [];
241
244
  const uniqueFiles = validSizeFiles.filter((file) => {
242
245
  const fileKey = `${file.name}-${file.size}`;
243
246
  const existsInPrev = fileExists(file, currentFiles);
244
247
  if (existsInPrev) {
245
- duplicateFiles.push(file);
246
- addRejectedFile(file, "FILE_EXISTS");
248
+ addRejectedFile(file, FILE_UPLOAD_ERRORS.FILE_EXISTS);
247
249
  return false;
248
250
  }
249
251
  if (seenFiles.has(fileKey)) {
250
- duplicateFiles.push(file);
251
- addRejectedFile(file, "FILE_EXISTS");
252
+ addRejectedFile(file, FILE_UPLOAD_ERRORS.FILE_EXISTS);
252
253
  return false;
253
254
  }
254
255
  seenFiles.set(fileKey, file);
255
256
  return true;
256
257
  });
257
258
  let filesToAdd = multiple ? uniqueFiles : uniqueFiles.slice(0, 1);
258
- if (maxFiles !== void 0) {
259
- const currentCount = currentFiles.length;
260
- const remainingSlots = maxFiles - currentCount;
259
+ if (remainingSlots !== void 0) {
261
260
  if (remainingSlots <= 0) {
262
- filesToAdd.forEach((file) => {
263
- addRejectedFile(file, "TOO_MANY_FILES");
264
- });
265
261
  filesToAdd = [];
266
262
  } else if (filesToAdd.length > remainingSlots) {
267
263
  filesToAdd.forEach((file) => {
268
- addRejectedFile(file, "TOO_MANY_FILES");
264
+ addRejectedFile(file, FILE_UPLOAD_ERRORS.TOO_MANY_FILES);
269
265
  });
270
266
  filesToAdd = [];
271
267
  }
@@ -298,7 +294,7 @@ var FileUpload = ({
298
294
  let updatedRejectedFiles = rejectedFiles;
299
295
  if (maxFiles !== void 0 && updated.length < maxFiles) {
300
296
  updatedRejectedFiles = rejectedFiles.filter(
301
- (rejected) => !rejected.errors.includes("TOO_MANY_FILES")
297
+ (rejected) => !rejected.errors.includes(FILE_UPLOAD_ERRORS.TOO_MANY_FILES)
302
298
  );
303
299
  setRejectedFiles(updatedRejectedFiles);
304
300
  }
@@ -317,7 +313,6 @@ var FileUpload = ({
317
313
  }
318
314
  setFiles([]);
319
315
  setRejectedFiles([]);
320
- deleteButtonRefs.current = [];
321
316
  if (onFileChange) {
322
317
  onFileChange({
323
318
  acceptedFiles: [],
@@ -335,6 +330,77 @@ var FileUpload = ({
335
330
  setRejectedFiles([]);
336
331
  };
337
332
  const maxFilesReached = maxFiles !== void 0 && files.length >= maxFiles;
333
+ return {
334
+ files,
335
+ rejectedFiles,
336
+ addFiles,
337
+ removeFile,
338
+ removeRejectedFile,
339
+ clearFiles,
340
+ clearRejectedFiles,
341
+ maxFilesReached
342
+ };
343
+ }
344
+
345
+ // src/file-upload/FileUpload.tsx
346
+ var import_jsx_runtime = require("react/jsx-runtime");
347
+ var FileUploadContext = (0, import_react3.createContext)(null);
348
+ var ID_PREFIX = ":file-upload";
349
+ var FileUpload = ({
350
+ asChild: _asChild = false,
351
+ children,
352
+ defaultValue = [],
353
+ value: controlledValue,
354
+ onFileAccept,
355
+ onFileReject,
356
+ onFileChange,
357
+ multiple = true,
358
+ accept,
359
+ maxFiles,
360
+ maxFileSize,
361
+ minFileSize,
362
+ disabled: disabledProp = false,
363
+ readOnly: readOnlyProp = false,
364
+ locale
365
+ }) => {
366
+ const field = (0, import_form_field.useFormFieldControl)();
367
+ const internalId = (0, import_react3.useId)();
368
+ const inputId = field.id || `${ID_PREFIX}-${internalId}`;
369
+ const inputName = field.name;
370
+ const inputRef = (0, import_react3.useRef)(null);
371
+ const triggerRef = (0, import_react3.useRef)(null);
372
+ const dropzoneRef = (0, import_react3.useRef)(null);
373
+ const deleteButtonRefs = (0, import_react3.useRef)([]);
374
+ const disabled = field.disabled ?? disabledProp;
375
+ const readOnly = field.readOnly ?? readOnlyProp;
376
+ const {
377
+ files,
378
+ rejectedFiles,
379
+ addFiles,
380
+ removeFile,
381
+ removeRejectedFile,
382
+ clearFiles: clearFilesFromHook,
383
+ clearRejectedFiles,
384
+ maxFilesReached
385
+ } = useFileUploadState({
386
+ defaultValue,
387
+ value: controlledValue,
388
+ onFileAccept,
389
+ onFileReject,
390
+ onFileChange,
391
+ multiple,
392
+ accept,
393
+ maxFiles,
394
+ maxFileSize,
395
+ minFileSize,
396
+ disabled,
397
+ readOnly,
398
+ locale
399
+ });
400
+ const clearFiles = () => {
401
+ clearFilesFromHook();
402
+ deleteButtonRefs.current = [];
403
+ };
338
404
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
339
405
  FileUploadContext.Provider,
340
406
  {
@@ -355,10 +421,10 @@ var FileUpload = ({
355
421
  maxFilesReached,
356
422
  disabled,
357
423
  readOnly,
358
- locale: defaultLocale,
359
- description,
360
- isInvalid,
361
- isRequired
424
+ locale: locale || (typeof navigator !== "undefined" && navigator.language ? navigator.language : "en"),
425
+ description: field.description,
426
+ isInvalid: field.isInvalid,
427
+ isRequired: field.isRequired
362
428
  },
363
429
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative", children: [
364
430
  children,
@@ -374,10 +440,10 @@ var FileUpload = ({
374
440
  accept,
375
441
  disabled,
376
442
  readOnly: readOnly && !disabled,
377
- required: isRequired,
378
- "aria-invalid": isInvalid,
379
- "aria-describedby": description,
380
- "aria-label": !labelId ? "Upload files test" : void 0,
443
+ required: field.isRequired,
444
+ "aria-invalid": field.isInvalid,
445
+ "aria-describedby": field.description,
446
+ "aria-label": !field.labelId ? "Upload files" : void 0,
381
447
  className: "sr-only",
382
448
  onChange: (e) => {
383
449
  if (e.target.files && !disabled && !readOnly) {
@@ -396,7 +462,7 @@ var FileUpload = ({
396
462
  };
397
463
  FileUpload.displayName = "FileUpload";
398
464
  var useFileUploadContext = () => {
399
- const context = (0, import_react2.useContext)(FileUploadContext);
465
+ const context = (0, import_react3.useContext)(FileUploadContext);
400
466
  if (!context) {
401
467
  throw Error("useFileUploadContext must be used within a FileUpload provider");
402
468
  }
@@ -405,13 +471,14 @@ var useFileUploadContext = () => {
405
471
 
406
472
  // src/file-upload/FileUploadAcceptedFile.tsx
407
473
  var import_class_variance_authority10 = require("class-variance-authority");
474
+ var import_react11 = require("react");
408
475
 
409
476
  // src/icon/Icon.tsx
410
- var import_react4 = require("react");
477
+ var import_react5 = require("react");
411
478
 
412
479
  // src/slot/Slot.tsx
413
480
  var import_radix_ui = require("radix-ui");
414
- var import_react3 = require("react");
481
+ var import_react4 = require("react");
415
482
  var import_jsx_runtime2 = require("react/jsx-runtime");
416
483
  var Slottable = import_radix_ui.Slot.Slottable;
417
484
  var Slot = ({ ref, ...props }) => {
@@ -419,7 +486,7 @@ var Slot = ({ ref, ...props }) => {
419
486
  };
420
487
  var wrapPolymorphicSlot = (asChild, children, callback) => {
421
488
  if (!asChild) return callback(children);
422
- return (0, import_react3.isValidElement)(children) ? (0, import_react3.cloneElement)(
489
+ return (0, import_react4.isValidElement)(children) ? (0, import_react4.cloneElement)(
423
490
  children,
424
491
  void 0,
425
492
  callback(children.props.children)
@@ -497,9 +564,9 @@ var Icon = ({
497
564
  children,
498
565
  ...others
499
566
  }) => {
500
- const child = import_react4.Children.only(children);
567
+ const child = import_react5.Children.only(children);
501
568
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
502
- (0, import_react4.cloneElement)(child, {
569
+ (0, import_react5.cloneElement)(child, {
503
570
  className: iconStyles({ className, size, intent }),
504
571
  "data-spark-component": "icon",
505
572
  "aria-hidden": "true",
@@ -514,7 +581,7 @@ Icon.displayName = "Icon";
514
581
  // src/progress/Progress.tsx
515
582
  var import_class_variance_authority4 = require("class-variance-authority");
516
583
  var import_radix_ui3 = require("radix-ui");
517
- var import_react6 = require("react");
584
+ var import_react7 = require("react");
518
585
 
519
586
  // src/progress/ProgressBar.styles.ts
520
587
  var import_class_variance_authority2 = require("class-variance-authority");
@@ -531,11 +598,11 @@ var progressBarStyles = (0, import_class_variance_authority2.cva)(
531
598
  );
532
599
 
533
600
  // src/progress/ProgressContext.tsx
534
- var import_react5 = require("react");
535
- var ProgressContext = (0, import_react5.createContext)(null);
601
+ var import_react6 = require("react");
602
+ var ProgressContext = (0, import_react6.createContext)(null);
536
603
  var ID_PREFIX2 = ":progress";
537
604
  var useProgress = () => {
538
- const context = (0, import_react5.useContext)(ProgressContext);
605
+ const context = (0, import_react6.useContext)(ProgressContext);
539
606
  if (!context) {
540
607
  throw new Error("useProgress must be used within a Progress provider");
541
608
  }
@@ -586,10 +653,17 @@ var ProgressIndicator = ({
586
653
  className,
587
654
  style,
588
655
  ref,
656
+ onTransitionEnd,
589
657
  ...others
590
658
  }) => {
591
- const { value, max, intent, shape, isIndeterminate } = useProgress();
659
+ const { value, max, intent, shape, isIndeterminate, onComplete } = useProgress();
592
660
  const x = (max - value) / max * 100;
661
+ const handleTransitionEnd = (event) => {
662
+ onTransitionEnd?.(event);
663
+ if (value >= max && onComplete && !isIndeterminate) {
664
+ onComplete();
665
+ }
666
+ };
593
667
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
594
668
  import_radix_ui2.Progress.ProgressIndicator,
595
669
  {
@@ -597,6 +671,7 @@ var ProgressIndicator = ({
597
671
  className: progressIndicatorStyles({ className, intent, shape, isIndeterminate }),
598
672
  style: { ...style, ...!isIndeterminate && { transform: `translateX(-${x}%)` } },
599
673
  ref,
674
+ onTransitionEnd: handleTransitionEnd,
600
675
  ...others
601
676
  }
602
677
  );
@@ -634,14 +709,23 @@ var Progress = ({
634
709
  shape = "square",
635
710
  intent = "basic",
636
711
  isIndeterminate = false,
712
+ onComplete,
637
713
  children = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProgressBar, {}),
638
714
  ref,
639
715
  ...others
640
716
  }) => {
641
- const [labelId, setLabelId] = (0, import_react6.useState)();
642
- const value = (0, import_react6.useMemo)(() => {
643
- return { value: valueProp ?? 0, max, intent, shape, isIndeterminate, onLabelId: setLabelId };
644
- }, [max, valueProp, intent, shape, isIndeterminate, setLabelId]);
717
+ const [labelId, setLabelId] = (0, import_react7.useState)();
718
+ const value = (0, import_react7.useMemo)(() => {
719
+ return {
720
+ value: valueProp ?? 0,
721
+ max,
722
+ intent,
723
+ shape,
724
+ isIndeterminate,
725
+ onLabelId: setLabelId,
726
+ onComplete
727
+ };
728
+ }, [max, valueProp, intent, shape, isIndeterminate, setLabelId, onComplete]);
645
729
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProgressContext.Provider, { "data-spark-component": "progress", value, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
646
730
  import_radix_ui3.Progress.Progress,
647
731
  {
@@ -661,7 +745,7 @@ Progress.displayName = "Progress";
661
745
 
662
746
  // src/progress/ProgressLabel.tsx
663
747
  var import_use_merge_refs = require("@spark-ui/hooks/use-merge-refs");
664
- var import_react7 = require("react");
748
+ var import_react8 = require("react");
665
749
  var import_jsx_runtime8 = require("react/jsx-runtime");
666
750
  var ProgressLabel = ({
667
751
  id: idProp,
@@ -669,10 +753,10 @@ var ProgressLabel = ({
669
753
  ref: forwardedRef,
670
754
  ...others
671
755
  }) => {
672
- const internalID = `${ID_PREFIX2}-label-${(0, import_react7.useId)()}`;
756
+ const internalID = `${ID_PREFIX2}-label-${(0, import_react8.useId)()}`;
673
757
  const id = idProp || internalID;
674
758
  const { onLabelId } = useProgress();
675
- const rootRef = (0, import_react7.useCallback)(
759
+ const rootRef = (0, import_react8.useCallback)(
676
760
  (el) => {
677
761
  onLabelId(el ? id : void 0);
678
762
  },
@@ -707,11 +791,11 @@ ProgressLabel.displayName = "Progress.Label";
707
791
  // src/file-upload/FileUploadItemDeleteTrigger.tsx
708
792
  var import_Close = require("@spark-ui/icons/Close");
709
793
  var import_class_variance_authority9 = require("class-variance-authority");
710
- var import_react9 = require("react");
794
+ var import_react10 = require("react");
711
795
 
712
796
  // src/button/Button.tsx
713
797
  var import_class_variance_authority7 = require("class-variance-authority");
714
- var import_react8 = require("react");
798
+ var import_react9 = require("react");
715
799
 
716
800
  // src/spinner/Spinner.styles.tsx
717
801
  var import_internal_utils2 = require("@spark-ui/internal-utils");
@@ -1516,7 +1600,7 @@ var Button = ({
1516
1600
  }) => {
1517
1601
  const Component = asChild ? Slot : "button";
1518
1602
  const shouldNotInteract = !!disabled || isLoading;
1519
- const disabledEventHandlers = (0, import_react8.useMemo)(() => {
1603
+ const disabledEventHandlers = (0, import_react9.useMemo)(() => {
1520
1604
  const result = {};
1521
1605
  if (shouldNotInteract) {
1522
1606
  blockedEventHandlers.forEach((eventHandler) => result[eventHandler] = void 0);
@@ -1623,14 +1707,14 @@ var ItemDeleteTrigger = ({
1623
1707
  ...props
1624
1708
  }) => {
1625
1709
  const { removeFile, triggerRef, dropzoneRef, deleteButtonRefs, disabled, readOnly, files } = useFileUploadContext();
1626
- const buttonRef = (0, import_react9.useRef)(null);
1710
+ const buttonRef = (0, import_react10.useRef)(null);
1627
1711
  const fileIndex = files.findIndex((f) => f.name === file.name && f.size === file.size);
1628
1712
  const handleClick = (e) => {
1629
1713
  if (disabled || readOnly) {
1630
1714
  return;
1631
1715
  }
1632
1716
  removeFile(fileIndex);
1633
- setTimeout(() => {
1717
+ requestAnimationFrame(() => {
1634
1718
  const remainingButtons = deleteButtonRefs.current.filter(Boolean);
1635
1719
  if (remainingButtons.length > 0) {
1636
1720
  const targetIndex = Math.min(fileIndex, remainingButtons.length - 1);
@@ -1644,7 +1728,7 @@ var ItemDeleteTrigger = ({
1644
1728
  focusTarget.focus();
1645
1729
  }
1646
1730
  }
1647
- }, 0);
1731
+ });
1648
1732
  onClick?.(e);
1649
1733
  };
1650
1734
  const setRef = (node) => {
@@ -1681,7 +1765,6 @@ ItemDeleteTrigger.displayName = "FileUpload.ItemDeleteTrigger";
1681
1765
  // src/file-upload/FileUploadAcceptedFile.tsx
1682
1766
  var import_jsx_runtime13 = require("react/jsx-runtime");
1683
1767
  var AcceptedFile = ({
1684
- asChild: _asChild = false,
1685
1768
  className,
1686
1769
  file,
1687
1770
  uploadProgress,
@@ -1690,6 +1773,17 @@ var AcceptedFile = ({
1690
1773
  ...props
1691
1774
  }) => {
1692
1775
  const { locale } = useFileUploadContext();
1776
+ const [showProgress, setShowProgress] = (0, import_react11.useState)(uploadProgress !== void 0);
1777
+ (0, import_react11.useEffect)(() => {
1778
+ if (uploadProgress !== void 0) {
1779
+ setShowProgress(true);
1780
+ } else {
1781
+ setShowProgress(false);
1782
+ }
1783
+ }, [uploadProgress]);
1784
+ const handleProgressComplete = (0, import_react11.useCallback)(() => {
1785
+ setShowProgress(false);
1786
+ }, []);
1693
1787
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1694
1788
  "li",
1695
1789
  {
@@ -1702,13 +1796,19 @@ var AcceptedFile = ({
1702
1796
  ),
1703
1797
  ...props,
1704
1798
  children: [
1705
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "size-sz-40 bg-support-container flex items-center justify-center rounded-md", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { size: "md", children: getFileIcon(file) }) }),
1706
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "min-w-0 flex-1", children: [
1707
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "gap-md flex flex-row items-center justify-between", children: [
1708
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-body-2 truncate font-medium", children: file.name }),
1709
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-caption opacity-dim-1", children: formatFileSize(file.size, locale) })
1710
- ] }),
1711
- uploadProgress !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "mt-md", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Progress2, { value: uploadProgress, max: 100, "aria-label": progressAriaLabel }) })
1799
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "size-sz-36 bg-support-container flex items-center justify-center rounded-md", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { size: "md", children: getFileIcon(file) }) }),
1800
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "gap-md relative flex min-w-0 flex-1 flex-row items-center justify-between self-stretch", children: [
1801
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-body-2 truncate font-medium", children: file.name }),
1802
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-caption opacity-dim-1", children: formatFileSize(file.size, locale) }),
1803
+ showProgress && uploadProgress !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "absolute bottom-0 left-0 w-full", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1804
+ Progress2,
1805
+ {
1806
+ value: uploadProgress,
1807
+ max: 100,
1808
+ "aria-label": progressAriaLabel,
1809
+ onComplete: handleProgressComplete
1810
+ }
1811
+ ) })
1712
1812
  ] }),
1713
1813
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ItemDeleteTrigger, { "aria-label": deleteButtonAriaLabel, file })
1714
1814
  ]
@@ -1732,17 +1832,17 @@ Context.displayName = "FileUpload.Context";
1732
1832
 
1733
1833
  // src/file-upload/FileUploadDropzone.tsx
1734
1834
  var import_class_variance_authority11 = require("class-variance-authority");
1735
- var import_react10 = require("react");
1835
+ var import_react12 = require("react");
1736
1836
  var import_jsx_runtime15 = require("react/jsx-runtime");
1737
- var DropzoneContext = (0, import_react10.createContext)(false);
1738
- var useDropzoneContext = () => (0, import_react10.useContext)(DropzoneContext);
1837
+ var DropzoneContext = (0, import_react12.createContext)(false);
1838
+ var useDropzoneContext = () => (0, import_react12.useContext)(DropzoneContext);
1739
1839
  function Dropzone({
1740
1840
  children,
1741
1841
  className,
1742
1842
  unstyled = false
1743
1843
  }) {
1744
1844
  const ctx = useFileUploadContext();
1745
- const dropzoneRef = (0, import_react10.useRef)(null);
1845
+ const dropzoneRef = (0, import_react12.useRef)(null);
1746
1846
  if (!ctx) throw new Error("FileUploadDropzone must be used inside <FileUpload>");
1747
1847
  const handleDrop = (e) => {
1748
1848
  e.preventDefault();
@@ -1824,20 +1924,19 @@ Dropzone.displayName = "FileUploadDropzone";
1824
1924
 
1825
1925
  // src/file-upload/FileUploadPreviewImage.tsx
1826
1926
  var import_class_variance_authority12 = require("class-variance-authority");
1827
- var import_react11 = require("react");
1927
+ var import_react13 = require("react");
1828
1928
  var import_jsx_runtime16 = require("react/jsx-runtime");
1829
1929
  var PreviewImage = ({
1830
- asChild: _asChild = false,
1831
1930
  className,
1832
1931
  file,
1833
1932
  fallback = "\u{1F4C4}",
1834
1933
  ...props
1835
1934
  }) => {
1836
- const [imageError, setImageError] = (0, import_react11.useState)(false);
1837
- const [imageLoaded, setImageLoaded] = (0, import_react11.useState)(false);
1935
+ const [imageError, setImageError] = (0, import_react13.useState)(false);
1936
+ const [imageLoaded, setImageLoaded] = (0, import_react13.useState)(false);
1838
1937
  const isImage = file.type.startsWith("image/");
1839
1938
  const imageUrl = isImage ? URL.createObjectURL(file) : null;
1840
- (0, import_react11.useEffect)(() => {
1939
+ (0, import_react13.useEffect)(() => {
1841
1940
  return () => {
1842
1941
  if (imageUrl) {
1843
1942
  URL.revokeObjectURL(imageUrl);
@@ -1889,7 +1988,7 @@ var import_class_variance_authority14 = require("class-variance-authority");
1889
1988
  // src/file-upload/FileUploadRejectedFileDeleteTrigger.tsx
1890
1989
  var import_Close2 = require("@spark-ui/icons/Close");
1891
1990
  var import_class_variance_authority13 = require("class-variance-authority");
1892
- var import_react12 = require("react");
1991
+ var import_react14 = require("react");
1893
1992
  var import_jsx_runtime17 = require("react/jsx-runtime");
1894
1993
  var RejectedFileDeleteTrigger = ({
1895
1994
  className,
@@ -1898,7 +1997,7 @@ var RejectedFileDeleteTrigger = ({
1898
1997
  ...props
1899
1998
  }) => {
1900
1999
  const { removeRejectedFile, triggerRef, dropzoneRef, disabled, readOnly, rejectedFiles } = useFileUploadContext();
1901
- const buttonRef = (0, import_react12.useRef)(null);
2000
+ const buttonRef = (0, import_react14.useRef)(null);
1902
2001
  const rejectedFileIndex = rejectedFiles.findIndex(
1903
2002
  (rf) => rf.file.name === rejectedFile.file.name && rf.file.size === rejectedFile.file.size
1904
2003
  );
@@ -1936,7 +2035,6 @@ RejectedFileDeleteTrigger.displayName = "FileUpload.RejectedFileDeleteTrigger";
1936
2035
  // src/file-upload/FileUploadRejectedFile.tsx
1937
2036
  var import_jsx_runtime18 = require("react/jsx-runtime");
1938
2037
  var RejectedFile = ({
1939
- asChild: _asChild = false,
1940
2038
  className,
1941
2039
  rejectedFile,
1942
2040
  renderError,
@@ -1957,7 +2055,7 @@ var RejectedFile = ({
1957
2055
  ),
1958
2056
  ...props,
1959
2057
  children: [
1960
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "size-sz-40 bg-error-container flex items-center justify-center rounded-md", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { size: "md", className: "text-error", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_WarningOutline.WarningOutline, {}) }) }),
2058
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "size-sz-36 bg-error-container flex items-center justify-center rounded-md", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { size: "md", className: "text-error", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_WarningOutline.WarningOutline, {}) }) }),
1961
2059
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "gap-md flex flex-col", children: [
1962
2060
  /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "gap-md flex flex-row items-center justify-between", children: [
1963
2061
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-body-2 truncate font-medium", children: rejectedFile.file.name }),
@@ -2076,6 +2174,7 @@ RejectedFile.displayName = "FileUpload.RejectedFile";
2076
2174
  RejectedFileDeleteTrigger.displayName = "FileUpload.RejectedFileDeleteTrigger";
2077
2175
  // Annotate the CommonJS export names for ESM import in node:
2078
2176
  0 && (module.exports = {
2177
+ FILE_UPLOAD_ERRORS,
2079
2178
  FileUpload
2080
2179
  });
2081
2180
  //# sourceMappingURL=index.js.map