@mantine-vue/dropzone 1.1.2

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/esm/index.mjs ADDED
@@ -0,0 +1,906 @@
1
+ import { cloneVNode, computed, defineComponent, h, isVNode, onMounted, onUnmounted, reactive, ref, watch } from "vue";
2
+ import { assignRef, useDisclosure } from "@mantine-vue/hooks";
3
+ import { Box, LoadingOverlay, OptionalPortal, createSafeContext, createVarsResolver, getDefaultZIndex, getRadius, useProps, useStyles, withBoxProps } from "@mantine-vue/core";
4
+ //#region src/Dropzone.context.ts
5
+ var [provideDropzoneContext, useDropzoneContext] = createSafeContext("Dropzone component was not found in tree");
6
+ //#endregion
7
+ //#region src/DropzoneStatus.ts
8
+ function upperFirst(value) {
9
+ return value.charAt(0).toUpperCase() + value.slice(1);
10
+ }
11
+ function createDropzoneStatus(status) {
12
+ return defineComponent({
13
+ name: `Dropzone${upperFirst(status)}`,
14
+ setup(_, { slots, attrs }) {
15
+ const ctx = useDropzoneContext();
16
+ return () => {
17
+ if (!ctx[status]) return null;
18
+ const children = slots.default?.();
19
+ const child = children && children.length === 1 ? children[0] : children;
20
+ if (isVNode(child) && !Array.isArray(child)) return cloneVNode(child, attrs);
21
+ return h("span", attrs, children);
22
+ };
23
+ }
24
+ });
25
+ }
26
+ var DropzoneAccept = createDropzoneStatus("accept");
27
+ var DropzoneReject = createDropzoneStatus("reject");
28
+ var DropzoneIdle = createDropzoneStatus("idle");
29
+ //#endregion
30
+ //#region src/get-files-from-event.ts
31
+ function toFileWithPath(file, path) {
32
+ const fileWithPath = file;
33
+ const relativePath = path || file.webkitRelativePath || file.name;
34
+ if (fileWithPath.path === void 0) try {
35
+ Object.defineProperty(fileWithPath, "path", {
36
+ value: relativePath,
37
+ writable: false,
38
+ configurable: true,
39
+ enumerable: true
40
+ });
41
+ } catch {}
42
+ return fileWithPath;
43
+ }
44
+ async function fromDataTransferItem(item) {
45
+ const entry = item.webkitGetAsEntry?.();
46
+ if (entry?.isDirectory) return fromDirectoryEntry(entry);
47
+ const file = item.getAsFile();
48
+ return file ? [toFileWithPath(file)] : [];
49
+ }
50
+ function fromDirectoryEntry(dirEntry, path = "") {
51
+ const reader = dirEntry.createReader();
52
+ return new Promise((resolve) => {
53
+ const entries = [];
54
+ const readEntries = () => {
55
+ reader.readEntries(async (batch) => {
56
+ if (batch.length === 0) {
57
+ resolve((await Promise.all(entries.map((entry) => entry.isDirectory ? fromDirectoryEntry(entry, `${path}${dirEntry.name}/`) : new Promise((res) => {
58
+ entry.file((file) => res([toFileWithPath(file, `${path}${dirEntry.name}/${file.name}`)]));
59
+ })))).flat());
60
+ return;
61
+ }
62
+ entries.push(...batch);
63
+ readEntries();
64
+ }, () => resolve([]));
65
+ };
66
+ readEntries();
67
+ });
68
+ }
69
+ async function fromDataTransfer(dataTransfer) {
70
+ if (dataTransfer.items && dataTransfer.items.length > 0) {
71
+ const items = Array.from(dataTransfer.items).filter((item) => item.kind === "file");
72
+ return (await Promise.all(items.map(fromDataTransferItem))).flat();
73
+ }
74
+ return Array.from(dataTransfer.files || []).map((file) => toFileWithPath(file));
75
+ }
76
+ async function getFilesFromEvent(event) {
77
+ if (Array.isArray(event)) return (await Promise.all(event.map((handle) => handle.getFile()))).map((file) => toFileWithPath(file));
78
+ const dragEvent = event;
79
+ if (dragEvent.dataTransfer) return fromDataTransfer(dragEvent.dataTransfer);
80
+ const target = event.target;
81
+ if (target?.files) return Array.from(target.files).map((file) => toFileWithPath(file));
82
+ return [];
83
+ }
84
+ //#endregion
85
+ //#region src/utils.ts
86
+ var FILE_INVALID_TYPE = "file-invalid-type";
87
+ var FILE_TOO_LARGE = "file-too-large";
88
+ var FILE_TOO_SMALL = "file-too-small";
89
+ var TOO_MANY_FILES = "too-many-files";
90
+ var ErrorCode = {
91
+ FileInvalidType: FILE_INVALID_TYPE,
92
+ FileTooLarge: FILE_TOO_LARGE,
93
+ FileTooSmall: FILE_TOO_SMALL,
94
+ TooManyFiles: TOO_MANY_FILES
95
+ };
96
+ var getInvalidTypeRejectionErr = (accept = "") => {
97
+ const acceptArr = accept.split(",");
98
+ return {
99
+ code: FILE_INVALID_TYPE,
100
+ message: `File type must be ${acceptArr.length > 1 ? `one of ${acceptArr.join(", ")}` : acceptArr[0]}`
101
+ };
102
+ };
103
+ var getTooLargeRejectionErr = (maxSize) => ({
104
+ code: FILE_TOO_LARGE,
105
+ message: `File is larger than ${maxSize} ${maxSize === 1 ? "byte" : "bytes"}`
106
+ });
107
+ var getTooSmallRejectionErr = (minSize) => ({
108
+ code: FILE_TOO_SMALL,
109
+ message: `File is smaller than ${minSize} ${minSize === 1 ? "byte" : "bytes"}`
110
+ });
111
+ var TOO_MANY_FILES_REJECTION = {
112
+ code: TOO_MANY_FILES,
113
+ message: "Too many files"
114
+ };
115
+ function isDefined(value) {
116
+ return value !== void 0 && value !== null;
117
+ }
118
+ function attrAccept(file, acceptedFiles) {
119
+ if (!acceptedFiles) return true;
120
+ const fileName = file.name || "";
121
+ const mimeType = (file.type || "").toLowerCase();
122
+ const baseMimeType = mimeType.replace(/\/.*$/, "");
123
+ return acceptedFiles.split(",").map((type) => type.trim().toLowerCase()).some((type) => {
124
+ if (type.startsWith(".")) return fileName.toLowerCase().endsWith(type);
125
+ if (type.endsWith("/*")) return baseMimeType === type.replace(/\/.*$/, "");
126
+ return mimeType === type;
127
+ });
128
+ }
129
+ /**
130
+ * Check if the given file is a DataTransferItem with an empty type. During drag events some
131
+ * browsers report an empty MIME type on DataTransferItem for certain file extensions even though
132
+ * the type is correctly set once the file is actually dropped, so we accept those provisionally.
133
+ */
134
+ function isDataTransferItemWithEmptyType(file) {
135
+ return file.type === "" && typeof file.getAsFile === "function";
136
+ }
137
+ function fileAccepted(file, accept) {
138
+ const isAcceptable = file.type === "application/x-moz-file" || attrAccept(file, accept) || isDataTransferItemWithEmptyType(file);
139
+ return [isAcceptable, isAcceptable ? null : getInvalidTypeRejectionErr(accept)];
140
+ }
141
+ function fileMatchSize(file, minSize, maxSize) {
142
+ if (isDefined(file.size)) {
143
+ if (isDefined(minSize) && isDefined(maxSize)) {
144
+ if (file.size > maxSize) return [false, getTooLargeRejectionErr(maxSize)];
145
+ if (file.size < minSize) return [false, getTooSmallRejectionErr(minSize)];
146
+ } else if (isDefined(minSize) && file.size < minSize) return [false, getTooSmallRejectionErr(minSize)];
147
+ else if (isDefined(maxSize) && file.size > maxSize) return [false, getTooLargeRejectionErr(maxSize)];
148
+ }
149
+ return [true, null];
150
+ }
151
+ function allFilesAccepted({ files, accept, minSize, maxSize, multiple, maxFiles, validator }) {
152
+ if (!multiple && files.length > 1 || multiple && (maxFiles ?? 0) >= 1 && files.length > maxFiles) return false;
153
+ return files.every((file) => {
154
+ const [accepted] = fileAccepted(file, accept);
155
+ const [sizeMatch] = fileMatchSize(file, minSize, maxSize);
156
+ const customErrors = validator ? validator(file) : null;
157
+ return accepted && sizeMatch && !customErrors;
158
+ });
159
+ }
160
+ function isEvtWithFiles(event) {
161
+ const dataTransfer = event.dataTransfer;
162
+ if (!dataTransfer) {
163
+ const target = event.target;
164
+ return !!target && !!target.files;
165
+ }
166
+ return Array.prototype.some.call(dataTransfer.types || [], (type) => type === "Files" || type === "application/x-moz-file");
167
+ }
168
+ function canUseFileSystemAccessAPI() {
169
+ return typeof window !== "undefined" && "showOpenFilePicker" in window;
170
+ }
171
+ /** Convert the `accept` prop into the `{types}` option for `window.showOpenFilePicker`. */
172
+ function pickerOptionsFromAccept(accept) {
173
+ if (!isDefined(accept)) return;
174
+ return [{
175
+ description: "Files",
176
+ accept: Object.entries(accept).filter(([mimeType, ext]) => isMIMEType(mimeType) && Array.isArray(ext) && ext.every(isExt)).reduce((agg, [mimeType, ext]) => ({
177
+ ...agg,
178
+ [mimeType]: ext
179
+ }), {})
180
+ }];
181
+ }
182
+ /** Convert the `accept` prop into a comma-separated string suitable for `<input accept>`. */
183
+ function acceptPropAsAcceptAttr(accept) {
184
+ if (!isDefined(accept)) return;
185
+ return Object.entries(accept).reduce((acc, [mimeType, ext]) => [
186
+ ...acc,
187
+ mimeType,
188
+ ...ext
189
+ ], []).filter((v) => isMIMEType(v) || isExt(v)).join(",");
190
+ }
191
+ function isAbort(v) {
192
+ return v instanceof DOMException && (v.name === "AbortError" || v.code === v.ABORT_ERR);
193
+ }
194
+ function isSecurityError(v) {
195
+ return v instanceof DOMException && (v.name === "SecurityError" || v.code === v.SECURITY_ERR);
196
+ }
197
+ function isMIMEType(v) {
198
+ return v === "audio/*" || v === "video/*" || v === "image/*" || v === "text/*" || v === "application/*" || /\w+\/[-+.\w]+/g.test(v);
199
+ }
200
+ function isExt(v) {
201
+ return /^.*\.[\w]+$/.test(v);
202
+ }
203
+ //#endregion
204
+ //#region src/use-dropzone.ts
205
+ function useDropzone(options) {
206
+ const rootRef = ref(null);
207
+ const inputRef = ref(null);
208
+ const state = reactive({
209
+ isFocused: false,
210
+ isFileDialogActive: false,
211
+ isDragActive: false,
212
+ isDragAccept: false,
213
+ isDragReject: false
214
+ });
215
+ let dragTargets = [];
216
+ const fsAccessApiWorks = typeof window !== "undefined" && window.isSecureContext && !!options.useFsAccessApi?.() && canUseFileSystemAccessAPI();
217
+ const acceptAttr = computed(() => acceptPropAsAcceptAttr(options.accept?.()));
218
+ const pickerTypes = computed(() => pickerOptionsFromAccept(options.accept?.()));
219
+ const getFilesFromEvent$1 = (event) => (options.getFilesFromEvent?.() ?? getFilesFromEvent)(event);
220
+ const onErr = (error) => {
221
+ if (options.onError) options.onError(error);
222
+ else console.error(error);
223
+ };
224
+ const stopPropagation = (event) => {
225
+ if (options.noDragEventsBubbling?.()) event.stopPropagation();
226
+ };
227
+ const onWindowFocus = () => {
228
+ if (!fsAccessApiWorks && state.isFileDialogActive) setTimeout(() => {
229
+ if (inputRef.value && !inputRef.value.files?.length) {
230
+ state.isFileDialogActive = false;
231
+ options.onFileDialogCancel?.();
232
+ }
233
+ }, 300);
234
+ };
235
+ const onDocumentDragOver = (event) => event.preventDefault();
236
+ const onDocumentDrop = (event) => {
237
+ if (rootRef.value && event.target && rootRef.value.contains(event.target)) return;
238
+ event.preventDefault();
239
+ dragTargets = [];
240
+ };
241
+ onMounted(() => {
242
+ window.addEventListener("focus", onWindowFocus, false);
243
+ if (options.preventDropOnDocument?.() ?? true) {
244
+ document.addEventListener("dragover", onDocumentDragOver, false);
245
+ document.addEventListener("drop", onDocumentDrop, false);
246
+ }
247
+ if ((options.autoFocus?.() ?? false) && !options.disabled?.()) rootRef.value?.focus();
248
+ });
249
+ onUnmounted(() => {
250
+ window.removeEventListener("focus", onWindowFocus, false);
251
+ document.removeEventListener("dragover", onDocumentDragOver);
252
+ document.removeEventListener("drop", onDocumentDrop);
253
+ });
254
+ const setFiles = (files, event) => {
255
+ const acceptedFiles = [];
256
+ const fileRejections = [];
257
+ const minSize = options.minSize?.();
258
+ const maxSize = options.maxSize?.();
259
+ const multiple = options.multiple?.() ?? true;
260
+ const maxFiles = options.maxFiles?.();
261
+ const validator = options.validator?.();
262
+ files.forEach((file) => {
263
+ const [accepted, acceptError] = fileAccepted(file, acceptAttr.value);
264
+ const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);
265
+ const customErrors = validator ? validator(file) : null;
266
+ if (accepted && sizeMatch && !customErrors) acceptedFiles.push(file);
267
+ else {
268
+ const errors = [acceptError, sizeError].filter((e) => !!e);
269
+ if (customErrors) errors.push(...Array.isArray(customErrors) ? customErrors : [customErrors]);
270
+ fileRejections.push({
271
+ file,
272
+ errors
273
+ });
274
+ }
275
+ });
276
+ if (!multiple && acceptedFiles.length > 1 || multiple && (maxFiles ?? 0) >= 1 && acceptedFiles.length > maxFiles) {
277
+ acceptedFiles.forEach((file) => fileRejections.push({
278
+ file,
279
+ errors: [TOO_MANY_FILES_REJECTION]
280
+ }));
281
+ acceptedFiles.length = 0;
282
+ }
283
+ options.onDrop?.(acceptedFiles, fileRejections, event);
284
+ if (fileRejections.length > 0) options.onDropRejected?.(fileRejections, event);
285
+ if (acceptedFiles.length > 0) options.onDropAccepted?.(acceptedFiles, event);
286
+ };
287
+ const onDragEnterCb = (event) => {
288
+ event.preventDefault();
289
+ stopPropagation(event);
290
+ dragTargets = [...dragTargets, event.target];
291
+ if (isEvtWithFiles(event)) Promise.resolve(getFilesFromEvent$1(event)).then((files) => {
292
+ const isDragAccept = files.length > 0 && allFilesAccepted({
293
+ files,
294
+ accept: acceptAttr.value,
295
+ minSize: options.minSize?.(),
296
+ maxSize: options.maxSize?.(),
297
+ multiple: options.multiple?.() ?? true,
298
+ maxFiles: options.maxFiles?.(),
299
+ validator: options.validator?.()
300
+ });
301
+ const isDragReject = files.length > 0 && !isDragAccept;
302
+ state.isDragActive = true;
303
+ state.isDragAccept = isDragAccept;
304
+ state.isDragReject = isDragReject;
305
+ options.onDragEnter?.(event);
306
+ }).catch(onErr);
307
+ };
308
+ const onDragOverCb = (event) => {
309
+ event.preventDefault();
310
+ stopPropagation(event);
311
+ const hasFiles = isEvtWithFiles(event);
312
+ if (hasFiles && event.dataTransfer) try {
313
+ event.dataTransfer.dropEffect = "copy";
314
+ } catch {}
315
+ if (hasFiles) options.onDragOver?.(event);
316
+ };
317
+ const onDragLeaveCb = (event) => {
318
+ event.preventDefault();
319
+ stopPropagation(event);
320
+ const targets = dragTargets.filter((target) => rootRef.value && rootRef.value.contains(target));
321
+ const targetIdx = targets.indexOf(event.target);
322
+ if (targetIdx !== -1) targets.splice(targetIdx, 1);
323
+ dragTargets = targets;
324
+ if (targets.length > 0) return;
325
+ state.isDragActive = false;
326
+ state.isDragAccept = false;
327
+ state.isDragReject = false;
328
+ if (isEvtWithFiles(event)) options.onDragLeave?.(event);
329
+ };
330
+ const onDropCb = (event) => {
331
+ event.preventDefault();
332
+ stopPropagation(event);
333
+ dragTargets = [];
334
+ if (isEvtWithFiles(event)) Promise.resolve(getFilesFromEvent$1(event)).then((files) => setFiles(files, event)).catch(onErr);
335
+ state.isDragActive = false;
336
+ state.isDragAccept = false;
337
+ state.isDragReject = false;
338
+ };
339
+ const openFileDialog = () => {
340
+ if (options.disabled?.()) return;
341
+ if (fsAccessApiWorks) {
342
+ state.isFileDialogActive = true;
343
+ options.onFileDialogOpen?.();
344
+ const opts = {
345
+ multiple: options.multiple?.() ?? true,
346
+ types: pickerTypes.value
347
+ };
348
+ window.showOpenFilePicker(opts).then((handles) => getFilesFromEvent$1(handles)).then((files) => {
349
+ setFiles(files, null);
350
+ state.isFileDialogActive = false;
351
+ }).catch((e) => {
352
+ if (isAbort(e)) {
353
+ options.onFileDialogCancel?.();
354
+ state.isFileDialogActive = false;
355
+ } else if (isSecurityError(e)) if (inputRef.value) {
356
+ inputRef.value.value = "";
357
+ inputRef.value.click();
358
+ } else onErr(/* @__PURE__ */ new Error("Cannot open the file picker: no <input> was rendered as a fallback."));
359
+ else onErr(e);
360
+ });
361
+ return;
362
+ }
363
+ if (inputRef.value) {
364
+ state.isFileDialogActive = true;
365
+ options.onFileDialogOpen?.();
366
+ inputRef.value.value = "";
367
+ inputRef.value.click();
368
+ }
369
+ };
370
+ const onKeyDownCb = (event) => {
371
+ if (!rootRef.value || rootRef.value !== event.target) return;
372
+ if (event.key === " " || event.key === "Enter") {
373
+ event.preventDefault();
374
+ openFileDialog();
375
+ }
376
+ };
377
+ const onFocusCb = () => {
378
+ state.isFocused = true;
379
+ };
380
+ const onBlurCb = () => {
381
+ state.isFocused = false;
382
+ };
383
+ const onClickCb = () => {
384
+ if (!options.noClick?.()) openFileDialog();
385
+ };
386
+ const onInputClickCb = (event) => {
387
+ event.stopPropagation();
388
+ };
389
+ const onInputChangeCb = (event) => {
390
+ onDropCb(event);
391
+ };
392
+ const composeHandler = (fn) => options.disabled?.() ? null : fn;
393
+ const composeKeyboardHandler = (fn) => options.noKeyboard?.() ? null : composeHandler(fn);
394
+ const composeDragHandler = (fn) => options.noDrag?.() ? null : composeHandler(fn);
395
+ const getRootProps = (overrides = {}) => ({
396
+ onKeydown: composeKeyboardHandler(onKeyDownCb),
397
+ onFocus: composeKeyboardHandler(onFocusCb),
398
+ onBlur: composeKeyboardHandler(onBlurCb),
399
+ onClick: composeHandler(onClickCb),
400
+ onDragenter: composeDragHandler(onDragEnterCb),
401
+ onDragover: composeDragHandler(onDragOverCb),
402
+ onDragleave: composeDragHandler(onDragLeaveCb),
403
+ onDrop: composeDragHandler(onDropCb),
404
+ role: "presentation",
405
+ ref: (el) => {
406
+ rootRef.value = el?.$el ?? el ?? null;
407
+ },
408
+ ...!options.disabled?.() && !options.noKeyboard?.() ? { tabindex: 0 } : {},
409
+ ...overrides
410
+ });
411
+ const getInputProps = (overrides = {}) => ({
412
+ type: "file",
413
+ accept: acceptAttr.value,
414
+ multiple: options.multiple?.() ?? true,
415
+ style: {
416
+ border: 0,
417
+ clip: "rect(0, 0, 0, 0)",
418
+ clipPath: "inset(50%)",
419
+ height: "1px",
420
+ margin: "0 -1px -1px 0",
421
+ overflow: "hidden",
422
+ padding: 0,
423
+ position: "absolute",
424
+ width: "1px",
425
+ whiteSpace: "nowrap"
426
+ },
427
+ onChange: composeHandler(onInputChangeCb),
428
+ onClick: composeHandler(onInputClickCb),
429
+ tabindex: -1,
430
+ ref: (el) => {
431
+ inputRef.value = el?.$el ?? el ?? null;
432
+ },
433
+ ...overrides
434
+ });
435
+ return {
436
+ state,
437
+ rootRef,
438
+ inputRef,
439
+ isFocused: computed(() => state.isFocused && !options.disabled?.()),
440
+ isDragActive: computed(() => state.isDragActive),
441
+ isDragAccept: computed(() => state.isDragAccept),
442
+ isDragReject: computed(() => state.isDragReject),
443
+ getRootProps,
444
+ getInputProps,
445
+ open: () => composeHandler(openFileDialog)?.()
446
+ };
447
+ }
448
+ var Dropzone_module_default = {
449
+ root: "_root_27ynu_1",
450
+ inner: "_inner_27ynu_53",
451
+ fullScreen: "_fullScreen_27ynu_62",
452
+ dropzone: "_dropzone_27ynu_71"
453
+ };
454
+ //#endregion
455
+ //#region src/Dropzone.ts
456
+ var defaultProps$1 = {
457
+ multiple: true,
458
+ maxSize: Infinity,
459
+ activateOnClick: true,
460
+ activateOnDrag: true,
461
+ dragEventsBubbling: true,
462
+ activateOnKeyboard: true,
463
+ useFsAccessApi: false,
464
+ preventDropOnDocument: true,
465
+ variant: "light",
466
+ rejectColor: "red"
467
+ };
468
+ var varsResolver = createVarsResolver((theme, { radius, variant, acceptColor, rejectColor }) => {
469
+ const acceptColors = theme.variantColorResolver({
470
+ color: acceptColor || theme.primaryColor,
471
+ theme,
472
+ variant
473
+ });
474
+ const rejectColors = theme.variantColorResolver({
475
+ color: rejectColor || "red",
476
+ theme,
477
+ variant
478
+ });
479
+ return { root: {
480
+ "--dropzone-radius": getRadius(radius),
481
+ "--dropzone-accept-color": acceptColors.color,
482
+ "--dropzone-accept-bg": acceptColors.background,
483
+ "--dropzone-reject-color": rejectColors.color,
484
+ "--dropzone-reject-bg": rejectColors.background
485
+ } };
486
+ });
487
+ var DropzoneBaseComponent = defineComponent({
488
+ name: "Dropzone",
489
+ inheritAttrs: false,
490
+ props: {
491
+ acceptColor: {
492
+ type: String,
493
+ default: void 0
494
+ },
495
+ rejectColor: {
496
+ type: String,
497
+ default: void 0
498
+ },
499
+ radius: {
500
+ type: [String, Number],
501
+ default: void 0
502
+ },
503
+ disabled: {
504
+ type: Boolean,
505
+ default: false
506
+ },
507
+ loading: {
508
+ type: Boolean,
509
+ default: false
510
+ },
511
+ accept: {
512
+ type: [Object, Array],
513
+ default: void 0
514
+ },
515
+ multiple: {
516
+ type: Boolean,
517
+ default: void 0
518
+ },
519
+ maxSize: {
520
+ type: Number,
521
+ default: void 0
522
+ },
523
+ name: {
524
+ type: String,
525
+ default: void 0
526
+ },
527
+ maxFiles: {
528
+ type: Number,
529
+ default: void 0
530
+ },
531
+ autoFocus: {
532
+ type: Boolean,
533
+ default: false
534
+ },
535
+ activateOnClick: {
536
+ type: Boolean,
537
+ default: void 0
538
+ },
539
+ activateOnDrag: {
540
+ type: Boolean,
541
+ default: void 0
542
+ },
543
+ activateOnKeyboard: {
544
+ type: Boolean,
545
+ default: void 0
546
+ },
547
+ dragEventsBubbling: {
548
+ type: Boolean,
549
+ default: void 0
550
+ },
551
+ preventDropOnDocument: {
552
+ type: Boolean,
553
+ default: void 0
554
+ },
555
+ useFsAccessApi: {
556
+ type: Boolean,
557
+ default: void 0
558
+ },
559
+ enablePointerEvents: {
560
+ type: Boolean,
561
+ default: false
562
+ },
563
+ variant: {
564
+ type: String,
565
+ default: void 0
566
+ },
567
+ loaderProps: {
568
+ type: Object,
569
+ default: void 0
570
+ },
571
+ inputProps: {
572
+ type: Object,
573
+ default: void 0
574
+ },
575
+ validator: {
576
+ type: Function,
577
+ default: void 0
578
+ },
579
+ getFilesFromEvent: {
580
+ type: Function,
581
+ default: void 0
582
+ },
583
+ openRef: {
584
+ type: [Object, Function],
585
+ default: void 0
586
+ },
587
+ onDrop: {
588
+ type: Function,
589
+ required: true
590
+ },
591
+ onDropAny: {
592
+ type: Function,
593
+ default: void 0
594
+ },
595
+ onReject: {
596
+ type: Function,
597
+ default: void 0
598
+ },
599
+ onDragEnter: {
600
+ type: Function,
601
+ default: void 0
602
+ },
603
+ onDragLeave: {
604
+ type: Function,
605
+ default: void 0
606
+ },
607
+ onDragOver: {
608
+ type: Function,
609
+ default: void 0
610
+ },
611
+ onFileDialogCancel: {
612
+ type: Function,
613
+ default: void 0
614
+ },
615
+ onFileDialogOpen: {
616
+ type: Function,
617
+ default: void 0
618
+ },
619
+ classNames: {
620
+ type: [Object, Function],
621
+ default: void 0
622
+ },
623
+ styles: {
624
+ type: [Object, Function],
625
+ default: void 0
626
+ },
627
+ vars: {
628
+ type: [Object, Function],
629
+ default: void 0
630
+ },
631
+ unstyled: {
632
+ type: Boolean,
633
+ default: false
634
+ }
635
+ },
636
+ setup(rawProps, { attrs, slots }) {
637
+ const props = useProps("Dropzone", defaultProps$1, rawProps);
638
+ const getStyles = useStyles({
639
+ name: "Dropzone",
640
+ classes: Dropzone_module_default,
641
+ props,
642
+ className: attrs.class,
643
+ style: attrs.style,
644
+ classNames: props.classNames,
645
+ styles: props.styles,
646
+ vars: props.vars,
647
+ varsResolver,
648
+ unstyled: props.unstyled
649
+ });
650
+ const dz = useDropzone({
651
+ accept: () => Array.isArray(props.accept) ? props.accept.reduce((r, key) => ({
652
+ ...r,
653
+ [key]: []
654
+ }), {}) : props.accept,
655
+ disabled: () => props.disabled || props.loading,
656
+ multiple: () => props.multiple,
657
+ maxSize: () => props.maxSize,
658
+ maxFiles: () => props.maxFiles,
659
+ autoFocus: () => props.autoFocus,
660
+ noClick: () => !props.activateOnClick,
661
+ noDrag: () => !props.activateOnDrag,
662
+ noDragEventsBubbling: () => !props.dragEventsBubbling,
663
+ noKeyboard: () => !props.activateOnKeyboard,
664
+ preventDropOnDocument: () => props.preventDropOnDocument,
665
+ useFsAccessApi: () => props.useFsAccessApi,
666
+ validator: () => props.validator,
667
+ getFilesFromEvent: () => props.getFilesFromEvent,
668
+ onDrop: (files, fileRejections) => props.onDropAny?.(files, fileRejections),
669
+ onDropAccepted: (files) => props.onDrop(files),
670
+ onDropRejected: (fileRejections) => props.onReject?.(fileRejections),
671
+ onDragEnter: (event) => props.onDragEnter?.(event),
672
+ onDragLeave: (event) => props.onDragLeave?.(event),
673
+ onDragOver: (event) => props.onDragOver?.(event),
674
+ onFileDialogCancel: () => props.onFileDialogCancel?.(),
675
+ onFileDialogOpen: () => props.onFileDialogOpen?.()
676
+ });
677
+ assignRef(props.openRef, dz.open);
678
+ provideDropzoneContext({
679
+ get accept() {
680
+ return dz.isDragActive.value && dz.isDragAccept.value;
681
+ },
682
+ get reject() {
683
+ return dz.isDragActive.value && dz.isDragReject.value;
684
+ },
685
+ get idle() {
686
+ const accepted = dz.isDragActive.value && dz.isDragAccept.value;
687
+ const rejected = dz.isDragActive.value && dz.isDragReject.value;
688
+ return !accepted && !rejected;
689
+ }
690
+ });
691
+ return () => {
692
+ const isAccepted = dz.isDragActive.value && dz.isDragAccept.value;
693
+ const isRejected = dz.isDragActive.value && dz.isDragReject.value;
694
+ const isIdle = !isAccepted && !isRejected;
695
+ const rootProps = dz.getRootProps();
696
+ const inputProps = dz.getInputProps(props.inputProps);
697
+ return h(Box, {
698
+ ...rootProps,
699
+ ...getStyles("root"),
700
+ ...attrs,
701
+ mod: [{
702
+ accept: isAccepted,
703
+ reject: isRejected,
704
+ idle: isIdle,
705
+ disabled: props.disabled,
706
+ loading: props.loading,
707
+ "activate-on-click": props.activateOnClick
708
+ }, attrs.mod]
709
+ }, () => [
710
+ h(LoadingOverlay, {
711
+ visible: props.loading,
712
+ overlayProps: { radius: props.radius },
713
+ unstyled: props.unstyled,
714
+ loaderProps: props.loaderProps
715
+ }),
716
+ h("input", {
717
+ ...inputProps,
718
+ name: props.name
719
+ }),
720
+ h("div", {
721
+ ...getStyles("inner"),
722
+ "data-enable-pointer-events": props.enablePointerEvents || void 0
723
+ }, slots.default?.())
724
+ ]);
725
+ };
726
+ }
727
+ });
728
+ var Dropzone$1 = Object.assign(withBoxProps(DropzoneBaseComponent), {
729
+ classes: Dropzone_module_default,
730
+ varsResolver,
731
+ Accept: DropzoneAccept,
732
+ Idle: DropzoneIdle,
733
+ Reject: DropzoneReject
734
+ });
735
+ //#endregion
736
+ //#region src/DropzoneFullScreen.ts
737
+ var defaultProps = {
738
+ maxSize: Infinity,
739
+ activateOnDrag: true,
740
+ dragEventsBubbling: true,
741
+ activateOnKeyboard: true,
742
+ active: true,
743
+ zIndex: getDefaultZIndex("max"),
744
+ withinPortal: true
745
+ };
746
+ var DropzoneFullScreen = withBoxProps(defineComponent({
747
+ name: "DropzoneFullScreen",
748
+ inheritAttrs: false,
749
+ props: {
750
+ active: {
751
+ type: Boolean,
752
+ default: void 0
753
+ },
754
+ onDrop: {
755
+ type: Function,
756
+ required: true
757
+ },
758
+ onReject: {
759
+ type: Function,
760
+ default: void 0
761
+ },
762
+ zIndex: {
763
+ type: [String, Number],
764
+ default: void 0
765
+ },
766
+ withinPortal: {
767
+ type: Boolean,
768
+ default: void 0
769
+ },
770
+ portalProps: {
771
+ type: Object,
772
+ default: void 0
773
+ },
774
+ classNames: {
775
+ type: [Object, Function],
776
+ default: void 0
777
+ },
778
+ styles: {
779
+ type: [Object, Function],
780
+ default: void 0
781
+ },
782
+ unstyled: {
783
+ type: Boolean,
784
+ default: false
785
+ }
786
+ },
787
+ setup(rawProps, { attrs, slots }) {
788
+ const props = useProps("DropzoneFullScreen", defaultProps, rawProps);
789
+ const getStyles = useStyles({
790
+ name: "DropzoneFullScreen",
791
+ classes: Dropzone_module_default,
792
+ props,
793
+ className: attrs.class,
794
+ style: attrs.style,
795
+ classNames: props.classNames,
796
+ styles: props.styles,
797
+ unstyled: props.unstyled,
798
+ rootSelector: "fullScreen"
799
+ });
800
+ const counter = ref(0);
801
+ const [visible, { open, close }] = useDisclosure(false);
802
+ const handleDragEnter = (event) => {
803
+ if (event.dataTransfer?.types.includes("Files")) {
804
+ counter.value += 1;
805
+ open();
806
+ }
807
+ };
808
+ const handleDragLeave = () => {
809
+ counter.value -= 1;
810
+ };
811
+ watch(counter, (value) => {
812
+ if (value === 0) close();
813
+ });
814
+ let attached = false;
815
+ const attach = () => {
816
+ if (attached) return;
817
+ document.addEventListener("dragenter", handleDragEnter, false);
818
+ document.addEventListener("dragleave", handleDragLeave, false);
819
+ attached = true;
820
+ };
821
+ const detach = () => {
822
+ if (!attached) return;
823
+ document.removeEventListener("dragenter", handleDragEnter, false);
824
+ document.removeEventListener("dragleave", handleDragLeave, false);
825
+ attached = false;
826
+ };
827
+ watch(() => props.active, (active) => {
828
+ detach();
829
+ if (active) attach();
830
+ }, { immediate: true });
831
+ onUnmounted(detach);
832
+ return () => h(OptionalPortal, {
833
+ ...props.portalProps,
834
+ withinPortal: props.withinPortal
835
+ }, () => h("div", { ...getStyles("fullScreen", { style: {
836
+ opacity: visible.value ? 1 : 0,
837
+ pointerEvents: visible.value ? "all" : "none",
838
+ zIndex: props.zIndex
839
+ } }) }, [h(Dropzone$1, {
840
+ activateOnClick: false,
841
+ ...attrs,
842
+ classNames: props.classNames,
843
+ styles: props.styles,
844
+ unstyled: props.unstyled,
845
+ class: Dropzone_module_default.dropzone,
846
+ onDrop: (files) => {
847
+ props.onDrop(files);
848
+ close();
849
+ counter.value = 0;
850
+ },
851
+ onReject: (fileRejections) => {
852
+ props.onReject?.(fileRejections);
853
+ close();
854
+ counter.value = 0;
855
+ }
856
+ }, slots)]));
857
+ }
858
+ }));
859
+ //#endregion
860
+ //#region src/mime-types.ts
861
+ var MIME_TYPES = {
862
+ png: "image/png",
863
+ gif: "image/gif",
864
+ jpeg: "image/jpeg",
865
+ svg: "image/svg+xml",
866
+ webp: "image/webp",
867
+ avif: "image/avif",
868
+ heic: "image/heic",
869
+ heif: "image/heif",
870
+ mp4: "video/mp4",
871
+ zip: "application/zip",
872
+ rar: "application/x-rar",
873
+ "7z": "application/x-7z-compressed",
874
+ csv: "text/csv",
875
+ pdf: "application/pdf",
876
+ doc: "application/msword",
877
+ docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
878
+ xls: "application/vnd.ms-excel",
879
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
880
+ ppt: "application/vnd.ms-powerpoint",
881
+ pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
882
+ exe: "application/vnd.microsoft.portable-executable"
883
+ };
884
+ var IMAGE_MIME_TYPE = [
885
+ MIME_TYPES.png,
886
+ MIME_TYPES.gif,
887
+ MIME_TYPES.jpeg,
888
+ MIME_TYPES.svg,
889
+ MIME_TYPES.webp,
890
+ MIME_TYPES.avif,
891
+ MIME_TYPES.heic,
892
+ MIME_TYPES.heif
893
+ ];
894
+ var PDF_MIME_TYPE = [MIME_TYPES.pdf];
895
+ var MS_WORD_MIME_TYPE = [MIME_TYPES.doc, MIME_TYPES.docx];
896
+ var MS_EXCEL_MIME_TYPE = [MIME_TYPES.xls, MIME_TYPES.xlsx];
897
+ var MS_POWERPOINT_MIME_TYPE = [MIME_TYPES.ppt, MIME_TYPES.pptx];
898
+ var EXE_MIME_TYPE = [MIME_TYPES.exe];
899
+ //#endregion
900
+ //#region src/index.ts
901
+ Object.assign(Dropzone$1, { FullScreen: DropzoneFullScreen });
902
+ var Dropzone = Dropzone$1;
903
+ //#endregion
904
+ export { Dropzone, DropzoneAccept, DropzoneFullScreen, DropzoneIdle, DropzoneReject, EXE_MIME_TYPE, ErrorCode, FILE_INVALID_TYPE, FILE_TOO_LARGE, FILE_TOO_SMALL, IMAGE_MIME_TYPE, MIME_TYPES, MS_EXCEL_MIME_TYPE, MS_POWERPOINT_MIME_TYPE, MS_WORD_MIME_TYPE, PDF_MIME_TYPE, TOO_MANY_FILES, TOO_MANY_FILES_REJECTION, acceptPropAsAcceptAttr, allFilesAccepted, canUseFileSystemAccessAPI, fileAccepted, fileMatchSize, getInvalidTypeRejectionErr, getTooLargeRejectionErr, getTooSmallRejectionErr, isAbort, isDataTransferItemWithEmptyType, isEvtWithFiles, isExt, isMIMEType, isSecurityError, pickerOptionsFromAccept, useDropzone };
905
+
906
+ //# sourceMappingURL=index.mjs.map