@spark-ui/components 11.4.2 → 11.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/checkbox/index.js.map +1 -1
- package/dist/checkbox/index.mjs.map +1 -1
- package/dist/chip/index.js.map +1 -1
- package/dist/chip/index.mjs.map +1 -1
- package/dist/docgen.json +42 -303
- package/dist/file-upload/index.d.mts +35 -79
- package/dist/file-upload/index.d.ts +35 -79
- package/dist/file-upload/index.js +186 -187
- package/dist/file-upload/index.js.map +1 -1
- package/dist/file-upload/index.mjs +165 -166
- package/dist/file-upload/index.mjs.map +1 -1
- package/package.json +5 -5
|
@@ -17,8 +17,9 @@ import {
|
|
|
17
17
|
} from "../chunk-6QCEPQ3U.mjs";
|
|
18
18
|
|
|
19
19
|
// src/file-upload/FileUpload.tsx
|
|
20
|
+
import { useFormFieldControl } from "@spark-ui/components/form-field";
|
|
20
21
|
import { useCombinedState } from "@spark-ui/hooks/use-combined-state";
|
|
21
|
-
import { createContext, useContext, useRef, useState } from "react";
|
|
22
|
+
import { createContext, useContext, useId, useRef, useState } from "react";
|
|
22
23
|
|
|
23
24
|
// src/file-upload/utils.ts
|
|
24
25
|
import { CvOutline } from "@spark-ui/icons/CvOutline";
|
|
@@ -122,33 +123,45 @@ function getFileIcon(file) {
|
|
|
122
123
|
// src/file-upload/FileUpload.tsx
|
|
123
124
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
124
125
|
var FileUploadContext = createContext(null);
|
|
126
|
+
var ID_PREFIX = ":file-upload";
|
|
125
127
|
var FileUpload = ({
|
|
126
128
|
asChild: _asChild = false,
|
|
127
129
|
children,
|
|
128
130
|
defaultValue = [],
|
|
129
131
|
value: controlledValue,
|
|
130
|
-
|
|
132
|
+
onFileAccept,
|
|
133
|
+
onFileReject,
|
|
134
|
+
onFileChange,
|
|
131
135
|
multiple = true,
|
|
132
136
|
accept,
|
|
133
137
|
maxFiles,
|
|
134
|
-
onMaxFilesReached,
|
|
135
138
|
maxFileSize,
|
|
136
139
|
minFileSize,
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
readOnly = false,
|
|
140
|
+
disabled: disabledProp = false,
|
|
141
|
+
readOnly: readOnlyProp = false,
|
|
140
142
|
locale
|
|
141
143
|
}) => {
|
|
144
|
+
const field = useFormFieldControl();
|
|
145
|
+
const {
|
|
146
|
+
id: fieldId,
|
|
147
|
+
name: fieldName,
|
|
148
|
+
isInvalid,
|
|
149
|
+
isRequired,
|
|
150
|
+
description,
|
|
151
|
+
disabled: fieldDisabled,
|
|
152
|
+
readOnly: fieldReadOnly
|
|
153
|
+
} = field;
|
|
142
154
|
const defaultLocale = locale || (typeof navigator !== "undefined" && navigator.language ? navigator.language : "en");
|
|
155
|
+
const internalId = useId();
|
|
156
|
+
const inputId = fieldId || `${ID_PREFIX}-${internalId}`;
|
|
157
|
+
const inputName = fieldName;
|
|
143
158
|
const inputRef = useRef(null);
|
|
144
159
|
const triggerRef = useRef(null);
|
|
145
160
|
const dropzoneRef = useRef(null);
|
|
146
161
|
const deleteButtonRefs = useRef([]);
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
onFilesChange
|
|
151
|
-
);
|
|
162
|
+
const disabled = fieldDisabled ?? disabledProp;
|
|
163
|
+
const readOnly = fieldReadOnly ?? readOnlyProp;
|
|
164
|
+
const [filesState, setFilesState, ,] = useCombinedState(controlledValue, defaultValue);
|
|
152
165
|
const files = filesState ?? [];
|
|
153
166
|
const setFiles = setFilesState;
|
|
154
167
|
const [rejectedFiles, setRejectedFiles] = useState([]);
|
|
@@ -177,9 +190,6 @@ var FileUpload = ({
|
|
|
177
190
|
errors: [error]
|
|
178
191
|
});
|
|
179
192
|
}
|
|
180
|
-
if (onFileSizeError) {
|
|
181
|
-
onFileSizeError(file, error);
|
|
182
|
-
}
|
|
183
193
|
};
|
|
184
194
|
setFiles((prev) => {
|
|
185
195
|
const currentFiles = prev ?? [];
|
|
@@ -243,19 +253,29 @@ var FileUpload = ({
|
|
|
243
253
|
filesToAdd.forEach((file) => {
|
|
244
254
|
addRejectedFile(file, "TOO_MANY_FILES");
|
|
245
255
|
});
|
|
246
|
-
onMaxFilesReached?.(maxFiles, filesToAdd.length);
|
|
247
256
|
filesToAdd = [];
|
|
248
257
|
} else if (filesToAdd.length > remainingSlots) {
|
|
249
258
|
filesToAdd.forEach((file) => {
|
|
250
259
|
addRejectedFile(file, "TOO_MANY_FILES");
|
|
251
260
|
});
|
|
252
|
-
onMaxFilesReached?.(maxFiles, filesToAdd.length);
|
|
253
261
|
filesToAdd = [];
|
|
254
262
|
}
|
|
255
263
|
}
|
|
256
264
|
const updated = multiple ? [...currentFiles, ...filesToAdd] : filesToAdd;
|
|
257
265
|
const rejectedFilesToAdd = [...newRejectedFiles];
|
|
258
266
|
setRejectedFiles(rejectedFilesToAdd);
|
|
267
|
+
if (filesToAdd.length > 0 && onFileAccept) {
|
|
268
|
+
onFileAccept({ files: filesToAdd });
|
|
269
|
+
}
|
|
270
|
+
if (rejectedFilesToAdd.length > 0 && onFileReject) {
|
|
271
|
+
onFileReject({ files: rejectedFilesToAdd });
|
|
272
|
+
}
|
|
273
|
+
if (onFileChange) {
|
|
274
|
+
onFileChange({
|
|
275
|
+
acceptedFiles: updated,
|
|
276
|
+
rejectedFiles: rejectedFilesToAdd
|
|
277
|
+
});
|
|
278
|
+
}
|
|
259
279
|
return updated;
|
|
260
280
|
});
|
|
261
281
|
};
|
|
@@ -266,10 +286,18 @@ var FileUpload = ({
|
|
|
266
286
|
setFiles((prev) => {
|
|
267
287
|
const currentFiles = prev ?? [];
|
|
268
288
|
const updated = currentFiles.filter((_, i) => i !== index);
|
|
289
|
+
let updatedRejectedFiles = rejectedFiles;
|
|
269
290
|
if (maxFiles !== void 0 && updated.length < maxFiles) {
|
|
270
|
-
|
|
271
|
-
(
|
|
291
|
+
updatedRejectedFiles = rejectedFiles.filter(
|
|
292
|
+
(rejected) => !rejected.errors.includes("TOO_MANY_FILES")
|
|
272
293
|
);
|
|
294
|
+
setRejectedFiles(updatedRejectedFiles);
|
|
295
|
+
}
|
|
296
|
+
if (onFileChange) {
|
|
297
|
+
onFileChange({
|
|
298
|
+
acceptedFiles: updated,
|
|
299
|
+
rejectedFiles: updatedRejectedFiles
|
|
300
|
+
});
|
|
273
301
|
}
|
|
274
302
|
return updated;
|
|
275
303
|
});
|
|
@@ -281,6 +309,12 @@ var FileUpload = ({
|
|
|
281
309
|
setFiles([]);
|
|
282
310
|
setRejectedFiles([]);
|
|
283
311
|
deleteButtonRefs.current = [];
|
|
312
|
+
if (onFileChange) {
|
|
313
|
+
onFileChange({
|
|
314
|
+
acceptedFiles: [],
|
|
315
|
+
rejectedFiles: []
|
|
316
|
+
});
|
|
317
|
+
}
|
|
284
318
|
};
|
|
285
319
|
const removeRejectedFile = (index) => {
|
|
286
320
|
if (disabled || readOnly) {
|
|
@@ -312,7 +346,10 @@ var FileUpload = ({
|
|
|
312
346
|
maxFilesReached,
|
|
313
347
|
disabled,
|
|
314
348
|
readOnly,
|
|
315
|
-
locale: defaultLocale
|
|
349
|
+
locale: defaultLocale,
|
|
350
|
+
description,
|
|
351
|
+
isInvalid,
|
|
352
|
+
isRequired
|
|
316
353
|
},
|
|
317
354
|
children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
318
355
|
children,
|
|
@@ -322,12 +359,15 @@ var FileUpload = ({
|
|
|
322
359
|
ref: inputRef,
|
|
323
360
|
type: "file",
|
|
324
361
|
tabIndex: -1,
|
|
325
|
-
id:
|
|
362
|
+
id: inputId,
|
|
326
363
|
multiple,
|
|
327
|
-
name:
|
|
364
|
+
name: inputName,
|
|
328
365
|
accept,
|
|
329
366
|
disabled,
|
|
330
367
|
readOnly: readOnly && !disabled,
|
|
368
|
+
required: isRequired,
|
|
369
|
+
"aria-invalid": isInvalid,
|
|
370
|
+
"aria-describedby": description,
|
|
331
371
|
className: "sr-only",
|
|
332
372
|
onChange: (e) => {
|
|
333
373
|
if (e.target.files && !disabled && !readOnly) {
|
|
@@ -353,45 +393,23 @@ var useFileUploadContext = () => {
|
|
|
353
393
|
return context;
|
|
354
394
|
};
|
|
355
395
|
|
|
356
|
-
// src/file-upload/
|
|
357
|
-
import { cx } from "class-variance-authority";
|
|
358
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
359
|
-
var Item = ({
|
|
360
|
-
asChild: _asChild = false,
|
|
361
|
-
className,
|
|
362
|
-
children,
|
|
363
|
-
...props
|
|
364
|
-
}) => {
|
|
365
|
-
return /* @__PURE__ */ jsx2(
|
|
366
|
-
"li",
|
|
367
|
-
{
|
|
368
|
-
"data-spark-component": "file-upload-item",
|
|
369
|
-
className: cx(
|
|
370
|
-
"relative",
|
|
371
|
-
"default:bg-surface default:border-sm default:border-outline default:p-md default:rounded-md",
|
|
372
|
-
"gap-md flex items-center justify-between default:w-full",
|
|
373
|
-
className
|
|
374
|
-
),
|
|
375
|
-
...props,
|
|
376
|
-
children
|
|
377
|
-
}
|
|
378
|
-
);
|
|
379
|
-
};
|
|
380
|
-
Item.displayName = "FileUpload.Item";
|
|
396
|
+
// src/file-upload/FileUploadAcceptedFile.tsx
|
|
397
|
+
import { cx as cx2 } from "class-variance-authority";
|
|
381
398
|
|
|
382
399
|
// src/file-upload/FileUploadItemDeleteTrigger.tsx
|
|
383
400
|
import { Close } from "@spark-ui/icons/Close";
|
|
384
|
-
import { cx
|
|
401
|
+
import { cx } from "class-variance-authority";
|
|
385
402
|
import { useRef as useRef2 } from "react";
|
|
386
|
-
import { jsx as
|
|
403
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
387
404
|
var ItemDeleteTrigger = ({
|
|
388
405
|
className,
|
|
389
|
-
|
|
406
|
+
file,
|
|
390
407
|
onClick,
|
|
391
408
|
...props
|
|
392
409
|
}) => {
|
|
393
|
-
const { removeFile, triggerRef, dropzoneRef, deleteButtonRefs, disabled, readOnly } = useFileUploadContext();
|
|
410
|
+
const { removeFile, triggerRef, dropzoneRef, deleteButtonRefs, disabled, readOnly, files } = useFileUploadContext();
|
|
394
411
|
const buttonRef = useRef2(null);
|
|
412
|
+
const fileIndex = files.findIndex((f) => f.name === file.name && f.size === file.size);
|
|
395
413
|
const handleClick = (e) => {
|
|
396
414
|
if (disabled || readOnly) {
|
|
397
415
|
return;
|
|
@@ -427,98 +445,68 @@ var ItemDeleteTrigger = ({
|
|
|
427
445
|
}
|
|
428
446
|
}
|
|
429
447
|
};
|
|
430
|
-
return /* @__PURE__ */
|
|
448
|
+
return /* @__PURE__ */ jsx2(
|
|
431
449
|
IconButton,
|
|
432
450
|
{
|
|
433
451
|
ref: setRef,
|
|
434
452
|
"data-spark-component": "file-upload-item-delete-trigger",
|
|
435
|
-
className:
|
|
453
|
+
className: cx(className),
|
|
436
454
|
onClick: handleClick,
|
|
437
455
|
disabled: disabled || readOnly,
|
|
438
456
|
size: "sm",
|
|
439
457
|
design: "contrast",
|
|
440
458
|
intent: "surface",
|
|
441
459
|
...props,
|
|
442
|
-
children: /* @__PURE__ */
|
|
460
|
+
children: /* @__PURE__ */ jsx2(Icon, { size: "sm", children: /* @__PURE__ */ jsx2(Close, {}) })
|
|
443
461
|
}
|
|
444
462
|
);
|
|
445
463
|
};
|
|
446
464
|
ItemDeleteTrigger.displayName = "FileUpload.ItemDeleteTrigger";
|
|
447
465
|
|
|
448
|
-
// src/file-upload/FileUploadItemFileName.tsx
|
|
449
|
-
import { cx as cx3 } from "class-variance-authority";
|
|
450
|
-
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
451
|
-
var ItemFileName = ({
|
|
452
|
-
asChild: _asChild = false,
|
|
453
|
-
className,
|
|
454
|
-
children,
|
|
455
|
-
...props
|
|
456
|
-
}) => {
|
|
457
|
-
return /* @__PURE__ */ jsx4(
|
|
458
|
-
"p",
|
|
459
|
-
{
|
|
460
|
-
"data-spark-component": "file-upload-item-file-name",
|
|
461
|
-
className: cx3("text-body-2 truncate font-medium", className),
|
|
462
|
-
...props,
|
|
463
|
-
children
|
|
464
|
-
}
|
|
465
|
-
);
|
|
466
|
-
};
|
|
467
|
-
ItemFileName.displayName = "FileUpload.ItemFileName";
|
|
468
|
-
|
|
469
|
-
// src/file-upload/FileUploadItemSizeText.tsx
|
|
470
|
-
import { cx as cx4 } from "class-variance-authority";
|
|
471
|
-
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
472
|
-
var ItemSizeText = ({
|
|
473
|
-
asChild: _asChild = false,
|
|
474
|
-
className,
|
|
475
|
-
children,
|
|
476
|
-
...props
|
|
477
|
-
}) => {
|
|
478
|
-
return /* @__PURE__ */ jsx5(
|
|
479
|
-
"p",
|
|
480
|
-
{
|
|
481
|
-
"data-spark-component": "file-upload-item-size-text",
|
|
482
|
-
className: cx4("text-caption", className),
|
|
483
|
-
...props,
|
|
484
|
-
children
|
|
485
|
-
}
|
|
486
|
-
);
|
|
487
|
-
};
|
|
488
|
-
ItemSizeText.displayName = "FileUpload.ItemSizeText";
|
|
489
|
-
|
|
490
466
|
// src/file-upload/FileUploadAcceptedFile.tsx
|
|
491
|
-
import { jsx as
|
|
467
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
492
468
|
var AcceptedFile = ({
|
|
493
469
|
asChild: _asChild = false,
|
|
494
470
|
className,
|
|
495
471
|
file,
|
|
496
|
-
fileIndex,
|
|
497
472
|
uploadProgress,
|
|
498
473
|
deleteButtonAriaLabel,
|
|
499
474
|
progressAriaLabel,
|
|
500
475
|
...props
|
|
501
476
|
}) => {
|
|
502
477
|
const { locale } = useFileUploadContext();
|
|
503
|
-
return /* @__PURE__ */ jsxs2(
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
478
|
+
return /* @__PURE__ */ jsxs2(
|
|
479
|
+
"li",
|
|
480
|
+
{
|
|
481
|
+
"data-spark-component": "file-upload-accepted-file",
|
|
482
|
+
className: cx2(
|
|
483
|
+
"relative",
|
|
484
|
+
"default:bg-surface default:border-sm default:border-outline default:p-md default:rounded-md",
|
|
485
|
+
"gap-md flex items-center justify-between default:w-full",
|
|
486
|
+
className
|
|
487
|
+
),
|
|
488
|
+
...props,
|
|
489
|
+
children: [
|
|
490
|
+
/* @__PURE__ */ jsx3("div", { className: "size-sz-40 bg-support-container flex items-center justify-center rounded-md", children: /* @__PURE__ */ jsx3(Icon, { size: "md", children: getFileIcon(file) }) }),
|
|
491
|
+
/* @__PURE__ */ jsxs2("div", { className: "min-w-0 flex-1", children: [
|
|
492
|
+
/* @__PURE__ */ jsxs2("div", { className: "gap-md flex flex-row items-center justify-between", children: [
|
|
493
|
+
/* @__PURE__ */ jsx3("p", { className: "text-body-2 truncate font-medium", children: file.name }),
|
|
494
|
+
/* @__PURE__ */ jsx3("p", { className: "text-caption opacity-dim-1", children: formatFileSize(file.size, locale) })
|
|
495
|
+
] }),
|
|
496
|
+
uploadProgress !== void 0 && /* @__PURE__ */ jsx3("div", { className: "mt-md", children: /* @__PURE__ */ jsx3(Progress, { value: uploadProgress, max: 100, "aria-label": progressAriaLabel }) })
|
|
497
|
+
] }),
|
|
498
|
+
/* @__PURE__ */ jsx3(ItemDeleteTrigger, { "aria-label": deleteButtonAriaLabel, file })
|
|
499
|
+
]
|
|
500
|
+
}
|
|
501
|
+
);
|
|
514
502
|
};
|
|
515
503
|
AcceptedFile.displayName = "FileUpload.AcceptedFile";
|
|
516
504
|
|
|
517
505
|
// src/file-upload/FileUploadContext.tsx
|
|
518
|
-
import { Fragment, jsx as
|
|
506
|
+
import { Fragment, jsx as jsx4 } from "react/jsx-runtime";
|
|
519
507
|
var Context = ({ children }) => {
|
|
520
508
|
const { files = [], rejectedFiles = [], locale } = useFileUploadContext();
|
|
521
|
-
return /* @__PURE__ */
|
|
509
|
+
return /* @__PURE__ */ jsx4(Fragment, { children: children({
|
|
522
510
|
acceptedFiles: files,
|
|
523
511
|
rejectedFiles,
|
|
524
512
|
formatFileSize,
|
|
@@ -528,12 +516,11 @@ var Context = ({ children }) => {
|
|
|
528
516
|
Context.displayName = "FileUpload.Context";
|
|
529
517
|
|
|
530
518
|
// src/file-upload/FileUploadDropzone.tsx
|
|
531
|
-
import { cx as
|
|
519
|
+
import { cx as cx3 } from "class-variance-authority";
|
|
532
520
|
import { useRef as useRef3 } from "react";
|
|
533
|
-
import { jsx as
|
|
521
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
534
522
|
function Dropzone({
|
|
535
523
|
children,
|
|
536
|
-
onFiles,
|
|
537
524
|
className,
|
|
538
525
|
unstyled = false
|
|
539
526
|
}) {
|
|
@@ -548,7 +535,6 @@ function Dropzone({
|
|
|
548
535
|
return;
|
|
549
536
|
}
|
|
550
537
|
const files = e.dataTransfer.files;
|
|
551
|
-
onFiles?.(files);
|
|
552
538
|
let filesArray = [];
|
|
553
539
|
if (files) {
|
|
554
540
|
filesArray = Array.isArray(files) ? [...files] : Array.from(files);
|
|
@@ -571,7 +557,7 @@ function Dropzone({
|
|
|
571
557
|
}
|
|
572
558
|
};
|
|
573
559
|
const isDisabled = ctx.disabled || ctx.readOnly;
|
|
574
|
-
return /* @__PURE__ */
|
|
560
|
+
return /* @__PURE__ */ jsx5(
|
|
575
561
|
"div",
|
|
576
562
|
{
|
|
577
563
|
ref: (node) => {
|
|
@@ -583,18 +569,21 @@ function Dropzone({
|
|
|
583
569
|
role: "button",
|
|
584
570
|
tabIndex: isDisabled ? -1 : 0,
|
|
585
571
|
"aria-disabled": ctx.disabled ? true : void 0,
|
|
572
|
+
"aria-describedby": ctx.description,
|
|
573
|
+
"aria-invalid": ctx.isInvalid,
|
|
574
|
+
"aria-required": ctx.isRequired,
|
|
586
575
|
onClick: handleClick,
|
|
587
576
|
onKeyDown: handleKeyDown,
|
|
588
577
|
onDrop: handleDrop,
|
|
589
578
|
onDragOver: (e) => {
|
|
590
579
|
e.preventDefault();
|
|
591
580
|
},
|
|
592
|
-
className: unstyled ? className :
|
|
593
|
-
"default:bg-surface default:border-sm default:border-outline default:rounded-lg default:border-dashed",
|
|
581
|
+
className: unstyled ? className : cx3(
|
|
582
|
+
"default:bg-surface default:border-sm default:border-outline default:relative default:rounded-lg default:border-dashed",
|
|
594
583
|
"gap-lg flex flex-col items-center justify-center text-center",
|
|
595
584
|
"default:p-xl",
|
|
596
585
|
"transition-colors duration-200",
|
|
597
|
-
!isDisabled && "hover:bg-surface-hovered",
|
|
586
|
+
!isDisabled && "default:hover:bg-surface-hovered",
|
|
598
587
|
"data-[drag-over=true]:border-outline-high data-[drag-over=true]:bg-surface-hovered data-[drag-over=true]:border-solid",
|
|
599
588
|
// Disabled: more visually disabled (opacity + cursor)
|
|
600
589
|
ctx.disabled && "cursor-not-allowed opacity-50",
|
|
@@ -617,9 +606,9 @@ function Dropzone({
|
|
|
617
606
|
Dropzone.displayName = "FileUploadDropzone";
|
|
618
607
|
|
|
619
608
|
// src/file-upload/FileUploadPreviewImage.tsx
|
|
620
|
-
import { cx as
|
|
609
|
+
import { cx as cx4 } from "class-variance-authority";
|
|
621
610
|
import { useEffect, useState as useState2 } from "react";
|
|
622
|
-
import { jsx as
|
|
611
|
+
import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
623
612
|
var PreviewImage = ({
|
|
624
613
|
asChild: _asChild = false,
|
|
625
614
|
className,
|
|
@@ -639,11 +628,11 @@ var PreviewImage = ({
|
|
|
639
628
|
};
|
|
640
629
|
}, [imageUrl]);
|
|
641
630
|
if (!isImage || imageError) {
|
|
642
|
-
return /* @__PURE__ */
|
|
631
|
+
return /* @__PURE__ */ jsx6(
|
|
643
632
|
"div",
|
|
644
633
|
{
|
|
645
634
|
"data-spark-component": "file-upload-preview-image",
|
|
646
|
-
className:
|
|
635
|
+
className: cx4(
|
|
647
636
|
"bg-neutral-container flex items-center justify-center rounded-md",
|
|
648
637
|
className
|
|
649
638
|
),
|
|
@@ -656,20 +645,20 @@ var PreviewImage = ({
|
|
|
656
645
|
"div",
|
|
657
646
|
{
|
|
658
647
|
"data-spark-component": "file-upload-preview-image",
|
|
659
|
-
className:
|
|
648
|
+
className: cx4("bg-neutral-container overflow-hidden", className),
|
|
660
649
|
...props,
|
|
661
650
|
children: [
|
|
662
|
-
/* @__PURE__ */
|
|
651
|
+
/* @__PURE__ */ jsx6(
|
|
663
652
|
"img",
|
|
664
653
|
{
|
|
665
654
|
src: imageUrl,
|
|
666
655
|
alt: file.name,
|
|
667
|
-
className:
|
|
656
|
+
className: cx4("size-full object-cover", !imageLoaded && "opacity-0"),
|
|
668
657
|
onLoad: () => setImageLoaded(true),
|
|
669
658
|
onError: () => setImageError(true)
|
|
670
659
|
}
|
|
671
660
|
),
|
|
672
|
-
!imageLoaded && /* @__PURE__ */
|
|
661
|
+
!imageLoaded && /* @__PURE__ */ jsx6("div", { className: "absolute inset-0 flex items-center justify-center", children: fallback })
|
|
673
662
|
]
|
|
674
663
|
}
|
|
675
664
|
);
|
|
@@ -678,21 +667,24 @@ PreviewImage.displayName = "FileUpload.PreviewImage";
|
|
|
678
667
|
|
|
679
668
|
// src/file-upload/FileUploadRejectedFile.tsx
|
|
680
669
|
import { WarningOutline } from "@spark-ui/icons/WarningOutline";
|
|
681
|
-
import { cx as
|
|
670
|
+
import { cx as cx6 } from "class-variance-authority";
|
|
682
671
|
|
|
683
672
|
// src/file-upload/FileUploadRejectedFileDeleteTrigger.tsx
|
|
684
673
|
import { Close as Close2 } from "@spark-ui/icons/Close";
|
|
685
|
-
import { cx as
|
|
674
|
+
import { cx as cx5 } from "class-variance-authority";
|
|
686
675
|
import { useRef as useRef4 } from "react";
|
|
687
|
-
import { jsx as
|
|
676
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
688
677
|
var RejectedFileDeleteTrigger = ({
|
|
689
678
|
className,
|
|
690
|
-
|
|
679
|
+
rejectedFile,
|
|
691
680
|
onClick,
|
|
692
681
|
...props
|
|
693
682
|
}) => {
|
|
694
|
-
const { removeRejectedFile, triggerRef, dropzoneRef, disabled, readOnly } = useFileUploadContext();
|
|
683
|
+
const { removeRejectedFile, triggerRef, dropzoneRef, disabled, readOnly, rejectedFiles } = useFileUploadContext();
|
|
695
684
|
const buttonRef = useRef4(null);
|
|
685
|
+
const rejectedFileIndex = rejectedFiles.findIndex(
|
|
686
|
+
(rf) => rf.file.name === rejectedFile.file.name && rf.file.size === rejectedFile.file.size
|
|
687
|
+
);
|
|
696
688
|
const handleClick = (e) => {
|
|
697
689
|
if (disabled || readOnly) {
|
|
698
690
|
return;
|
|
@@ -706,59 +698,66 @@ var RejectedFileDeleteTrigger = ({
|
|
|
706
698
|
}, 0);
|
|
707
699
|
onClick?.(e);
|
|
708
700
|
};
|
|
709
|
-
return /* @__PURE__ */
|
|
701
|
+
return /* @__PURE__ */ jsx7(
|
|
710
702
|
IconButton,
|
|
711
703
|
{
|
|
712
704
|
ref: buttonRef,
|
|
713
705
|
"data-spark-component": "file-upload-rejected-file-delete-trigger",
|
|
714
|
-
className:
|
|
706
|
+
className: cx5(className),
|
|
715
707
|
onClick: handleClick,
|
|
716
708
|
disabled: disabled || readOnly,
|
|
717
709
|
size: "sm",
|
|
718
710
|
design: "contrast",
|
|
719
711
|
intent: "surface",
|
|
720
712
|
...props,
|
|
721
|
-
children: /* @__PURE__ */
|
|
713
|
+
children: /* @__PURE__ */ jsx7(Icon, { size: "sm", children: /* @__PURE__ */ jsx7(Close2, {}) })
|
|
722
714
|
}
|
|
723
715
|
);
|
|
724
716
|
};
|
|
725
717
|
RejectedFileDeleteTrigger.displayName = "FileUpload.RejectedFileDeleteTrigger";
|
|
726
718
|
|
|
727
719
|
// src/file-upload/FileUploadRejectedFile.tsx
|
|
728
|
-
import { jsx as
|
|
720
|
+
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
729
721
|
var RejectedFile = ({
|
|
730
722
|
asChild: _asChild = false,
|
|
731
723
|
className,
|
|
732
724
|
rejectedFile,
|
|
733
|
-
rejectedFileIndex,
|
|
734
725
|
renderError,
|
|
735
726
|
deleteButtonAriaLabel,
|
|
736
727
|
...props
|
|
737
728
|
}) => {
|
|
738
729
|
const { locale } = useFileUploadContext();
|
|
739
|
-
return /* @__PURE__ */ jsxs4(
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
730
|
+
return /* @__PURE__ */ jsxs4(
|
|
731
|
+
"li",
|
|
732
|
+
{
|
|
733
|
+
"data-spark-component": "file-upload-rejected-file",
|
|
734
|
+
className: cx6(
|
|
735
|
+
"relative",
|
|
736
|
+
"default:bg-surface default:border-sm default:border-outline default:p-md default:rounded-md",
|
|
737
|
+
"gap-md flex items-center justify-between default:w-full",
|
|
738
|
+
"border-error border-md",
|
|
739
|
+
className
|
|
740
|
+
),
|
|
741
|
+
...props,
|
|
742
|
+
children: [
|
|
743
|
+
/* @__PURE__ */ jsx8("div", { className: "size-sz-40 bg-error-container flex items-center justify-center rounded-md", children: /* @__PURE__ */ jsx8(Icon, { size: "md", className: "text-error", children: /* @__PURE__ */ jsx8(WarningOutline, {}) }) }),
|
|
744
|
+
/* @__PURE__ */ jsx8("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxs4("div", { className: "gap-md flex flex-col", children: [
|
|
745
|
+
/* @__PURE__ */ jsxs4("div", { className: "gap-md flex flex-row items-center justify-between", children: [
|
|
746
|
+
/* @__PURE__ */ jsx8("p", { className: "text-body-2 truncate font-medium", children: rejectedFile.file.name }),
|
|
747
|
+
/* @__PURE__ */ jsx8("p", { className: "text-caption opacity-dim-1", children: formatFileSize(rejectedFile.file.size, locale) })
|
|
748
|
+
] }),
|
|
749
|
+
/* @__PURE__ */ jsx8("div", { className: "gap-xs flex flex-col", children: rejectedFile.errors.map((error, errorIndex) => /* @__PURE__ */ jsx8("div", { className: "text-caption text-error", "data-error-code": error, children: renderError(error) }, errorIndex)) })
|
|
750
|
+
] }) }),
|
|
751
|
+
/* @__PURE__ */ jsx8(RejectedFileDeleteTrigger, { "aria-label": deleteButtonAriaLabel, rejectedFile })
|
|
752
|
+
]
|
|
753
|
+
}
|
|
754
|
+
);
|
|
756
755
|
};
|
|
757
756
|
RejectedFile.displayName = "FileUpload.RejectedFile";
|
|
758
757
|
|
|
759
758
|
// src/file-upload/FileUploadTrigger.tsx
|
|
760
|
-
import { cx as
|
|
761
|
-
import { jsx as
|
|
759
|
+
import { cx as cx7 } from "class-variance-authority";
|
|
760
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
762
761
|
var Trigger = ({
|
|
763
762
|
className,
|
|
764
763
|
children,
|
|
@@ -769,7 +768,7 @@ var Trigger = ({
|
|
|
769
768
|
ref,
|
|
770
769
|
...props
|
|
771
770
|
}) => {
|
|
772
|
-
const { inputRef, triggerRef, disabled, readOnly } = useFileUploadContext();
|
|
771
|
+
const { inputRef, triggerRef, disabled, readOnly, description, isInvalid, isRequired } = useFileUploadContext();
|
|
773
772
|
const handleClick = (e) => {
|
|
774
773
|
e.stopPropagation();
|
|
775
774
|
e.preventDefault();
|
|
@@ -779,7 +778,7 @@ var Trigger = ({
|
|
|
779
778
|
};
|
|
780
779
|
const buttonComponent = unstyled ? "button" : Button;
|
|
781
780
|
const Comp = asChild ? Slot : buttonComponent;
|
|
782
|
-
return /* @__PURE__ */
|
|
781
|
+
return /* @__PURE__ */ jsx9(
|
|
783
782
|
Comp,
|
|
784
783
|
{
|
|
785
784
|
type: "button",
|
|
@@ -798,9 +797,12 @@ var Trigger = ({
|
|
|
798
797
|
design,
|
|
799
798
|
intent,
|
|
800
799
|
"data-spark-component": "file-upload-trigger",
|
|
801
|
-
className:
|
|
800
|
+
className: cx7(className),
|
|
802
801
|
disabled: disabled || readOnly,
|
|
803
802
|
onClick: handleClick,
|
|
803
|
+
"aria-describedby": description,
|
|
804
|
+
"aria-invalid": isInvalid,
|
|
805
|
+
"aria-required": isRequired,
|
|
804
806
|
...props,
|
|
805
807
|
children
|
|
806
808
|
}
|
|
@@ -810,25 +812,22 @@ Trigger.displayName = "FileUpload.Trigger";
|
|
|
810
812
|
|
|
811
813
|
// src/file-upload/index.ts
|
|
812
814
|
var FileUpload2 = Object.assign(FileUpload, {
|
|
815
|
+
// Main input components
|
|
813
816
|
Trigger,
|
|
814
817
|
Dropzone,
|
|
818
|
+
// Context components
|
|
815
819
|
Context,
|
|
816
|
-
Item,
|
|
817
|
-
ItemFileName,
|
|
818
|
-
ItemSizeText,
|
|
819
|
-
ItemDeleteTrigger,
|
|
820
|
-
PreviewImage,
|
|
821
820
|
AcceptedFile,
|
|
822
821
|
RejectedFile,
|
|
822
|
+
// Helpers for custom renders
|
|
823
|
+
PreviewImage,
|
|
824
|
+
ItemDeleteTrigger,
|
|
823
825
|
RejectedFileDeleteTrigger
|
|
824
826
|
});
|
|
825
827
|
FileUpload2.displayName = "FileUpload";
|
|
826
828
|
Trigger.displayName = "FileUpload.Trigger";
|
|
827
829
|
Dropzone.displayName = "FileUpload.Dropzone";
|
|
828
830
|
Context.displayName = "FileUpload.Context";
|
|
829
|
-
Item.displayName = "FileUpload.Item";
|
|
830
|
-
ItemFileName.displayName = "FileUpload.ItemFileName";
|
|
831
|
-
ItemSizeText.displayName = "FileUpload.ItemSizeText";
|
|
832
831
|
ItemDeleteTrigger.displayName = "FileUpload.ItemDeleteTrigger";
|
|
833
832
|
PreviewImage.displayName = "FileUpload.PreviewImage";
|
|
834
833
|
AcceptedFile.displayName = "FileUpload.AcceptedFile";
|