react-dropzone 18.1.0 → 18.2.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/README.md CHANGED
@@ -299,7 +299,7 @@ This lib is not a file uploader; as such, it does not process files or provide a
299
299
 
300
300
  ### Using \<label\> as Root
301
301
 
302
- If you use [\<label\>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label) as the root element, the file dialog will be opened twice; see [#1107](https://github.com/react-dropzone/react-dropzone/issues/1107) why. To avoid this, use `noClick`:
302
+ If you use [\<label\>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label) as the root element, the file dialog will be opened twice; see [#1107](https://github.com/react-dropzone/react-dropzone/issues/1107) and [#1432](https://github.com/react-dropzone/react-dropzone/issues/1432) why. A `<label>` natively forwards clicks to the `<input>` it wraps, so the dialog opens once from that and once from our own click handler. To avoid this, use `noClick`:
303
303
 
304
304
  ```jsx static
305
305
  import React, {useCallback} from "react";
@@ -338,6 +338,56 @@ function MyDropzone() {
338
338
  }
339
339
  ```
340
340
 
341
+ ### Changing Props Before open()
342
+
343
+ Browsers only let you open the file dialog from within a short window after a user gesture (a "[transient user activation](https://developer.mozilla.org/en-US/docs/Web/Security/User_activation)"). Because of this, `open()` must run synchronously in the same event that the user triggered - it cannot wait for React to re-render.
344
+
345
+ So if you update a prop (e.g. `accept`) and call `open()` in the same handler, `open()` runs against the _previous_ render, before the new prop is applied. Some browsers (notably Safari) may also drop the file dialog entirely, so it appears to require a second click. See [#1188](https://github.com/react-dropzone/react-dropzone/issues/1188).
346
+
347
+ ```jsx static
348
+ // 🚫 open() runs with the old `accept` - and may not open at all on Safari
349
+ function MyDropzone() {
350
+ const [accept, setAccept] = useState({"image/*": []});
351
+ const {getRootProps, getInputProps, open} = useDropzone({accept, noClick: true});
352
+
353
+ const pickPdfs = () => {
354
+ setAccept({"application/pdf": []}); // applied on the next render
355
+ open(); // still uses {"image/*": []}
356
+ };
357
+
358
+ return (
359
+ <div {...getRootProps()}>
360
+ <input {...getInputProps()} />
361
+ <button type="button" onClick={pickPdfs}>
362
+ Pick PDFs
363
+ </button>
364
+ </div>
365
+ );
366
+ }
367
+ ```
368
+
369
+ Instead, render one dropzone per set of props (each with its own `open`) and call the right one, so no state change has to land before opening:
370
+
371
+ ```jsx static
372
+ function MyDropzone() {
373
+ const images = useDropzone({accept: {"image/*": []}, noClick: true});
374
+ const pdfs = useDropzone({accept: {"application/pdf": []}, noClick: true});
375
+
376
+ return (
377
+ <div {...images.getRootProps()}>
378
+ <input {...images.getInputProps()} />
379
+ <input {...pdfs.getInputProps()} />
380
+ <button type="button" onClick={images.open}>
381
+ Pick images
382
+ </button>
383
+ <button type="button" onClick={pdfs.open}>
384
+ Pick PDFs
385
+ </button>
386
+ </div>
387
+ );
388
+ }
389
+ ```
390
+
341
391
  ### File Dialog Cancel Callback
342
392
 
343
393
  The `onFileDialogCancel()` cb is unstable in most browsers, meaning, there's a good chance of it being triggered even though you have selected files.
@@ -365,6 +415,7 @@ With the use of the file system access API enabled, there's a couple of caveats
365
415
  1. The users will not be able to select directories
366
416
  2. It requires the app to run in a [secure context](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts)
367
417
  3. In [Electron](https://www.electronjs.org/), the path may not be set (see [#1249](https://github.com/react-dropzone/react-dropzone/issues/1249))
418
+ 4. Some browsers/configurations block `showOpenFilePicker()` and reject with a `NotAllowedError` (e.g. Microsoft Edge for Business or other restrictive enterprise/security policies). When this happens we automatically fall back to the native `<input>` so the file dialog still opens, provided you render one via `getInputProps()` (see [#1429](https://github.com/react-dropzone/react-dropzone/issues/1429))
368
419
 
369
420
  ## Supported Browsers
370
421
 
package/dist/index.cjs CHANGED
@@ -227,6 +227,17 @@ function isSecurityError(v) {
227
227
  return v instanceof DOMException && (v.name === "SecurityError" || v.code === v.SECURITY_ERR);
228
228
  }
229
229
  /**
230
+ * Check if v is a "not allowed" error.
231
+ *
232
+ * Some browsers/configurations block `window.showOpenFilePicker()` outright and reject with a
233
+ * `NotAllowedError` instead of showing the picker (e.g. Microsoft Edge for Business, or other
234
+ * restrictive enterprise/security policies). We treat this like a security error and fall back
235
+ * to the native `<input>`. See https://github.com/react-dropzone/react-dropzone/issues/1429
236
+ */
237
+ function isNotAllowedError(v) {
238
+ return v instanceof DOMException && v.name === "NotAllowedError";
239
+ }
240
+ /**
230
241
  * Check if v is a MIME type string.
231
242
  */
232
243
  function isMIMEType(v) {
@@ -299,7 +310,7 @@ const initialState = {
299
310
  * ```
300
311
  */
301
312
  function useDropzone(props = {}) {
302
- const { accept, disabled = false, getFilesFromEvent = file_selector.fromEvent, maxSize = Number.POSITIVE_INFINITY, minSize = 0, multiple = true, maxFiles = 0, onDragEnter, onDragLeave, onDragOver, onDrop, onDropAccepted, onDropRejected, onFileDialogCancel, onFileDialogOpen, useFsAccessApi = false, autoFocus = false, preventDropOnDocument = true, noClick = false, noKeyboard = false, noDrag = false, noDragEventsBubbling = false, onError, validator } = props;
313
+ const { accept, disabled = false, getFilesFromEvent = file_selector.fromEvent, maxSize = Number.POSITIVE_INFINITY, minSize = 0, multiple = true, maxFiles = 0, onDragEnter, onDragLeave, onDragOver, onDrop, onDropAccepted, onDropRejected, onFileDialogCancel, onFileDialogOpen, useFsAccessApi = false, autoFocus = false, preventDropOnDocument = true, noClick = false, noKeyboard = false, noDrag = false, noDragEventsBubbling = false, onError, validator, getErrorMessage } = props;
303
314
  const acceptAttr = (0, react.useMemo)(() => acceptPropAsAcceptAttr(accept), [accept]);
304
315
  const inputAcceptAttr = (0, react.useMemo)(() => acceptPropAsAcceptAttr(accept, { omitWildcardMimeTypesWithExtensions: true }), [accept]);
305
316
  const pickerTypes = (0, react.useMemo)(() => pickerOptionsFromAccept(accept), [accept]);
@@ -476,6 +487,10 @@ function useDropzone(props = {}) {
476
487
  const setFiles = (0, react.useCallback)((files, event) => {
477
488
  const acceptedFiles = [];
478
489
  const fileRejections = [];
490
+ const localizeError = (error, file) => getErrorMessage ? {
491
+ ...error,
492
+ message: getErrorMessage(error, file)
493
+ } : error;
479
494
  files.forEach((file) => {
480
495
  const [accepted, acceptError] = fileAccepted(file, inputAcceptAttr);
481
496
  const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);
@@ -486,7 +501,7 @@ function useDropzone(props = {}) {
486
501
  if (customErrors) errors = errors.concat(customErrors);
487
502
  fileRejections.push({
488
503
  file,
489
- errors: errors.filter((e) => e != null)
504
+ errors: errors.filter((e) => e != null).map((error) => localizeError(error, file))
490
505
  });
491
506
  }
492
507
  });
@@ -494,7 +509,7 @@ function useDropzone(props = {}) {
494
509
  acceptedFiles.forEach((file) => {
495
510
  fileRejections.push({
496
511
  file,
497
- errors: [TOO_MANY_FILES_REJECTION]
512
+ errors: [localizeError(TOO_MANY_FILES_REJECTION, file)]
498
513
  });
499
514
  });
500
515
  acceptedFiles.splice(0);
@@ -517,7 +532,8 @@ function useDropzone(props = {}) {
517
532
  onDrop,
518
533
  onDropAccepted,
519
534
  onDropRejected,
520
- validator
535
+ validator,
536
+ getErrorMessage
521
537
  ]);
522
538
  const onDropCb = (0, react.useCallback)((event) => {
523
539
  event.preventDefault();
@@ -550,7 +566,7 @@ function useDropzone(props = {}) {
550
566
  if (isAbort(e)) {
551
567
  onFileDialogCancelCb(e);
552
568
  dispatch({ type: "closeDialog" });
553
- } else if (isSecurityError(e)) {
569
+ } else if (isSecurityError(e) || isNotAllowedError(e)) {
554
570
  fsAccessApiWorksRef.current = false;
555
571
  if (inputRef.current) {
556
572
  inputRef.current.value = "";
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["attrAccept","fromEvent"],"sources":["../src/utils/index.ts","../src/index.tsx"],"sourcesContent":["import attrAccept from \"attr-accept\";\n\n// attr-accept ships as a CommonJS module (`module.exports = { __esModule: true, default: fn }`).\n// Bundler interop surfaces its default export inconsistently — as the function under Node/Vitest,\n// but as `{ default: fn }` in some browser bundles. Normalize to the function.\nconst accepts =\n typeof attrAccept === \"function\" ? attrAccept : (attrAccept as unknown as {default: typeof attrAccept}).default;\n\n/**\n * A map of accepted MIME types to file extensions, as passed to the `accept` prop.\n */\nexport interface Accept {\n [key: string]: readonly string[];\n}\n\n/**\n * A file rejection error.\n */\nexport interface FileError {\n message: string;\n code: ErrorCode | string;\n}\n\n// Error codes\nexport const FILE_INVALID_TYPE = \"file-invalid-type\";\nexport const FILE_TOO_LARGE = \"file-too-large\";\nexport const FILE_TOO_SMALL = \"file-too-small\";\nexport const TOO_MANY_FILES = \"too-many-files\";\n\nexport enum ErrorCode {\n FileInvalidType = \"file-invalid-type\",\n FileTooLarge = \"file-too-large\",\n FileTooSmall = \"file-too-small\",\n TooManyFiles = \"too-many-files\"\n}\n\nexport function getInvalidTypeRejectionErr(accept: string = \"\"): FileError {\n const acceptArr = accept.split(\",\");\n const msg = acceptArr.length > 1 ? `one of ${acceptArr.join(\", \")}` : acceptArr[0];\n\n return {\n code: FILE_INVALID_TYPE,\n message: `File type must be ${msg}`\n };\n}\n\nconst FILE_SIZE_UNITS = [\"KB\", \"MB\", \"GB\", \"TB\", \"PB\"];\n\n/**\n * Format a byte count into a human-readable string, e.g. `1111` -> `1.08 KB`.\n * Values below 1 KB are kept in bytes to preserve the singular/plural wording.\n */\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} ${bytes === 1 ? \"byte\" : \"bytes\"}`;\n }\n\n let size = bytes / 1024;\n let unitIndex = 0;\n while (size >= 1024 && unitIndex < FILE_SIZE_UNITS.length - 1) {\n size /= 1024;\n unitIndex++;\n }\n\n // Round to 2 decimals, then drop trailing zeros (1.00 -> 1, 1.50 -> 1.5).\n return `${Number(size.toFixed(2))} ${FILE_SIZE_UNITS[unitIndex]}`;\n}\n\nexport function getTooLargeRejectionErr(maxSize: number): FileError {\n return {\n code: FILE_TOO_LARGE,\n message: `File is larger than ${formatBytes(maxSize)}`\n };\n}\n\nexport function getTooSmallRejectionErr(minSize: number): FileError {\n return {\n code: FILE_TOO_SMALL,\n message: `File is smaller than ${formatBytes(minSize)}`\n };\n}\n\nexport const TOO_MANY_FILES_REJECTION: FileError = {\n code: TOO_MANY_FILES,\n message: \"Too many files\"\n};\n\n/**\n * Check if the given file is a DataTransferItem with an empty type.\n *\n * During drag events, browsers may return DataTransferItem objects instead of File objects.\n * Some browsers (e.g., Chrome) return an empty MIME type for certain file types (like .md files)\n * on DataTransferItem during drag events, even though the type is correctly set during drop.\n */\nexport function isDataTransferItemWithEmptyType(file: File | DataTransferItem): boolean {\n return file.type === \"\" && typeof (file as DataTransferItem).getAsFile === \"function\";\n}\n\n/**\n * Check if file is accepted.\n *\n * Firefox versions prior to 53 return a bogus MIME type for every file drag,\n * so dragovers with that MIME type will always be accepted.\n *\n * Chrome/other browsers may return an empty MIME type for files during drag events,\n * so we accept those as well (we'll validate properly on drop).\n */\nexport function fileAccepted(file: File, accept?: string): [boolean, FileError | null] {\n const isAcceptable =\n file.type === \"application/x-moz-file\" || accepts(file, accept ?? \"\") || isDataTransferItemWithEmptyType(file);\n return [isAcceptable, isAcceptable ? null : getInvalidTypeRejectionErr(accept)];\n}\n\nexport function fileMatchSize(\n file: {size?: number | null},\n minSize?: number,\n maxSize?: number\n): [boolean, FileError | null] {\n if (isDefined(file.size)) {\n if (isDefined(minSize) && isDefined(maxSize)) {\n if (file.size > maxSize) return [false, getTooLargeRejectionErr(maxSize)];\n if (file.size < minSize) return [false, getTooSmallRejectionErr(minSize)];\n } else if (isDefined(minSize) && file.size < minSize) {\n return [false, getTooSmallRejectionErr(minSize)];\n } else if (isDefined(maxSize) && file.size > maxSize) {\n return [false, getTooLargeRejectionErr(maxSize)];\n }\n }\n return [true, null];\n}\n\nfunction isDefined<T>(value: T): value is NonNullable<T> {\n return value !== undefined && value !== null;\n}\n\nexport function allFilesAccepted({\n files,\n accept,\n minSize,\n maxSize,\n multiple,\n maxFiles = 0,\n validator\n}: {\n files: File[];\n accept?: string;\n minSize?: number;\n maxSize?: number;\n multiple?: boolean;\n maxFiles?: number;\n validator?: (file: File) => FileError | readonly FileError[] | null;\n}): boolean {\n if ((!multiple && files.length > 1) || (multiple && maxFiles >= 1 && files.length > maxFiles)) {\n return false;\n }\n\n return files.every(file => {\n const [accepted] = fileAccepted(file, accept);\n const [sizeMatch] = fileMatchSize(file, minSize, maxSize);\n const customErrors = validator ? validator(file) : null;\n return accepted && sizeMatch && !customErrors;\n });\n}\n\n// React's synthetic events has event.isPropagationStopped,\n// but to remain compatibility with other libs (Preact) fall back\n// to check event.cancelBubble\nexport function isPropagationStopped(event: any): boolean {\n if (typeof event.isPropagationStopped === \"function\") {\n return event.isPropagationStopped();\n } else if (typeof event.cancelBubble !== \"undefined\") {\n return event.cancelBubble;\n }\n return false;\n}\n\nexport function isEvtWithFiles(event: any): boolean {\n if (!event.dataTransfer) {\n return !!event.target && !!event.target.files;\n }\n // https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/types\n // https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#file\n return Array.prototype.some.call(\n event.dataTransfer.types,\n (type: string) => type === \"Files\" || type === \"application/x-moz-file\"\n );\n}\n\nexport function isKindFile(item: any): boolean {\n return typeof item === \"object\" && item !== null && item.kind === \"file\";\n}\n\n// allow the entire document to be a drag target\nexport function onDocumentDragOver(event: Event): void {\n event.preventDefault();\n}\n\nfunction isIe(userAgent: string): boolean {\n return userAgent.indexOf(\"MSIE\") !== -1 || userAgent.indexOf(\"Trident/\") !== -1;\n}\n\nfunction isEdge(userAgent: string): boolean {\n return userAgent.indexOf(\"Edge/\") !== -1;\n}\n\nexport function isIeOrEdge(userAgent: string = window.navigator.userAgent): boolean {\n return isIe(userAgent) || isEdge(userAgent);\n}\n\n/**\n * This is intended to be used to compose event handlers.\n * They are executed in order until one of them calls `event.isPropagationStopped()`.\n * Note that the check is done on the first invoke too,\n * meaning that if propagation was stopped before invoking the fns,\n * no handlers will be executed.\n */\nexport function composeEventHandlers(\n ...fns: Array<((event: any, ...args: any[]) => void) | null | undefined>\n): (event: any, ...args: any[]) => boolean {\n return (event: any, ...args: any[]) =>\n fns.some(fn => {\n if (!isPropagationStopped(event) && fn) {\n fn(event, ...args);\n }\n return isPropagationStopped(event);\n });\n}\n\n/**\n * canUseFileSystemAccessAPI checks if the File System Access API is supported by the browser.\n */\nexport function canUseFileSystemAccessAPI(): boolean {\n return \"showOpenFilePicker\" in window;\n}\n\n/**\n * Convert the `{accept}` dropzone prop to the `{types}` option for showOpenFilePicker.\n */\nexport function pickerOptionsFromAccept(accept?: Accept): Array<{description: string; accept: Accept}> | undefined {\n if (isDefined(accept)) {\n const acceptForPicker = Object.entries(accept)\n .filter(([mimeType, ext]) => {\n let ok = true;\n\n if (!isMIMEType(mimeType)) {\n console.warn(\n `Skipped \"${mimeType}\" because it is not a valid MIME type. Check https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types for a list of valid MIME types.`\n );\n ok = false;\n }\n\n if (!Array.isArray(ext) || !ext.every(isExt)) {\n console.warn(`Skipped \"${mimeType}\" because an invalid file extension was provided.`);\n ok = false;\n }\n\n return ok;\n })\n .reduce<Accept>((agg, [mimeType, ext]) => {\n agg[mimeType] = ext;\n return agg;\n }, {});\n return [\n {\n // description is required due to https://crbug.com/1264708\n description: \"Files\",\n accept: acceptForPicker\n }\n ];\n }\n return undefined;\n}\n\n/**\n * Convert the `{accept}` dropzone prop to a comma-separated accept attribute string.\n *\n * When `omitWildcardMimeTypesWithExtensions` is set, a wildcard MIME type (e.g. `image/*`)\n * that is paired with explicit extensions is dropped in favour of those extensions. The\n * accept attribute is an OR list, so leaving `image/*` in would make both the native file\n * picker and the drop-time validator accept ANY file of that type, ignoring the extension\n * restriction. The drag-time `isDragAccept` check keeps the wildcard because file names\n * (and therefore extensions) aren't readable during a drag.\n *\n * See https://github.com/react-dropzone/react-dropzone/issues/1220\n */\nexport function acceptPropAsAcceptAttr(\n accept?: Accept,\n {omitWildcardMimeTypesWithExtensions = false}: {omitWildcardMimeTypesWithExtensions?: boolean} = {}\n): string | undefined {\n if (isDefined(accept)) {\n return (\n Object.entries(accept)\n .reduce<string[]>((a, [mimeType, ext]) => {\n if (omitWildcardMimeTypesWithExtensions && isMIMETypeWildcard(mimeType) && ext.some(isExt)) {\n a.push(...ext);\n } else {\n a.push(mimeType, ...ext);\n }\n return a;\n }, [])\n // Silently discard invalid entries as pickerOptionsFromAccept warns about these\n .filter(v => isMIMEType(v) || isExt(v))\n .join(\",\")\n );\n }\n\n return undefined;\n}\n\n/**\n * Check if v is an exception caused by aborting a request (e.g window.showOpenFilePicker()).\n */\nexport function isAbort(v: any): boolean {\n return v instanceof DOMException && (v.name === \"AbortError\" || v.code === v.ABORT_ERR);\n}\n\n/**\n * Check if v is a security error.\n */\nexport function isSecurityError(v: any): boolean {\n return v instanceof DOMException && (v.name === \"SecurityError\" || v.code === v.SECURITY_ERR);\n}\n\n/**\n * Check if v is a MIME type string.\n */\nexport function isMIMEType(v: string): boolean {\n return (\n v === \"audio/*\" ||\n v === \"video/*\" ||\n v === \"image/*\" ||\n v === \"text/*\" ||\n v === \"application/*\" ||\n /\\w+\\/[-+.\\w]+/g.test(v)\n );\n}\n\n/**\n * Check if v is a wildcard MIME type (e.g. `image/*`).\n */\nexport function isMIMETypeWildcard(v: string): boolean {\n return v.endsWith(\"/*\");\n}\n\n/**\n * Check if v is a file extension.\n */\nexport function isExt(v: string): boolean {\n return /^.*\\.[\\w]+$/.test(v);\n}\n","import {fromEvent} from \"file-selector\";\nimport type {FileWithPath} from \"file-selector\";\nimport type * as React from \"react\";\nimport {forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useReducer, useRef} from \"react\";\nimport {\n acceptPropAsAcceptAttr,\n allFilesAccepted,\n canUseFileSystemAccessAPI,\n composeEventHandlers,\n ErrorCode,\n fileAccepted,\n fileMatchSize,\n isAbort,\n isEvtWithFiles,\n isIeOrEdge,\n isPropagationStopped,\n isSecurityError,\n onDocumentDragOver,\n pickerOptionsFromAccept,\n TOO_MANY_FILES_REJECTION\n} from \"./utils\";\nimport type {Accept, FileError} from \"./utils\";\n\nexport type {Accept, FileError, FileWithPath};\nexport {ErrorCode};\n\nexport interface DropzoneProps extends DropzoneOptions {\n children?: (state: DropzoneState) => React.ReactElement;\n}\n\nexport interface FileRejection {\n file: FileWithPath;\n errors: readonly FileError[];\n}\n\ntype SharedProps = \"multiple\" | \"onDragEnter\" | \"onDragOver\" | \"onDragLeave\";\n\nexport type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> & {\n accept?: Accept;\n minSize?: number;\n maxSize?: number;\n maxFiles?: number;\n preventDropOnDocument?: boolean;\n noClick?: boolean;\n noKeyboard?: boolean;\n noDrag?: boolean;\n noDragEventsBubbling?: boolean;\n disabled?: boolean;\n onDrop?: <T extends File>(acceptedFiles: T[], fileRejections: FileRejection[], event: DropEvent) => void;\n onDropAccepted?: <T extends File>(files: T[], event: DropEvent) => void;\n onDropRejected?: (fileRejections: FileRejection[], event: DropEvent) => void;\n getFilesFromEvent?: (event: DropEvent | Array<FileSystemFileHandle>) => Promise<Array<File | DataTransferItem>>;\n onFileDialogCancel?: () => void;\n onFileDialogOpen?: () => void;\n onError?: (err: Error) => void;\n validator?: <T extends File>(file: T) => FileError | readonly FileError[] | null;\n useFsAccessApi?: boolean;\n autoFocus?: boolean;\n};\n\nexport type DropEvent = React.DragEvent<HTMLElement> | React.ChangeEvent<HTMLInputElement> | DragEvent | Event;\n\nexport interface DropzoneRef {\n open: () => void;\n}\n\nexport type DropzoneState = DropzoneRef & {\n isFocused: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragGlobal: boolean;\n isFileDialogActive: boolean;\n acceptedFiles: readonly FileWithPath[];\n fileRejections: readonly FileRejection[];\n rootRef: React.RefObject<HTMLElement>;\n inputRef: React.RefObject<HTMLInputElement>;\n getRootProps: <T extends DropzoneRootProps>(props?: T) => T;\n getInputProps: <T extends DropzoneInputProps>(props?: T) => T;\n};\n\nexport interface DropzoneRootProps extends React.HTMLAttributes<HTMLElement> {\n refKey?: string;\n [key: string]: any;\n}\n\nexport interface DropzoneInputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n refKey?: string;\n}\n\n/**\n * Convenience wrapper component for the `useDropzone` hook\n *\n * ```jsx\n * <Dropzone>\n * {({getRootProps, getInputProps}) => (\n * <div {...getRootProps()}>\n * <input {...getInputProps()} />\n * <p>Drag 'n' drop some files here, or click to select files</p>\n * </div>\n * )}\n * </Dropzone>\n * ```\n */\nconst Dropzone: React.ForwardRefExoticComponent<DropzoneProps & React.RefAttributes<DropzoneRef>> = forwardRef<\n DropzoneRef,\n DropzoneProps\n>(({children, ...params}, ref) => {\n const {open, ...props} = useDropzone(params);\n\n useImperativeHandle(ref, () => ({open}), [open]);\n\n return <>{children?.({...props, open})}</>;\n});\n\nDropzone.displayName = \"Dropzone\";\n\nexport default Dropzone;\n\ninterface DropzoneInternalState {\n isFocused: boolean;\n isFileDialogActive: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragGlobal: boolean;\n acceptedFiles: FileWithPath[];\n fileRejections: FileRejection[];\n}\n\nconst initialState: DropzoneInternalState = {\n isFocused: false,\n isFileDialogActive: false,\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false,\n isDragGlobal: false,\n acceptedFiles: [],\n fileRejections: []\n};\n\n/**\n * A React hook that creates a drag 'n' drop area.\n *\n * ```jsx\n * function MyDropzone(props) {\n * const {getRootProps, getInputProps} = useDropzone({\n * onDrop: acceptedFiles => {\n * // do something with the File objects, e.g. upload to some server\n * }\n * });\n * return (\n * <div {...getRootProps()}>\n * <input {...getInputProps()} />\n * <p>Drag and drop some files here, or click to select files</p>\n * </div>\n * )\n * }\n * ```\n */\nexport function useDropzone(props: DropzoneOptions = {}): DropzoneState {\n const {\n accept,\n disabled = false,\n getFilesFromEvent = fromEvent,\n maxSize = Number.POSITIVE_INFINITY,\n minSize = 0,\n multiple = true,\n maxFiles = 0,\n onDragEnter,\n onDragLeave,\n onDragOver,\n onDrop,\n onDropAccepted,\n onDropRejected,\n onFileDialogCancel,\n onFileDialogOpen,\n useFsAccessApi = false,\n autoFocus = false,\n preventDropOnDocument = true,\n noClick = false,\n noKeyboard = false,\n noDrag = false,\n noDragEventsBubbling = false,\n onError,\n validator\n } = props;\n\n // `acceptAttr` keeps wildcard MIME types (e.g. `image/*`) so the drag-time\n // `isDragAccept`/`isDragReject` check can react to a file's MIME type - file names\n // (hence extensions) aren't readable during a drag.\n const acceptAttr = useMemo(() => acceptPropAsAcceptAttr(accept), [accept]);\n // `inputAcceptAttr` drops a wildcard MIME type when it is paired with extensions, so the\n // native picker and drop-time validation enforce the extensions instead of accepting any\n // file of that type. See https://github.com/react-dropzone/react-dropzone/issues/1220\n const inputAcceptAttr = useMemo(\n () =>\n acceptPropAsAcceptAttr(accept, {\n omitWildcardMimeTypesWithExtensions: true\n }),\n [accept]\n );\n const pickerTypes = useMemo(() => pickerOptionsFromAccept(accept), [accept]);\n\n const onFileDialogOpenCb = useMemo<(...args: any[]) => void>(\n () => (typeof onFileDialogOpen === \"function\" ? onFileDialogOpen : noop),\n [onFileDialogOpen]\n );\n const onFileDialogCancelCb = useMemo<(...args: any[]) => void>(\n () => (typeof onFileDialogCancel === \"function\" ? onFileDialogCancel : noop),\n [onFileDialogCancel]\n );\n\n const rootRef = useRef<HTMLElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [state, dispatch] = useReducer(reducer, initialState);\n const {isFocused, isFileDialogActive} = state;\n\n const fsAccessApiWorksRef = useRef(\n typeof window !== \"undefined\" && window.isSecureContext && useFsAccessApi && canUseFileSystemAccessAPI()\n );\n\n // Update file dialog active state when the window is focused on\n const onWindowFocus = () => {\n // Execute the timeout only if the file dialog is opened in the browser\n if (!fsAccessApiWorksRef.current && isFileDialogActive) {\n setTimeout(() => {\n if (inputRef.current) {\n const {files} = inputRef.current;\n\n if (!files?.length) {\n dispatch({type: \"closeDialog\"});\n onFileDialogCancelCb();\n }\n }\n }, 300);\n }\n };\n useEffect(() => {\n window.addEventListener(\"focus\", onWindowFocus, false);\n return () => {\n window.removeEventListener(\"focus\", onWindowFocus, false);\n };\n }, [inputRef, isFileDialogActive, onFileDialogCancelCb, fsAccessApiWorksRef]);\n\n const dragTargetsRef = useRef<EventTarget[]>([]);\n const globalDragTargetsRef = useRef<EventTarget[]>([]);\n const onDocumentDrop = (event: DragEvent) => {\n if (rootRef.current && event.target && rootRef.current.contains(event.target as Node)) {\n // If we intercepted an event for our instance, let it propagate down to the instance's onDrop handler\n return;\n }\n event.preventDefault();\n dragTargetsRef.current = [];\n };\n\n useEffect(() => {\n if (preventDropOnDocument) {\n document.addEventListener(\"dragover\", onDocumentDragOver, false);\n document.addEventListener(\"drop\", onDocumentDrop, false);\n }\n\n return () => {\n if (preventDropOnDocument) {\n document.removeEventListener(\"dragover\", onDocumentDragOver);\n document.removeEventListener(\"drop\", onDocumentDrop);\n }\n };\n }, [rootRef, preventDropOnDocument]);\n\n // Track global drag state for document-level drag events\n useEffect(() => {\n const onDocumentDragEnter = (event: DragEvent) => {\n if (event.target) {\n globalDragTargetsRef.current = [...globalDragTargetsRef.current, event.target];\n }\n\n if (isEvtWithFiles(event)) {\n dispatch({isDragGlobal: true, type: \"setDragGlobal\"});\n }\n };\n\n const onDocumentDragLeave = (event: DragEvent) => {\n // Only deactivate once we've left all children\n globalDragTargetsRef.current = globalDragTargetsRef.current.filter(el => el !== event.target && el !== null);\n\n if (globalDragTargetsRef.current.length > 0) {\n return;\n }\n\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDragEnd = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDropGlobal = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n document.addEventListener(\"dragenter\", onDocumentDragEnter, false);\n document.addEventListener(\"dragleave\", onDocumentDragLeave, false);\n document.addEventListener(\"dragend\", onDocumentDragEnd, false);\n document.addEventListener(\"drop\", onDocumentDropGlobal, false);\n\n return () => {\n document.removeEventListener(\"dragenter\", onDocumentDragEnter);\n document.removeEventListener(\"dragleave\", onDocumentDragLeave);\n document.removeEventListener(\"dragend\", onDocumentDragEnd);\n document.removeEventListener(\"drop\", onDocumentDropGlobal);\n };\n }, [rootRef]);\n\n // Auto focus the root when autoFocus is true\n useEffect(() => {\n if (!disabled && autoFocus && rootRef.current) {\n rootRef.current.focus();\n }\n return () => {};\n }, [rootRef, autoFocus, disabled]);\n\n const onErrCb = useCallback(\n (e: Error) => {\n if (onError) {\n onError(e);\n } else {\n // Let the user know something's gone wrong if they haven't provided the onError cb.\n console.error(e);\n }\n },\n [onError]\n );\n\n const onDragEnterCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n dragTargetsRef.current = [...dragTargetsRef.current, event.target];\n\n if (isEvtWithFiles(event)) {\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n return;\n }\n\n const fileCount = files.length;\n const isDragAccept =\n fileCount > 0 &&\n allFilesAccepted({\n files: files as File[],\n accept: acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n });\n const isDragReject = fileCount > 0 && !isDragAccept;\n\n dispatch({\n isDragAccept,\n isDragReject,\n isDragActive: true,\n type: \"setDraggedFiles\"\n });\n\n if (onDragEnter) {\n onDragEnter(event);\n }\n })\n .catch(e => onErrCb(e));\n }\n },\n [\n getFilesFromEvent,\n onDragEnter,\n onErrCb,\n noDragEventsBubbling,\n acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n ]\n );\n\n const onDragOverCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n const hasFiles = isEvtWithFiles(event);\n if (hasFiles && event.dataTransfer) {\n try {\n event.dataTransfer.dropEffect = \"copy\";\n } catch {\n /* no-op */\n }\n }\n\n if (hasFiles && onDragOver) {\n onDragOver(event);\n }\n\n return false;\n },\n [onDragOver, noDragEventsBubbling]\n );\n\n const onDragLeaveCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n // Only deactivate once the dropzone and all children have been left\n const targets = dragTargetsRef.current.filter(target => rootRef.current?.contains(target as Node));\n // Make sure to remove a target present multiple times only once\n // (Firefox may fire dragenter/dragleave multiple times on the same element)\n const targetIdx = targets.indexOf(event.target);\n if (targetIdx !== -1) {\n targets.splice(targetIdx, 1);\n }\n dragTargetsRef.current = targets;\n if (targets.length > 0) {\n return;\n }\n\n dispatch({\n type: \"setDraggedFiles\",\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false\n });\n\n if (isEvtWithFiles(event) && onDragLeave) {\n onDragLeave(event);\n }\n },\n [rootRef, onDragLeave, noDragEventsBubbling]\n );\n\n const setFiles = useCallback(\n (files: FileWithPath[], event: any) => {\n const acceptedFiles: FileWithPath[] = [];\n const fileRejections: FileRejection[] = [];\n\n files.forEach(file => {\n const [accepted, acceptError] = fileAccepted(file, inputAcceptAttr);\n const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);\n const customErrors = validator ? validator(file) : null;\n\n if (accepted && sizeMatch && !customErrors) {\n acceptedFiles.push(file);\n } else {\n let errors: Array<FileError | null> = [acceptError, sizeError];\n\n if (customErrors) {\n errors = errors.concat(customErrors);\n }\n\n fileRejections.push({\n file,\n errors: errors.filter((e): e is FileError => e != null)\n });\n }\n });\n\n if ((!multiple && acceptedFiles.length > 1) || (multiple && maxFiles >= 1 && acceptedFiles.length > maxFiles)) {\n // Reject everything and empty accepted files\n acceptedFiles.forEach(file => {\n fileRejections.push({file, errors: [TOO_MANY_FILES_REJECTION]});\n });\n acceptedFiles.splice(0);\n }\n\n dispatch({\n acceptedFiles,\n fileRejections,\n type: \"setFiles\"\n });\n\n if (onDrop) {\n onDrop(acceptedFiles, fileRejections, event);\n }\n\n if (fileRejections.length > 0 && onDropRejected) {\n onDropRejected(fileRejections, event);\n }\n\n if (acceptedFiles.length > 0 && onDropAccepted) {\n onDropAccepted(acceptedFiles, event);\n }\n },\n [dispatch, multiple, inputAcceptAttr, minSize, maxSize, maxFiles, onDrop, onDropAccepted, onDropRejected, validator]\n );\n\n const onDropCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n dragTargetsRef.current = [];\n\n if (isEvtWithFiles(event)) {\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n return;\n }\n setFiles(files as FileWithPath[], event);\n })\n .catch(e => onErrCb(e));\n }\n dispatch({type: \"reset\"});\n },\n [getFilesFromEvent, setFiles, onErrCb, noDragEventsBubbling]\n );\n\n // Fn for opening the file dialog programmatically\n const openFileDialog = useCallback(() => {\n // No point to use FS access APIs if context is not secure\n // https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#feature_detection\n if (fsAccessApiWorksRef.current) {\n dispatch({type: \"openDialog\"});\n onFileDialogOpenCb();\n // https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker\n const opts = {\n multiple,\n types: pickerTypes\n };\n (window as any)\n .showOpenFilePicker(opts)\n .then((handles: any) => getFilesFromEvent(handles))\n .then((files: Array<File | DataTransferItem>) => {\n setFiles(files as FileWithPath[], null);\n dispatch({type: \"closeDialog\"});\n })\n .catch((e: any) => {\n // AbortError means the user canceled\n if (isAbort(e)) {\n onFileDialogCancelCb(e);\n dispatch({type: \"closeDialog\"});\n } else if (isSecurityError(e)) {\n fsAccessApiWorksRef.current = false;\n // CORS, so cannot use this API\n // Try using the input\n if (inputRef.current) {\n inputRef.current.value = \"\";\n inputRef.current.click();\n } else {\n onErrCb(\n new Error(\n \"Cannot open the file picker because the https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API is not supported and no <input> was provided.\"\n )\n );\n }\n } else {\n onErrCb(e);\n }\n });\n return;\n }\n\n if (inputRef.current) {\n dispatch({type: \"openDialog\"});\n onFileDialogOpenCb();\n inputRef.current.value = \"\";\n inputRef.current.click();\n }\n }, [dispatch, onFileDialogOpenCb, onFileDialogCancelCb, useFsAccessApi, setFiles, onErrCb, pickerTypes, multiple]);\n\n // Cb to open the file dialog when SPACE/ENTER occurs on the dropzone\n const onKeyDownCb = useCallback(\n (event: any) => {\n // Ignore keyboard events bubbling up the DOM tree\n if (!rootRef.current?.isEqualNode(event.target)) {\n return;\n }\n\n if (event.key === \" \" || event.key === \"Enter\" || event.keyCode === 32 || event.keyCode === 13) {\n event.preventDefault();\n openFileDialog();\n }\n },\n [rootRef, openFileDialog]\n );\n\n // Update focus state for the dropzone\n const onFocusCb = useCallback(() => {\n dispatch({type: \"focus\"});\n }, []);\n const onBlurCb = useCallback(() => {\n dispatch({type: \"blur\"});\n }, []);\n\n // Cb to open the file dialog when click occurs on the dropzone\n const onClickCb = useCallback(() => {\n if (noClick) {\n return;\n }\n\n // In IE11/Edge the file-browser dialog is blocking, therefore, use setTimeout()\n // to ensure React can handle state changes\n // See: https://github.com/react-dropzone/react-dropzone/issues/450\n if (isIeOrEdge()) {\n setTimeout(openFileDialog, 0);\n } else {\n openFileDialog();\n }\n }, [noClick, openFileDialog]);\n\n const composeHandler = (fn: any) => {\n return disabled ? null : fn;\n };\n\n const composeKeyboardHandler = (fn: any) => {\n return noKeyboard ? null : composeHandler(fn);\n };\n\n const composeDragHandler = (fn: any) => {\n return noDrag ? null : composeHandler(fn);\n };\n\n const stopPropagation = (event: any) => {\n if (noDragEventsBubbling) {\n event.stopPropagation();\n }\n };\n\n const getRootProps = useMemo(\n () =>\n ({\n refKey = \"ref\",\n role,\n onKeyDown,\n onFocus,\n onBlur,\n onClick,\n onDragEnter,\n onDragOver,\n onDragLeave,\n onDrop,\n ...rest\n }: DropzoneRootProps = {}) => ({\n onKeyDown: composeKeyboardHandler(composeEventHandlers(onKeyDown, onKeyDownCb)),\n onFocus: composeKeyboardHandler(composeEventHandlers(onFocus, onFocusCb)),\n onBlur: composeKeyboardHandler(composeEventHandlers(onBlur, onBlurCb)),\n onClick: composeHandler(composeEventHandlers(onClick, onClickCb)),\n onDragEnter: composeDragHandler(composeEventHandlers(onDragEnter, onDragEnterCb)),\n onDragOver: composeDragHandler(composeEventHandlers(onDragOver, onDragOverCb)),\n onDragLeave: composeDragHandler(composeEventHandlers(onDragLeave, onDragLeaveCb)),\n onDrop: composeDragHandler(composeEventHandlers(onDrop, onDropCb)),\n role: typeof role === \"string\" && role !== \"\" ? role : \"presentation\",\n [refKey]: rootRef,\n ...(!disabled && !noKeyboard ? {tabIndex: 0} : {}),\n ...(disabled ? {\"aria-disabled\": true} : {}),\n ...rest\n }),\n [\n rootRef,\n onKeyDownCb,\n onFocusCb,\n onBlurCb,\n onClickCb,\n onDragEnterCb,\n onDragOverCb,\n onDragLeaveCb,\n onDropCb,\n noKeyboard,\n noDrag,\n disabled\n ]\n );\n\n const onInputElementClick = useCallback((event: any) => {\n event.stopPropagation();\n }, []);\n\n const getInputProps = useMemo(\n () =>\n ({refKey = \"ref\", onChange, onClick, ...rest}: DropzoneInputProps = {}) => {\n const inputProps = {\n accept: inputAcceptAttr,\n multiple,\n type: \"file\",\n \"aria-label\": \"file upload\",\n style: {\n border: 0,\n clip: \"rect(0, 0, 0, 0)\",\n clipPath: \"inset(50%)\",\n height: \"1px\",\n margin: \"0 -1px -1px 0\",\n overflow: \"hidden\",\n padding: 0,\n position: \"absolute\",\n width: \"1px\",\n whiteSpace: \"nowrap\"\n },\n onChange: composeHandler(composeEventHandlers(onChange, onDropCb)),\n onClick: composeHandler(composeEventHandlers(onClick, onInputElementClick)),\n tabIndex: -1,\n [refKey]: inputRef\n };\n\n return {\n ...inputProps,\n ...rest\n };\n },\n [inputRef, accept, multiple, onDropCb, disabled]\n );\n\n return {\n ...state,\n isFocused: isFocused && !disabled,\n getRootProps,\n getInputProps,\n rootRef,\n inputRef,\n open: composeHandler(openFileDialog)\n } as unknown as DropzoneState;\n}\n\nfunction reducer(state: DropzoneInternalState, action: any): DropzoneInternalState {\n switch (action.type) {\n case \"focus\":\n return {\n ...state,\n isFocused: true\n };\n case \"blur\":\n return {\n ...state,\n isFocused: false\n };\n case \"openDialog\":\n return {\n ...initialState,\n isFileDialogActive: true\n };\n case \"closeDialog\":\n return {\n ...state,\n isFileDialogActive: false\n };\n case \"setDraggedFiles\":\n return {\n ...state,\n isDragActive: action.isDragActive,\n isDragAccept: action.isDragAccept,\n isDragReject: action.isDragReject\n };\n case \"setFiles\":\n return {\n ...state,\n acceptedFiles: action.acceptedFiles,\n fileRejections: action.fileRejections,\n isDragReject: false\n };\n case \"setDragGlobal\":\n return {\n ...state,\n isDragGlobal: action.isDragGlobal\n };\n case \"reset\":\n return {\n ...initialState\n };\n default:\n return state;\n }\n}\n\nfunction noop() {}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["attrAccept","fromEvent"],"sources":["../src/utils/index.ts","../src/index.tsx"],"sourcesContent":["import attrAccept from \"attr-accept\";\n\n// attr-accept ships as a CommonJS module (`module.exports = { __esModule: true, default: fn }`).\n// Bundler interop surfaces its default export inconsistently — as the function under Node/Vitest,\n// but as `{ default: fn }` in some browser bundles. Normalize to the function.\nconst accepts =\n typeof attrAccept === \"function\" ? attrAccept : (attrAccept as unknown as {default: typeof attrAccept}).default;\n\n/**\n * A map of accepted MIME types to file extensions, as passed to the `accept` prop.\n */\nexport interface Accept {\n [key: string]: readonly string[];\n}\n\n/**\n * A file rejection error.\n */\nexport interface FileError {\n message: string;\n code: ErrorCode | string;\n}\n\n// Error codes\nexport const FILE_INVALID_TYPE = \"file-invalid-type\";\nexport const FILE_TOO_LARGE = \"file-too-large\";\nexport const FILE_TOO_SMALL = \"file-too-small\";\nexport const TOO_MANY_FILES = \"too-many-files\";\n\nexport enum ErrorCode {\n FileInvalidType = \"file-invalid-type\",\n FileTooLarge = \"file-too-large\",\n FileTooSmall = \"file-too-small\",\n TooManyFiles = \"too-many-files\"\n}\n\nexport function getInvalidTypeRejectionErr(accept: string = \"\"): FileError {\n const acceptArr = accept.split(\",\");\n const msg = acceptArr.length > 1 ? `one of ${acceptArr.join(\", \")}` : acceptArr[0];\n\n return {\n code: FILE_INVALID_TYPE,\n message: `File type must be ${msg}`\n };\n}\n\nconst FILE_SIZE_UNITS = [\"KB\", \"MB\", \"GB\", \"TB\", \"PB\"];\n\n/**\n * Format a byte count into a human-readable string, e.g. `1111` -> `1.08 KB`.\n * Values below 1 KB are kept in bytes to preserve the singular/plural wording.\n */\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} ${bytes === 1 ? \"byte\" : \"bytes\"}`;\n }\n\n let size = bytes / 1024;\n let unitIndex = 0;\n while (size >= 1024 && unitIndex < FILE_SIZE_UNITS.length - 1) {\n size /= 1024;\n unitIndex++;\n }\n\n // Round to 2 decimals, then drop trailing zeros (1.00 -> 1, 1.50 -> 1.5).\n return `${Number(size.toFixed(2))} ${FILE_SIZE_UNITS[unitIndex]}`;\n}\n\nexport function getTooLargeRejectionErr(maxSize: number): FileError {\n return {\n code: FILE_TOO_LARGE,\n message: `File is larger than ${formatBytes(maxSize)}`\n };\n}\n\nexport function getTooSmallRejectionErr(minSize: number): FileError {\n return {\n code: FILE_TOO_SMALL,\n message: `File is smaller than ${formatBytes(minSize)}`\n };\n}\n\nexport const TOO_MANY_FILES_REJECTION: FileError = {\n code: TOO_MANY_FILES,\n message: \"Too many files\"\n};\n\n/**\n * Check if the given file is a DataTransferItem with an empty type.\n *\n * During drag events, browsers may return DataTransferItem objects instead of File objects.\n * Some browsers (e.g., Chrome) return an empty MIME type for certain file types (like .md files)\n * on DataTransferItem during drag events, even though the type is correctly set during drop.\n */\nexport function isDataTransferItemWithEmptyType(file: File | DataTransferItem): boolean {\n return file.type === \"\" && typeof (file as DataTransferItem).getAsFile === \"function\";\n}\n\n/**\n * Check if file is accepted.\n *\n * Firefox versions prior to 53 return a bogus MIME type for every file drag,\n * so dragovers with that MIME type will always be accepted.\n *\n * Chrome/other browsers may return an empty MIME type for files during drag events,\n * so we accept those as well (we'll validate properly on drop).\n */\nexport function fileAccepted(file: File, accept?: string): [boolean, FileError | null] {\n const isAcceptable =\n file.type === \"application/x-moz-file\" || accepts(file, accept ?? \"\") || isDataTransferItemWithEmptyType(file);\n return [isAcceptable, isAcceptable ? null : getInvalidTypeRejectionErr(accept)];\n}\n\nexport function fileMatchSize(\n file: {size?: number | null},\n minSize?: number,\n maxSize?: number\n): [boolean, FileError | null] {\n if (isDefined(file.size)) {\n if (isDefined(minSize) && isDefined(maxSize)) {\n if (file.size > maxSize) return [false, getTooLargeRejectionErr(maxSize)];\n if (file.size < minSize) return [false, getTooSmallRejectionErr(minSize)];\n } else if (isDefined(minSize) && file.size < minSize) {\n return [false, getTooSmallRejectionErr(minSize)];\n } else if (isDefined(maxSize) && file.size > maxSize) {\n return [false, getTooLargeRejectionErr(maxSize)];\n }\n }\n return [true, null];\n}\n\nfunction isDefined<T>(value: T): value is NonNullable<T> {\n return value !== undefined && value !== null;\n}\n\nexport function allFilesAccepted({\n files,\n accept,\n minSize,\n maxSize,\n multiple,\n maxFiles = 0,\n validator\n}: {\n files: File[];\n accept?: string;\n minSize?: number;\n maxSize?: number;\n multiple?: boolean;\n maxFiles?: number;\n validator?: (file: File) => FileError | readonly FileError[] | null;\n}): boolean {\n if ((!multiple && files.length > 1) || (multiple && maxFiles >= 1 && files.length > maxFiles)) {\n return false;\n }\n\n return files.every(file => {\n const [accepted] = fileAccepted(file, accept);\n const [sizeMatch] = fileMatchSize(file, minSize, maxSize);\n const customErrors = validator ? validator(file) : null;\n return accepted && sizeMatch && !customErrors;\n });\n}\n\n// React's synthetic events has event.isPropagationStopped,\n// but to remain compatibility with other libs (Preact) fall back\n// to check event.cancelBubble\nexport function isPropagationStopped(event: any): boolean {\n if (typeof event.isPropagationStopped === \"function\") {\n return event.isPropagationStopped();\n } else if (typeof event.cancelBubble !== \"undefined\") {\n return event.cancelBubble;\n }\n return false;\n}\n\nexport function isEvtWithFiles(event: any): boolean {\n if (!event.dataTransfer) {\n return !!event.target && !!event.target.files;\n }\n // https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/types\n // https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#file\n return Array.prototype.some.call(\n event.dataTransfer.types,\n (type: string) => type === \"Files\" || type === \"application/x-moz-file\"\n );\n}\n\nexport function isKindFile(item: any): boolean {\n return typeof item === \"object\" && item !== null && item.kind === \"file\";\n}\n\n// allow the entire document to be a drag target\nexport function onDocumentDragOver(event: Event): void {\n event.preventDefault();\n}\n\nfunction isIe(userAgent: string): boolean {\n return userAgent.indexOf(\"MSIE\") !== -1 || userAgent.indexOf(\"Trident/\") !== -1;\n}\n\nfunction isEdge(userAgent: string): boolean {\n return userAgent.indexOf(\"Edge/\") !== -1;\n}\n\nexport function isIeOrEdge(userAgent: string = window.navigator.userAgent): boolean {\n return isIe(userAgent) || isEdge(userAgent);\n}\n\n/**\n * This is intended to be used to compose event handlers.\n * They are executed in order until one of them calls `event.isPropagationStopped()`.\n * Note that the check is done on the first invoke too,\n * meaning that if propagation was stopped before invoking the fns,\n * no handlers will be executed.\n */\nexport function composeEventHandlers(\n ...fns: Array<((event: any, ...args: any[]) => void) | null | undefined>\n): (event: any, ...args: any[]) => boolean {\n return (event: any, ...args: any[]) =>\n fns.some(fn => {\n if (!isPropagationStopped(event) && fn) {\n fn(event, ...args);\n }\n return isPropagationStopped(event);\n });\n}\n\n/**\n * canUseFileSystemAccessAPI checks if the File System Access API is supported by the browser.\n */\nexport function canUseFileSystemAccessAPI(): boolean {\n return \"showOpenFilePicker\" in window;\n}\n\n/**\n * Convert the `{accept}` dropzone prop to the `{types}` option for showOpenFilePicker.\n */\nexport function pickerOptionsFromAccept(accept?: Accept): Array<{description: string; accept: Accept}> | undefined {\n if (isDefined(accept)) {\n const acceptForPicker = Object.entries(accept)\n .filter(([mimeType, ext]) => {\n let ok = true;\n\n if (!isMIMEType(mimeType)) {\n console.warn(\n `Skipped \"${mimeType}\" because it is not a valid MIME type. Check https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types for a list of valid MIME types.`\n );\n ok = false;\n }\n\n if (!Array.isArray(ext) || !ext.every(isExt)) {\n console.warn(`Skipped \"${mimeType}\" because an invalid file extension was provided.`);\n ok = false;\n }\n\n return ok;\n })\n .reduce<Accept>((agg, [mimeType, ext]) => {\n agg[mimeType] = ext;\n return agg;\n }, {});\n return [\n {\n // description is required due to https://crbug.com/1264708\n description: \"Files\",\n accept: acceptForPicker\n }\n ];\n }\n return undefined;\n}\n\n/**\n * Convert the `{accept}` dropzone prop to a comma-separated accept attribute string.\n *\n * When `omitWildcardMimeTypesWithExtensions` is set, a wildcard MIME type (e.g. `image/*`)\n * that is paired with explicit extensions is dropped in favour of those extensions. The\n * accept attribute is an OR list, so leaving `image/*` in would make both the native file\n * picker and the drop-time validator accept ANY file of that type, ignoring the extension\n * restriction. The drag-time `isDragAccept` check keeps the wildcard because file names\n * (and therefore extensions) aren't readable during a drag.\n *\n * See https://github.com/react-dropzone/react-dropzone/issues/1220\n */\nexport function acceptPropAsAcceptAttr(\n accept?: Accept,\n {omitWildcardMimeTypesWithExtensions = false}: {omitWildcardMimeTypesWithExtensions?: boolean} = {}\n): string | undefined {\n if (isDefined(accept)) {\n return (\n Object.entries(accept)\n .reduce<string[]>((a, [mimeType, ext]) => {\n if (omitWildcardMimeTypesWithExtensions && isMIMETypeWildcard(mimeType) && ext.some(isExt)) {\n a.push(...ext);\n } else {\n a.push(mimeType, ...ext);\n }\n return a;\n }, [])\n // Silently discard invalid entries as pickerOptionsFromAccept warns about these\n .filter(v => isMIMEType(v) || isExt(v))\n .join(\",\")\n );\n }\n\n return undefined;\n}\n\n/**\n * Check if v is an exception caused by aborting a request (e.g window.showOpenFilePicker()).\n */\nexport function isAbort(v: any): boolean {\n return v instanceof DOMException && (v.name === \"AbortError\" || v.code === v.ABORT_ERR);\n}\n\n/**\n * Check if v is a security error.\n */\nexport function isSecurityError(v: any): boolean {\n return v instanceof DOMException && (v.name === \"SecurityError\" || v.code === v.SECURITY_ERR);\n}\n\n/**\n * Check if v is a \"not allowed\" error.\n *\n * Some browsers/configurations block `window.showOpenFilePicker()` outright and reject with a\n * `NotAllowedError` instead of showing the picker (e.g. Microsoft Edge for Business, or other\n * restrictive enterprise/security policies). We treat this like a security error and fall back\n * to the native `<input>`. See https://github.com/react-dropzone/react-dropzone/issues/1429\n */\nexport function isNotAllowedError(v: any): boolean {\n return v instanceof DOMException && v.name === \"NotAllowedError\";\n}\n\n/**\n * Check if v is a MIME type string.\n */\nexport function isMIMEType(v: string): boolean {\n return (\n v === \"audio/*\" ||\n v === \"video/*\" ||\n v === \"image/*\" ||\n v === \"text/*\" ||\n v === \"application/*\" ||\n /\\w+\\/[-+.\\w]+/g.test(v)\n );\n}\n\n/**\n * Check if v is a wildcard MIME type (e.g. `image/*`).\n */\nexport function isMIMETypeWildcard(v: string): boolean {\n return v.endsWith(\"/*\");\n}\n\n/**\n * Check if v is a file extension.\n */\nexport function isExt(v: string): boolean {\n return /^.*\\.[\\w]+$/.test(v);\n}\n","import {fromEvent} from \"file-selector\";\nimport type {FileWithPath} from \"file-selector\";\nimport type * as React from \"react\";\nimport {forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useReducer, useRef} from \"react\";\nimport {\n acceptPropAsAcceptAttr,\n allFilesAccepted,\n canUseFileSystemAccessAPI,\n composeEventHandlers,\n ErrorCode,\n fileAccepted,\n fileMatchSize,\n isAbort,\n isEvtWithFiles,\n isIeOrEdge,\n isNotAllowedError,\n isPropagationStopped,\n isSecurityError,\n onDocumentDragOver,\n pickerOptionsFromAccept,\n TOO_MANY_FILES_REJECTION\n} from \"./utils\";\nimport type {Accept, FileError} from \"./utils\";\n\nexport type {Accept, FileError, FileWithPath};\nexport {ErrorCode};\n\nexport interface DropzoneProps extends DropzoneOptions {\n children?: (state: DropzoneState) => React.ReactElement;\n}\n\nexport interface FileRejection {\n file: FileWithPath;\n errors: readonly FileError[];\n}\n\ntype SharedProps = \"multiple\" | \"onDragEnter\" | \"onDragOver\" | \"onDragLeave\";\n\nexport type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> & {\n accept?: Accept;\n minSize?: number;\n maxSize?: number;\n maxFiles?: number;\n preventDropOnDocument?: boolean;\n noClick?: boolean;\n noKeyboard?: boolean;\n noDrag?: boolean;\n noDragEventsBubbling?: boolean;\n disabled?: boolean;\n onDrop?: <T extends File>(acceptedFiles: T[], fileRejections: FileRejection[], event: DropEvent) => void;\n onDropAccepted?: <T extends File>(files: T[], event: DropEvent) => void;\n onDropRejected?: (fileRejections: FileRejection[], event: DropEvent) => void;\n getFilesFromEvent?: (event: DropEvent | Array<FileSystemFileHandle>) => Promise<Array<File | DataTransferItem>>;\n onFileDialogCancel?: () => void;\n onFileDialogOpen?: () => void;\n onError?: (err: Error) => void;\n validator?: <T extends File>(file: T) => FileError | readonly FileError[] | null;\n /**\n * Override the message of any rejection error (built-in or custom). Called once per error;\n * receives the error and the file it belongs to and returns the message to use. Return\n * `error.message` for codes you don't want to change. Useful for localizing error messages.\n */\n getErrorMessage?: (error: FileError, file: File) => string;\n useFsAccessApi?: boolean;\n autoFocus?: boolean;\n};\n\nexport type DropEvent = React.DragEvent<HTMLElement> | React.ChangeEvent<HTMLInputElement> | DragEvent | Event;\n\nexport interface DropzoneRef {\n open: () => void;\n}\n\nexport type DropzoneState = DropzoneRef & {\n isFocused: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragGlobal: boolean;\n isFileDialogActive: boolean;\n acceptedFiles: readonly FileWithPath[];\n fileRejections: readonly FileRejection[];\n rootRef: React.RefObject<HTMLElement>;\n inputRef: React.RefObject<HTMLInputElement>;\n getRootProps: <T extends DropzoneRootProps>(props?: T) => T;\n getInputProps: <T extends DropzoneInputProps>(props?: T) => T;\n};\n\nexport interface DropzoneRootProps extends React.HTMLAttributes<HTMLElement> {\n refKey?: string;\n [key: string]: any;\n}\n\nexport interface DropzoneInputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n refKey?: string;\n}\n\n/**\n * Convenience wrapper component for the `useDropzone` hook\n *\n * ```jsx\n * <Dropzone>\n * {({getRootProps, getInputProps}) => (\n * <div {...getRootProps()}>\n * <input {...getInputProps()} />\n * <p>Drag 'n' drop some files here, or click to select files</p>\n * </div>\n * )}\n * </Dropzone>\n * ```\n */\nconst Dropzone: React.ForwardRefExoticComponent<DropzoneProps & React.RefAttributes<DropzoneRef>> = forwardRef<\n DropzoneRef,\n DropzoneProps\n>(({children, ...params}, ref) => {\n const {open, ...props} = useDropzone(params);\n\n useImperativeHandle(ref, () => ({open}), [open]);\n\n return <>{children?.({...props, open})}</>;\n});\n\nDropzone.displayName = \"Dropzone\";\n\nexport default Dropzone;\n\ninterface DropzoneInternalState {\n isFocused: boolean;\n isFileDialogActive: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragGlobal: boolean;\n acceptedFiles: FileWithPath[];\n fileRejections: FileRejection[];\n}\n\nconst initialState: DropzoneInternalState = {\n isFocused: false,\n isFileDialogActive: false,\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false,\n isDragGlobal: false,\n acceptedFiles: [],\n fileRejections: []\n};\n\n/**\n * A React hook that creates a drag 'n' drop area.\n *\n * ```jsx\n * function MyDropzone(props) {\n * const {getRootProps, getInputProps} = useDropzone({\n * onDrop: acceptedFiles => {\n * // do something with the File objects, e.g. upload to some server\n * }\n * });\n * return (\n * <div {...getRootProps()}>\n * <input {...getInputProps()} />\n * <p>Drag and drop some files here, or click to select files</p>\n * </div>\n * )\n * }\n * ```\n */\nexport function useDropzone(props: DropzoneOptions = {}): DropzoneState {\n const {\n accept,\n disabled = false,\n getFilesFromEvent = fromEvent,\n maxSize = Number.POSITIVE_INFINITY,\n minSize = 0,\n multiple = true,\n maxFiles = 0,\n onDragEnter,\n onDragLeave,\n onDragOver,\n onDrop,\n onDropAccepted,\n onDropRejected,\n onFileDialogCancel,\n onFileDialogOpen,\n useFsAccessApi = false,\n autoFocus = false,\n preventDropOnDocument = true,\n noClick = false,\n noKeyboard = false,\n noDrag = false,\n noDragEventsBubbling = false,\n onError,\n validator,\n getErrorMessage\n } = props;\n\n // `acceptAttr` keeps wildcard MIME types (e.g. `image/*`) so the drag-time\n // `isDragAccept`/`isDragReject` check can react to a file's MIME type - file names\n // (hence extensions) aren't readable during a drag.\n const acceptAttr = useMemo(() => acceptPropAsAcceptAttr(accept), [accept]);\n // `inputAcceptAttr` drops a wildcard MIME type when it is paired with extensions, so the\n // native picker and drop-time validation enforce the extensions instead of accepting any\n // file of that type. See https://github.com/react-dropzone/react-dropzone/issues/1220\n const inputAcceptAttr = useMemo(\n () =>\n acceptPropAsAcceptAttr(accept, {\n omitWildcardMimeTypesWithExtensions: true\n }),\n [accept]\n );\n const pickerTypes = useMemo(() => pickerOptionsFromAccept(accept), [accept]);\n\n const onFileDialogOpenCb = useMemo<(...args: any[]) => void>(\n () => (typeof onFileDialogOpen === \"function\" ? onFileDialogOpen : noop),\n [onFileDialogOpen]\n );\n const onFileDialogCancelCb = useMemo<(...args: any[]) => void>(\n () => (typeof onFileDialogCancel === \"function\" ? onFileDialogCancel : noop),\n [onFileDialogCancel]\n );\n\n const rootRef = useRef<HTMLElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [state, dispatch] = useReducer(reducer, initialState);\n const {isFocused, isFileDialogActive} = state;\n\n const fsAccessApiWorksRef = useRef(\n typeof window !== \"undefined\" && window.isSecureContext && useFsAccessApi && canUseFileSystemAccessAPI()\n );\n\n // Update file dialog active state when the window is focused on\n const onWindowFocus = () => {\n // Execute the timeout only if the file dialog is opened in the browser\n if (!fsAccessApiWorksRef.current && isFileDialogActive) {\n setTimeout(() => {\n if (inputRef.current) {\n const {files} = inputRef.current;\n\n if (!files?.length) {\n dispatch({type: \"closeDialog\"});\n onFileDialogCancelCb();\n }\n }\n }, 300);\n }\n };\n useEffect(() => {\n window.addEventListener(\"focus\", onWindowFocus, false);\n return () => {\n window.removeEventListener(\"focus\", onWindowFocus, false);\n };\n }, [inputRef, isFileDialogActive, onFileDialogCancelCb, fsAccessApiWorksRef]);\n\n const dragTargetsRef = useRef<EventTarget[]>([]);\n const globalDragTargetsRef = useRef<EventTarget[]>([]);\n const onDocumentDrop = (event: DragEvent) => {\n if (rootRef.current && event.target && rootRef.current.contains(event.target as Node)) {\n // If we intercepted an event for our instance, let it propagate down to the instance's onDrop handler\n return;\n }\n event.preventDefault();\n dragTargetsRef.current = [];\n };\n\n useEffect(() => {\n if (preventDropOnDocument) {\n document.addEventListener(\"dragover\", onDocumentDragOver, false);\n document.addEventListener(\"drop\", onDocumentDrop, false);\n }\n\n return () => {\n if (preventDropOnDocument) {\n document.removeEventListener(\"dragover\", onDocumentDragOver);\n document.removeEventListener(\"drop\", onDocumentDrop);\n }\n };\n }, [rootRef, preventDropOnDocument]);\n\n // Track global drag state for document-level drag events\n useEffect(() => {\n const onDocumentDragEnter = (event: DragEvent) => {\n if (event.target) {\n globalDragTargetsRef.current = [...globalDragTargetsRef.current, event.target];\n }\n\n if (isEvtWithFiles(event)) {\n dispatch({isDragGlobal: true, type: \"setDragGlobal\"});\n }\n };\n\n const onDocumentDragLeave = (event: DragEvent) => {\n // Only deactivate once we've left all children\n globalDragTargetsRef.current = globalDragTargetsRef.current.filter(el => el !== event.target && el !== null);\n\n if (globalDragTargetsRef.current.length > 0) {\n return;\n }\n\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDragEnd = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDropGlobal = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n document.addEventListener(\"dragenter\", onDocumentDragEnter, false);\n document.addEventListener(\"dragleave\", onDocumentDragLeave, false);\n document.addEventListener(\"dragend\", onDocumentDragEnd, false);\n document.addEventListener(\"drop\", onDocumentDropGlobal, false);\n\n return () => {\n document.removeEventListener(\"dragenter\", onDocumentDragEnter);\n document.removeEventListener(\"dragleave\", onDocumentDragLeave);\n document.removeEventListener(\"dragend\", onDocumentDragEnd);\n document.removeEventListener(\"drop\", onDocumentDropGlobal);\n };\n }, [rootRef]);\n\n // Auto focus the root when autoFocus is true\n useEffect(() => {\n if (!disabled && autoFocus && rootRef.current) {\n rootRef.current.focus();\n }\n return () => {};\n }, [rootRef, autoFocus, disabled]);\n\n const onErrCb = useCallback(\n (e: Error) => {\n if (onError) {\n onError(e);\n } else {\n // Let the user know something's gone wrong if they haven't provided the onError cb.\n console.error(e);\n }\n },\n [onError]\n );\n\n const onDragEnterCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n dragTargetsRef.current = [...dragTargetsRef.current, event.target];\n\n if (isEvtWithFiles(event)) {\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n return;\n }\n\n const fileCount = files.length;\n const isDragAccept =\n fileCount > 0 &&\n allFilesAccepted({\n files: files as File[],\n accept: acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n });\n const isDragReject = fileCount > 0 && !isDragAccept;\n\n dispatch({\n isDragAccept,\n isDragReject,\n isDragActive: true,\n type: \"setDraggedFiles\"\n });\n\n if (onDragEnter) {\n onDragEnter(event);\n }\n })\n .catch(e => onErrCb(e));\n }\n },\n [\n getFilesFromEvent,\n onDragEnter,\n onErrCb,\n noDragEventsBubbling,\n acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n ]\n );\n\n const onDragOverCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n const hasFiles = isEvtWithFiles(event);\n if (hasFiles && event.dataTransfer) {\n try {\n event.dataTransfer.dropEffect = \"copy\";\n } catch {\n /* no-op */\n }\n }\n\n if (hasFiles && onDragOver) {\n onDragOver(event);\n }\n\n return false;\n },\n [onDragOver, noDragEventsBubbling]\n );\n\n const onDragLeaveCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n // Only deactivate once the dropzone and all children have been left\n const targets = dragTargetsRef.current.filter(target => rootRef.current?.contains(target as Node));\n // Make sure to remove a target present multiple times only once\n // (Firefox may fire dragenter/dragleave multiple times on the same element)\n const targetIdx = targets.indexOf(event.target);\n if (targetIdx !== -1) {\n targets.splice(targetIdx, 1);\n }\n dragTargetsRef.current = targets;\n if (targets.length > 0) {\n return;\n }\n\n dispatch({\n type: \"setDraggedFiles\",\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false\n });\n\n if (isEvtWithFiles(event) && onDragLeave) {\n onDragLeave(event);\n }\n },\n [rootRef, onDragLeave, noDragEventsBubbling]\n );\n\n const setFiles = useCallback(\n (files: FileWithPath[], event: any) => {\n const acceptedFiles: FileWithPath[] = [];\n const fileRejections: FileRejection[] = [];\n\n const localizeError = (error: FileError, file: File): FileError =>\n getErrorMessage ? {...error, message: getErrorMessage(error, file)} : error;\n\n files.forEach(file => {\n const [accepted, acceptError] = fileAccepted(file, inputAcceptAttr);\n const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);\n const customErrors = validator ? validator(file) : null;\n\n if (accepted && sizeMatch && !customErrors) {\n acceptedFiles.push(file);\n } else {\n let errors: Array<FileError | null> = [acceptError, sizeError];\n\n if (customErrors) {\n errors = errors.concat(customErrors);\n }\n\n fileRejections.push({\n file,\n errors: errors.filter((e): e is FileError => e != null).map(error => localizeError(error, file))\n });\n }\n });\n\n if ((!multiple && acceptedFiles.length > 1) || (multiple && maxFiles >= 1 && acceptedFiles.length > maxFiles)) {\n // Reject everything and empty accepted files\n acceptedFiles.forEach(file => {\n fileRejections.push({file, errors: [localizeError(TOO_MANY_FILES_REJECTION, file)]});\n });\n acceptedFiles.splice(0);\n }\n\n dispatch({\n acceptedFiles,\n fileRejections,\n type: \"setFiles\"\n });\n\n if (onDrop) {\n onDrop(acceptedFiles, fileRejections, event);\n }\n\n if (fileRejections.length > 0 && onDropRejected) {\n onDropRejected(fileRejections, event);\n }\n\n if (acceptedFiles.length > 0 && onDropAccepted) {\n onDropAccepted(acceptedFiles, event);\n }\n },\n [\n dispatch,\n multiple,\n inputAcceptAttr,\n minSize,\n maxSize,\n maxFiles,\n onDrop,\n onDropAccepted,\n onDropRejected,\n validator,\n getErrorMessage\n ]\n );\n\n const onDropCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n dragTargetsRef.current = [];\n\n if (isEvtWithFiles(event)) {\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n return;\n }\n setFiles(files as FileWithPath[], event);\n })\n .catch(e => onErrCb(e));\n }\n dispatch({type: \"reset\"});\n },\n [getFilesFromEvent, setFiles, onErrCb, noDragEventsBubbling]\n );\n\n // Fn for opening the file dialog programmatically\n const openFileDialog = useCallback(() => {\n // No point to use FS access APIs if context is not secure\n // https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#feature_detection\n if (fsAccessApiWorksRef.current) {\n dispatch({type: \"openDialog\"});\n onFileDialogOpenCb();\n // https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker\n const opts = {\n multiple,\n types: pickerTypes\n };\n (window as any)\n .showOpenFilePicker(opts)\n .then((handles: any) => getFilesFromEvent(handles))\n .then((files: Array<File | DataTransferItem>) => {\n setFiles(files as FileWithPath[], null);\n dispatch({type: \"closeDialog\"});\n })\n .catch((e: any) => {\n // AbortError means the user canceled\n if (isAbort(e)) {\n onFileDialogCancelCb(e);\n dispatch({type: \"closeDialog\"});\n } else if (isSecurityError(e) || isNotAllowedError(e)) {\n // The FS access API is unusable here: either the context forbids it (SecurityError,\n // e.g. CORS) or the browser/platform blocked the picker (NotAllowedError, e.g. Edge\n // for Business - see https://github.com/react-dropzone/react-dropzone/issues/1429).\n // Stop using it and fall back to the native <input>.\n fsAccessApiWorksRef.current = false;\n if (inputRef.current) {\n inputRef.current.value = \"\";\n inputRef.current.click();\n } else {\n onErrCb(\n new Error(\n \"Cannot open the file picker because the https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API is not supported and no <input> was provided.\"\n )\n );\n }\n } else {\n onErrCb(e);\n }\n });\n return;\n }\n\n if (inputRef.current) {\n dispatch({type: \"openDialog\"});\n onFileDialogOpenCb();\n inputRef.current.value = \"\";\n inputRef.current.click();\n }\n }, [dispatch, onFileDialogOpenCb, onFileDialogCancelCb, useFsAccessApi, setFiles, onErrCb, pickerTypes, multiple]);\n\n // Cb to open the file dialog when SPACE/ENTER occurs on the dropzone\n const onKeyDownCb = useCallback(\n (event: any) => {\n // Ignore keyboard events bubbling up the DOM tree\n if (!rootRef.current?.isEqualNode(event.target)) {\n return;\n }\n\n if (event.key === \" \" || event.key === \"Enter\" || event.keyCode === 32 || event.keyCode === 13) {\n event.preventDefault();\n openFileDialog();\n }\n },\n [rootRef, openFileDialog]\n );\n\n // Update focus state for the dropzone\n const onFocusCb = useCallback(() => {\n dispatch({type: \"focus\"});\n }, []);\n const onBlurCb = useCallback(() => {\n dispatch({type: \"blur\"});\n }, []);\n\n // Cb to open the file dialog when click occurs on the dropzone\n const onClickCb = useCallback(() => {\n if (noClick) {\n return;\n }\n\n // In IE11/Edge the file-browser dialog is blocking, therefore, use setTimeout()\n // to ensure React can handle state changes\n // See: https://github.com/react-dropzone/react-dropzone/issues/450\n if (isIeOrEdge()) {\n setTimeout(openFileDialog, 0);\n } else {\n openFileDialog();\n }\n }, [noClick, openFileDialog]);\n\n const composeHandler = (fn: any) => {\n return disabled ? null : fn;\n };\n\n const composeKeyboardHandler = (fn: any) => {\n return noKeyboard ? null : composeHandler(fn);\n };\n\n const composeDragHandler = (fn: any) => {\n return noDrag ? null : composeHandler(fn);\n };\n\n const stopPropagation = (event: any) => {\n if (noDragEventsBubbling) {\n event.stopPropagation();\n }\n };\n\n const getRootProps = useMemo(\n () =>\n ({\n refKey = \"ref\",\n role,\n onKeyDown,\n onFocus,\n onBlur,\n onClick,\n onDragEnter,\n onDragOver,\n onDragLeave,\n onDrop,\n ...rest\n }: DropzoneRootProps = {}) => ({\n onKeyDown: composeKeyboardHandler(composeEventHandlers(onKeyDown, onKeyDownCb)),\n onFocus: composeKeyboardHandler(composeEventHandlers(onFocus, onFocusCb)),\n onBlur: composeKeyboardHandler(composeEventHandlers(onBlur, onBlurCb)),\n onClick: composeHandler(composeEventHandlers(onClick, onClickCb)),\n onDragEnter: composeDragHandler(composeEventHandlers(onDragEnter, onDragEnterCb)),\n onDragOver: composeDragHandler(composeEventHandlers(onDragOver, onDragOverCb)),\n onDragLeave: composeDragHandler(composeEventHandlers(onDragLeave, onDragLeaveCb)),\n onDrop: composeDragHandler(composeEventHandlers(onDrop, onDropCb)),\n role: typeof role === \"string\" && role !== \"\" ? role : \"presentation\",\n [refKey]: rootRef,\n ...(!disabled && !noKeyboard ? {tabIndex: 0} : {}),\n ...(disabled ? {\"aria-disabled\": true} : {}),\n ...rest\n }),\n [\n rootRef,\n onKeyDownCb,\n onFocusCb,\n onBlurCb,\n onClickCb,\n onDragEnterCb,\n onDragOverCb,\n onDragLeaveCb,\n onDropCb,\n noKeyboard,\n noDrag,\n disabled\n ]\n );\n\n const onInputElementClick = useCallback((event: any) => {\n event.stopPropagation();\n }, []);\n\n const getInputProps = useMemo(\n () =>\n ({refKey = \"ref\", onChange, onClick, ...rest}: DropzoneInputProps = {}) => {\n const inputProps = {\n accept: inputAcceptAttr,\n multiple,\n type: \"file\",\n \"aria-label\": \"file upload\",\n style: {\n border: 0,\n clip: \"rect(0, 0, 0, 0)\",\n clipPath: \"inset(50%)\",\n height: \"1px\",\n margin: \"0 -1px -1px 0\",\n overflow: \"hidden\",\n padding: 0,\n position: \"absolute\",\n width: \"1px\",\n whiteSpace: \"nowrap\"\n },\n onChange: composeHandler(composeEventHandlers(onChange, onDropCb)),\n onClick: composeHandler(composeEventHandlers(onClick, onInputElementClick)),\n tabIndex: -1,\n [refKey]: inputRef\n };\n\n return {\n ...inputProps,\n ...rest\n };\n },\n [inputRef, accept, multiple, onDropCb, disabled]\n );\n\n return {\n ...state,\n isFocused: isFocused && !disabled,\n getRootProps,\n getInputProps,\n rootRef,\n inputRef,\n open: composeHandler(openFileDialog)\n } as unknown as DropzoneState;\n}\n\nfunction reducer(state: DropzoneInternalState, action: any): DropzoneInternalState {\n switch (action.type) {\n case \"focus\":\n return {\n ...state,\n isFocused: true\n };\n case \"blur\":\n return {\n ...state,\n isFocused: false\n };\n case \"openDialog\":\n return {\n ...initialState,\n isFileDialogActive: true\n };\n case \"closeDialog\":\n return {\n ...state,\n isFileDialogActive: false\n };\n case \"setDraggedFiles\":\n return {\n ...state,\n isDragActive: action.isDragActive,\n isDragAccept: action.isDragAccept,\n isDragReject: action.isDragReject\n };\n case \"setFiles\":\n return {\n ...state,\n acceptedFiles: action.acceptedFiles,\n fileRejections: action.fileRejections,\n isDragReject: false\n };\n case \"setDragGlobal\":\n return {\n ...state,\n isDragGlobal: action.isDragGlobal\n };\n case \"reset\":\n return {\n ...initialState\n };\n default:\n return state;\n }\n}\n\nfunction noop() {}\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -49,6 +49,12 @@ type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> & {
49
49
  onFileDialogOpen?: () => void;
50
50
  onError?: (err: Error) => void;
51
51
  validator?: <T extends File>(file: T) => FileError | readonly FileError[] | null;
52
+ /**
53
+ * Override the message of any rejection error (built-in or custom). Called once per error;
54
+ * receives the error and the file it belongs to and returns the message to use. Return
55
+ * `error.message` for codes you don't want to change. Useful for localizing error messages.
56
+ */
57
+ getErrorMessage?: (error: FileError, file: File) => string;
52
58
  useFsAccessApi?: boolean;
53
59
  autoFocus?: boolean;
54
60
  };
package/dist/index.d.ts CHANGED
@@ -49,6 +49,12 @@ type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> & {
49
49
  onFileDialogOpen?: () => void;
50
50
  onError?: (err: Error) => void;
51
51
  validator?: <T extends File>(file: T) => FileError | readonly FileError[] | null;
52
+ /**
53
+ * Override the message of any rejection error (built-in or custom). Called once per error;
54
+ * receives the error and the file it belongs to and returns the message to use. Return
55
+ * `error.message` for codes you don't want to change. Useful for localizing error messages.
56
+ */
57
+ getErrorMessage?: (error: FileError, file: File) => string;
52
58
  useFsAccessApi?: boolean;
53
59
  autoFocus?: boolean;
54
60
  };
package/dist/index.js CHANGED
@@ -200,6 +200,17 @@ function isSecurityError(v) {
200
200
  return v instanceof DOMException && (v.name === "SecurityError" || v.code === v.SECURITY_ERR);
201
201
  }
202
202
  /**
203
+ * Check if v is a "not allowed" error.
204
+ *
205
+ * Some browsers/configurations block `window.showOpenFilePicker()` outright and reject with a
206
+ * `NotAllowedError` instead of showing the picker (e.g. Microsoft Edge for Business, or other
207
+ * restrictive enterprise/security policies). We treat this like a security error and fall back
208
+ * to the native `<input>`. See https://github.com/react-dropzone/react-dropzone/issues/1429
209
+ */
210
+ function isNotAllowedError(v) {
211
+ return v instanceof DOMException && v.name === "NotAllowedError";
212
+ }
213
+ /**
203
214
  * Check if v is a MIME type string.
204
215
  */
205
216
  function isMIMEType(v) {
@@ -272,7 +283,7 @@ const initialState = {
272
283
  * ```
273
284
  */
274
285
  function useDropzone(props = {}) {
275
- const { accept, disabled = false, getFilesFromEvent = fromEvent, maxSize = Number.POSITIVE_INFINITY, minSize = 0, multiple = true, maxFiles = 0, onDragEnter, onDragLeave, onDragOver, onDrop, onDropAccepted, onDropRejected, onFileDialogCancel, onFileDialogOpen, useFsAccessApi = false, autoFocus = false, preventDropOnDocument = true, noClick = false, noKeyboard = false, noDrag = false, noDragEventsBubbling = false, onError, validator } = props;
286
+ const { accept, disabled = false, getFilesFromEvent = fromEvent, maxSize = Number.POSITIVE_INFINITY, minSize = 0, multiple = true, maxFiles = 0, onDragEnter, onDragLeave, onDragOver, onDrop, onDropAccepted, onDropRejected, onFileDialogCancel, onFileDialogOpen, useFsAccessApi = false, autoFocus = false, preventDropOnDocument = true, noClick = false, noKeyboard = false, noDrag = false, noDragEventsBubbling = false, onError, validator, getErrorMessage } = props;
276
287
  const acceptAttr = useMemo(() => acceptPropAsAcceptAttr(accept), [accept]);
277
288
  const inputAcceptAttr = useMemo(() => acceptPropAsAcceptAttr(accept, { omitWildcardMimeTypesWithExtensions: true }), [accept]);
278
289
  const pickerTypes = useMemo(() => pickerOptionsFromAccept(accept), [accept]);
@@ -449,6 +460,10 @@ function useDropzone(props = {}) {
449
460
  const setFiles = useCallback((files, event) => {
450
461
  const acceptedFiles = [];
451
462
  const fileRejections = [];
463
+ const localizeError = (error, file) => getErrorMessage ? {
464
+ ...error,
465
+ message: getErrorMessage(error, file)
466
+ } : error;
452
467
  files.forEach((file) => {
453
468
  const [accepted, acceptError] = fileAccepted(file, inputAcceptAttr);
454
469
  const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);
@@ -459,7 +474,7 @@ function useDropzone(props = {}) {
459
474
  if (customErrors) errors = errors.concat(customErrors);
460
475
  fileRejections.push({
461
476
  file,
462
- errors: errors.filter((e) => e != null)
477
+ errors: errors.filter((e) => e != null).map((error) => localizeError(error, file))
463
478
  });
464
479
  }
465
480
  });
@@ -467,7 +482,7 @@ function useDropzone(props = {}) {
467
482
  acceptedFiles.forEach((file) => {
468
483
  fileRejections.push({
469
484
  file,
470
- errors: [TOO_MANY_FILES_REJECTION]
485
+ errors: [localizeError(TOO_MANY_FILES_REJECTION, file)]
471
486
  });
472
487
  });
473
488
  acceptedFiles.splice(0);
@@ -490,7 +505,8 @@ function useDropzone(props = {}) {
490
505
  onDrop,
491
506
  onDropAccepted,
492
507
  onDropRejected,
493
- validator
508
+ validator,
509
+ getErrorMessage
494
510
  ]);
495
511
  const onDropCb = useCallback((event) => {
496
512
  event.preventDefault();
@@ -523,7 +539,7 @@ function useDropzone(props = {}) {
523
539
  if (isAbort(e)) {
524
540
  onFileDialogCancelCb(e);
525
541
  dispatch({ type: "closeDialog" });
526
- } else if (isSecurityError(e)) {
542
+ } else if (isSecurityError(e) || isNotAllowedError(e)) {
527
543
  fsAccessApiWorksRef.current = false;
528
544
  if (inputRef.current) {
529
545
  inputRef.current.value = "";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/utils/index.ts","../src/index.tsx"],"sourcesContent":["import attrAccept from \"attr-accept\";\n\n// attr-accept ships as a CommonJS module (`module.exports = { __esModule: true, default: fn }`).\n// Bundler interop surfaces its default export inconsistently — as the function under Node/Vitest,\n// but as `{ default: fn }` in some browser bundles. Normalize to the function.\nconst accepts =\n typeof attrAccept === \"function\" ? attrAccept : (attrAccept as unknown as {default: typeof attrAccept}).default;\n\n/**\n * A map of accepted MIME types to file extensions, as passed to the `accept` prop.\n */\nexport interface Accept {\n [key: string]: readonly string[];\n}\n\n/**\n * A file rejection error.\n */\nexport interface FileError {\n message: string;\n code: ErrorCode | string;\n}\n\n// Error codes\nexport const FILE_INVALID_TYPE = \"file-invalid-type\";\nexport const FILE_TOO_LARGE = \"file-too-large\";\nexport const FILE_TOO_SMALL = \"file-too-small\";\nexport const TOO_MANY_FILES = \"too-many-files\";\n\nexport enum ErrorCode {\n FileInvalidType = \"file-invalid-type\",\n FileTooLarge = \"file-too-large\",\n FileTooSmall = \"file-too-small\",\n TooManyFiles = \"too-many-files\"\n}\n\nexport function getInvalidTypeRejectionErr(accept: string = \"\"): FileError {\n const acceptArr = accept.split(\",\");\n const msg = acceptArr.length > 1 ? `one of ${acceptArr.join(\", \")}` : acceptArr[0];\n\n return {\n code: FILE_INVALID_TYPE,\n message: `File type must be ${msg}`\n };\n}\n\nconst FILE_SIZE_UNITS = [\"KB\", \"MB\", \"GB\", \"TB\", \"PB\"];\n\n/**\n * Format a byte count into a human-readable string, e.g. `1111` -> `1.08 KB`.\n * Values below 1 KB are kept in bytes to preserve the singular/plural wording.\n */\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} ${bytes === 1 ? \"byte\" : \"bytes\"}`;\n }\n\n let size = bytes / 1024;\n let unitIndex = 0;\n while (size >= 1024 && unitIndex < FILE_SIZE_UNITS.length - 1) {\n size /= 1024;\n unitIndex++;\n }\n\n // Round to 2 decimals, then drop trailing zeros (1.00 -> 1, 1.50 -> 1.5).\n return `${Number(size.toFixed(2))} ${FILE_SIZE_UNITS[unitIndex]}`;\n}\n\nexport function getTooLargeRejectionErr(maxSize: number): FileError {\n return {\n code: FILE_TOO_LARGE,\n message: `File is larger than ${formatBytes(maxSize)}`\n };\n}\n\nexport function getTooSmallRejectionErr(minSize: number): FileError {\n return {\n code: FILE_TOO_SMALL,\n message: `File is smaller than ${formatBytes(minSize)}`\n };\n}\n\nexport const TOO_MANY_FILES_REJECTION: FileError = {\n code: TOO_MANY_FILES,\n message: \"Too many files\"\n};\n\n/**\n * Check if the given file is a DataTransferItem with an empty type.\n *\n * During drag events, browsers may return DataTransferItem objects instead of File objects.\n * Some browsers (e.g., Chrome) return an empty MIME type for certain file types (like .md files)\n * on DataTransferItem during drag events, even though the type is correctly set during drop.\n */\nexport function isDataTransferItemWithEmptyType(file: File | DataTransferItem): boolean {\n return file.type === \"\" && typeof (file as DataTransferItem).getAsFile === \"function\";\n}\n\n/**\n * Check if file is accepted.\n *\n * Firefox versions prior to 53 return a bogus MIME type for every file drag,\n * so dragovers with that MIME type will always be accepted.\n *\n * Chrome/other browsers may return an empty MIME type for files during drag events,\n * so we accept those as well (we'll validate properly on drop).\n */\nexport function fileAccepted(file: File, accept?: string): [boolean, FileError | null] {\n const isAcceptable =\n file.type === \"application/x-moz-file\" || accepts(file, accept ?? \"\") || isDataTransferItemWithEmptyType(file);\n return [isAcceptable, isAcceptable ? null : getInvalidTypeRejectionErr(accept)];\n}\n\nexport function fileMatchSize(\n file: {size?: number | null},\n minSize?: number,\n maxSize?: number\n): [boolean, FileError | null] {\n if (isDefined(file.size)) {\n if (isDefined(minSize) && isDefined(maxSize)) {\n if (file.size > maxSize) return [false, getTooLargeRejectionErr(maxSize)];\n if (file.size < minSize) return [false, getTooSmallRejectionErr(minSize)];\n } else if (isDefined(minSize) && file.size < minSize) {\n return [false, getTooSmallRejectionErr(minSize)];\n } else if (isDefined(maxSize) && file.size > maxSize) {\n return [false, getTooLargeRejectionErr(maxSize)];\n }\n }\n return [true, null];\n}\n\nfunction isDefined<T>(value: T): value is NonNullable<T> {\n return value !== undefined && value !== null;\n}\n\nexport function allFilesAccepted({\n files,\n accept,\n minSize,\n maxSize,\n multiple,\n maxFiles = 0,\n validator\n}: {\n files: File[];\n accept?: string;\n minSize?: number;\n maxSize?: number;\n multiple?: boolean;\n maxFiles?: number;\n validator?: (file: File) => FileError | readonly FileError[] | null;\n}): boolean {\n if ((!multiple && files.length > 1) || (multiple && maxFiles >= 1 && files.length > maxFiles)) {\n return false;\n }\n\n return files.every(file => {\n const [accepted] = fileAccepted(file, accept);\n const [sizeMatch] = fileMatchSize(file, minSize, maxSize);\n const customErrors = validator ? validator(file) : null;\n return accepted && sizeMatch && !customErrors;\n });\n}\n\n// React's synthetic events has event.isPropagationStopped,\n// but to remain compatibility with other libs (Preact) fall back\n// to check event.cancelBubble\nexport function isPropagationStopped(event: any): boolean {\n if (typeof event.isPropagationStopped === \"function\") {\n return event.isPropagationStopped();\n } else if (typeof event.cancelBubble !== \"undefined\") {\n return event.cancelBubble;\n }\n return false;\n}\n\nexport function isEvtWithFiles(event: any): boolean {\n if (!event.dataTransfer) {\n return !!event.target && !!event.target.files;\n }\n // https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/types\n // https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#file\n return Array.prototype.some.call(\n event.dataTransfer.types,\n (type: string) => type === \"Files\" || type === \"application/x-moz-file\"\n );\n}\n\nexport function isKindFile(item: any): boolean {\n return typeof item === \"object\" && item !== null && item.kind === \"file\";\n}\n\n// allow the entire document to be a drag target\nexport function onDocumentDragOver(event: Event): void {\n event.preventDefault();\n}\n\nfunction isIe(userAgent: string): boolean {\n return userAgent.indexOf(\"MSIE\") !== -1 || userAgent.indexOf(\"Trident/\") !== -1;\n}\n\nfunction isEdge(userAgent: string): boolean {\n return userAgent.indexOf(\"Edge/\") !== -1;\n}\n\nexport function isIeOrEdge(userAgent: string = window.navigator.userAgent): boolean {\n return isIe(userAgent) || isEdge(userAgent);\n}\n\n/**\n * This is intended to be used to compose event handlers.\n * They are executed in order until one of them calls `event.isPropagationStopped()`.\n * Note that the check is done on the first invoke too,\n * meaning that if propagation was stopped before invoking the fns,\n * no handlers will be executed.\n */\nexport function composeEventHandlers(\n ...fns: Array<((event: any, ...args: any[]) => void) | null | undefined>\n): (event: any, ...args: any[]) => boolean {\n return (event: any, ...args: any[]) =>\n fns.some(fn => {\n if (!isPropagationStopped(event) && fn) {\n fn(event, ...args);\n }\n return isPropagationStopped(event);\n });\n}\n\n/**\n * canUseFileSystemAccessAPI checks if the File System Access API is supported by the browser.\n */\nexport function canUseFileSystemAccessAPI(): boolean {\n return \"showOpenFilePicker\" in window;\n}\n\n/**\n * Convert the `{accept}` dropzone prop to the `{types}` option for showOpenFilePicker.\n */\nexport function pickerOptionsFromAccept(accept?: Accept): Array<{description: string; accept: Accept}> | undefined {\n if (isDefined(accept)) {\n const acceptForPicker = Object.entries(accept)\n .filter(([mimeType, ext]) => {\n let ok = true;\n\n if (!isMIMEType(mimeType)) {\n console.warn(\n `Skipped \"${mimeType}\" because it is not a valid MIME type. Check https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types for a list of valid MIME types.`\n );\n ok = false;\n }\n\n if (!Array.isArray(ext) || !ext.every(isExt)) {\n console.warn(`Skipped \"${mimeType}\" because an invalid file extension was provided.`);\n ok = false;\n }\n\n return ok;\n })\n .reduce<Accept>((agg, [mimeType, ext]) => {\n agg[mimeType] = ext;\n return agg;\n }, {});\n return [\n {\n // description is required due to https://crbug.com/1264708\n description: \"Files\",\n accept: acceptForPicker\n }\n ];\n }\n return undefined;\n}\n\n/**\n * Convert the `{accept}` dropzone prop to a comma-separated accept attribute string.\n *\n * When `omitWildcardMimeTypesWithExtensions` is set, a wildcard MIME type (e.g. `image/*`)\n * that is paired with explicit extensions is dropped in favour of those extensions. The\n * accept attribute is an OR list, so leaving `image/*` in would make both the native file\n * picker and the drop-time validator accept ANY file of that type, ignoring the extension\n * restriction. The drag-time `isDragAccept` check keeps the wildcard because file names\n * (and therefore extensions) aren't readable during a drag.\n *\n * See https://github.com/react-dropzone/react-dropzone/issues/1220\n */\nexport function acceptPropAsAcceptAttr(\n accept?: Accept,\n {omitWildcardMimeTypesWithExtensions = false}: {omitWildcardMimeTypesWithExtensions?: boolean} = {}\n): string | undefined {\n if (isDefined(accept)) {\n return (\n Object.entries(accept)\n .reduce<string[]>((a, [mimeType, ext]) => {\n if (omitWildcardMimeTypesWithExtensions && isMIMETypeWildcard(mimeType) && ext.some(isExt)) {\n a.push(...ext);\n } else {\n a.push(mimeType, ...ext);\n }\n return a;\n }, [])\n // Silently discard invalid entries as pickerOptionsFromAccept warns about these\n .filter(v => isMIMEType(v) || isExt(v))\n .join(\",\")\n );\n }\n\n return undefined;\n}\n\n/**\n * Check if v is an exception caused by aborting a request (e.g window.showOpenFilePicker()).\n */\nexport function isAbort(v: any): boolean {\n return v instanceof DOMException && (v.name === \"AbortError\" || v.code === v.ABORT_ERR);\n}\n\n/**\n * Check if v is a security error.\n */\nexport function isSecurityError(v: any): boolean {\n return v instanceof DOMException && (v.name === \"SecurityError\" || v.code === v.SECURITY_ERR);\n}\n\n/**\n * Check if v is a MIME type string.\n */\nexport function isMIMEType(v: string): boolean {\n return (\n v === \"audio/*\" ||\n v === \"video/*\" ||\n v === \"image/*\" ||\n v === \"text/*\" ||\n v === \"application/*\" ||\n /\\w+\\/[-+.\\w]+/g.test(v)\n );\n}\n\n/**\n * Check if v is a wildcard MIME type (e.g. `image/*`).\n */\nexport function isMIMETypeWildcard(v: string): boolean {\n return v.endsWith(\"/*\");\n}\n\n/**\n * Check if v is a file extension.\n */\nexport function isExt(v: string): boolean {\n return /^.*\\.[\\w]+$/.test(v);\n}\n","import {fromEvent} from \"file-selector\";\nimport type {FileWithPath} from \"file-selector\";\nimport type * as React from \"react\";\nimport {forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useReducer, useRef} from \"react\";\nimport {\n acceptPropAsAcceptAttr,\n allFilesAccepted,\n canUseFileSystemAccessAPI,\n composeEventHandlers,\n ErrorCode,\n fileAccepted,\n fileMatchSize,\n isAbort,\n isEvtWithFiles,\n isIeOrEdge,\n isPropagationStopped,\n isSecurityError,\n onDocumentDragOver,\n pickerOptionsFromAccept,\n TOO_MANY_FILES_REJECTION\n} from \"./utils\";\nimport type {Accept, FileError} from \"./utils\";\n\nexport type {Accept, FileError, FileWithPath};\nexport {ErrorCode};\n\nexport interface DropzoneProps extends DropzoneOptions {\n children?: (state: DropzoneState) => React.ReactElement;\n}\n\nexport interface FileRejection {\n file: FileWithPath;\n errors: readonly FileError[];\n}\n\ntype SharedProps = \"multiple\" | \"onDragEnter\" | \"onDragOver\" | \"onDragLeave\";\n\nexport type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> & {\n accept?: Accept;\n minSize?: number;\n maxSize?: number;\n maxFiles?: number;\n preventDropOnDocument?: boolean;\n noClick?: boolean;\n noKeyboard?: boolean;\n noDrag?: boolean;\n noDragEventsBubbling?: boolean;\n disabled?: boolean;\n onDrop?: <T extends File>(acceptedFiles: T[], fileRejections: FileRejection[], event: DropEvent) => void;\n onDropAccepted?: <T extends File>(files: T[], event: DropEvent) => void;\n onDropRejected?: (fileRejections: FileRejection[], event: DropEvent) => void;\n getFilesFromEvent?: (event: DropEvent | Array<FileSystemFileHandle>) => Promise<Array<File | DataTransferItem>>;\n onFileDialogCancel?: () => void;\n onFileDialogOpen?: () => void;\n onError?: (err: Error) => void;\n validator?: <T extends File>(file: T) => FileError | readonly FileError[] | null;\n useFsAccessApi?: boolean;\n autoFocus?: boolean;\n};\n\nexport type DropEvent = React.DragEvent<HTMLElement> | React.ChangeEvent<HTMLInputElement> | DragEvent | Event;\n\nexport interface DropzoneRef {\n open: () => void;\n}\n\nexport type DropzoneState = DropzoneRef & {\n isFocused: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragGlobal: boolean;\n isFileDialogActive: boolean;\n acceptedFiles: readonly FileWithPath[];\n fileRejections: readonly FileRejection[];\n rootRef: React.RefObject<HTMLElement>;\n inputRef: React.RefObject<HTMLInputElement>;\n getRootProps: <T extends DropzoneRootProps>(props?: T) => T;\n getInputProps: <T extends DropzoneInputProps>(props?: T) => T;\n};\n\nexport interface DropzoneRootProps extends React.HTMLAttributes<HTMLElement> {\n refKey?: string;\n [key: string]: any;\n}\n\nexport interface DropzoneInputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n refKey?: string;\n}\n\n/**\n * Convenience wrapper component for the `useDropzone` hook\n *\n * ```jsx\n * <Dropzone>\n * {({getRootProps, getInputProps}) => (\n * <div {...getRootProps()}>\n * <input {...getInputProps()} />\n * <p>Drag 'n' drop some files here, or click to select files</p>\n * </div>\n * )}\n * </Dropzone>\n * ```\n */\nconst Dropzone: React.ForwardRefExoticComponent<DropzoneProps & React.RefAttributes<DropzoneRef>> = forwardRef<\n DropzoneRef,\n DropzoneProps\n>(({children, ...params}, ref) => {\n const {open, ...props} = useDropzone(params);\n\n useImperativeHandle(ref, () => ({open}), [open]);\n\n return <>{children?.({...props, open})}</>;\n});\n\nDropzone.displayName = \"Dropzone\";\n\nexport default Dropzone;\n\ninterface DropzoneInternalState {\n isFocused: boolean;\n isFileDialogActive: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragGlobal: boolean;\n acceptedFiles: FileWithPath[];\n fileRejections: FileRejection[];\n}\n\nconst initialState: DropzoneInternalState = {\n isFocused: false,\n isFileDialogActive: false,\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false,\n isDragGlobal: false,\n acceptedFiles: [],\n fileRejections: []\n};\n\n/**\n * A React hook that creates a drag 'n' drop area.\n *\n * ```jsx\n * function MyDropzone(props) {\n * const {getRootProps, getInputProps} = useDropzone({\n * onDrop: acceptedFiles => {\n * // do something with the File objects, e.g. upload to some server\n * }\n * });\n * return (\n * <div {...getRootProps()}>\n * <input {...getInputProps()} />\n * <p>Drag and drop some files here, or click to select files</p>\n * </div>\n * )\n * }\n * ```\n */\nexport function useDropzone(props: DropzoneOptions = {}): DropzoneState {\n const {\n accept,\n disabled = false,\n getFilesFromEvent = fromEvent,\n maxSize = Number.POSITIVE_INFINITY,\n minSize = 0,\n multiple = true,\n maxFiles = 0,\n onDragEnter,\n onDragLeave,\n onDragOver,\n onDrop,\n onDropAccepted,\n onDropRejected,\n onFileDialogCancel,\n onFileDialogOpen,\n useFsAccessApi = false,\n autoFocus = false,\n preventDropOnDocument = true,\n noClick = false,\n noKeyboard = false,\n noDrag = false,\n noDragEventsBubbling = false,\n onError,\n validator\n } = props;\n\n // `acceptAttr` keeps wildcard MIME types (e.g. `image/*`) so the drag-time\n // `isDragAccept`/`isDragReject` check can react to a file's MIME type - file names\n // (hence extensions) aren't readable during a drag.\n const acceptAttr = useMemo(() => acceptPropAsAcceptAttr(accept), [accept]);\n // `inputAcceptAttr` drops a wildcard MIME type when it is paired with extensions, so the\n // native picker and drop-time validation enforce the extensions instead of accepting any\n // file of that type. See https://github.com/react-dropzone/react-dropzone/issues/1220\n const inputAcceptAttr = useMemo(\n () =>\n acceptPropAsAcceptAttr(accept, {\n omitWildcardMimeTypesWithExtensions: true\n }),\n [accept]\n );\n const pickerTypes = useMemo(() => pickerOptionsFromAccept(accept), [accept]);\n\n const onFileDialogOpenCb = useMemo<(...args: any[]) => void>(\n () => (typeof onFileDialogOpen === \"function\" ? onFileDialogOpen : noop),\n [onFileDialogOpen]\n );\n const onFileDialogCancelCb = useMemo<(...args: any[]) => void>(\n () => (typeof onFileDialogCancel === \"function\" ? onFileDialogCancel : noop),\n [onFileDialogCancel]\n );\n\n const rootRef = useRef<HTMLElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [state, dispatch] = useReducer(reducer, initialState);\n const {isFocused, isFileDialogActive} = state;\n\n const fsAccessApiWorksRef = useRef(\n typeof window !== \"undefined\" && window.isSecureContext && useFsAccessApi && canUseFileSystemAccessAPI()\n );\n\n // Update file dialog active state when the window is focused on\n const onWindowFocus = () => {\n // Execute the timeout only if the file dialog is opened in the browser\n if (!fsAccessApiWorksRef.current && isFileDialogActive) {\n setTimeout(() => {\n if (inputRef.current) {\n const {files} = inputRef.current;\n\n if (!files?.length) {\n dispatch({type: \"closeDialog\"});\n onFileDialogCancelCb();\n }\n }\n }, 300);\n }\n };\n useEffect(() => {\n window.addEventListener(\"focus\", onWindowFocus, false);\n return () => {\n window.removeEventListener(\"focus\", onWindowFocus, false);\n };\n }, [inputRef, isFileDialogActive, onFileDialogCancelCb, fsAccessApiWorksRef]);\n\n const dragTargetsRef = useRef<EventTarget[]>([]);\n const globalDragTargetsRef = useRef<EventTarget[]>([]);\n const onDocumentDrop = (event: DragEvent) => {\n if (rootRef.current && event.target && rootRef.current.contains(event.target as Node)) {\n // If we intercepted an event for our instance, let it propagate down to the instance's onDrop handler\n return;\n }\n event.preventDefault();\n dragTargetsRef.current = [];\n };\n\n useEffect(() => {\n if (preventDropOnDocument) {\n document.addEventListener(\"dragover\", onDocumentDragOver, false);\n document.addEventListener(\"drop\", onDocumentDrop, false);\n }\n\n return () => {\n if (preventDropOnDocument) {\n document.removeEventListener(\"dragover\", onDocumentDragOver);\n document.removeEventListener(\"drop\", onDocumentDrop);\n }\n };\n }, [rootRef, preventDropOnDocument]);\n\n // Track global drag state for document-level drag events\n useEffect(() => {\n const onDocumentDragEnter = (event: DragEvent) => {\n if (event.target) {\n globalDragTargetsRef.current = [...globalDragTargetsRef.current, event.target];\n }\n\n if (isEvtWithFiles(event)) {\n dispatch({isDragGlobal: true, type: \"setDragGlobal\"});\n }\n };\n\n const onDocumentDragLeave = (event: DragEvent) => {\n // Only deactivate once we've left all children\n globalDragTargetsRef.current = globalDragTargetsRef.current.filter(el => el !== event.target && el !== null);\n\n if (globalDragTargetsRef.current.length > 0) {\n return;\n }\n\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDragEnd = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDropGlobal = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n document.addEventListener(\"dragenter\", onDocumentDragEnter, false);\n document.addEventListener(\"dragleave\", onDocumentDragLeave, false);\n document.addEventListener(\"dragend\", onDocumentDragEnd, false);\n document.addEventListener(\"drop\", onDocumentDropGlobal, false);\n\n return () => {\n document.removeEventListener(\"dragenter\", onDocumentDragEnter);\n document.removeEventListener(\"dragleave\", onDocumentDragLeave);\n document.removeEventListener(\"dragend\", onDocumentDragEnd);\n document.removeEventListener(\"drop\", onDocumentDropGlobal);\n };\n }, [rootRef]);\n\n // Auto focus the root when autoFocus is true\n useEffect(() => {\n if (!disabled && autoFocus && rootRef.current) {\n rootRef.current.focus();\n }\n return () => {};\n }, [rootRef, autoFocus, disabled]);\n\n const onErrCb = useCallback(\n (e: Error) => {\n if (onError) {\n onError(e);\n } else {\n // Let the user know something's gone wrong if they haven't provided the onError cb.\n console.error(e);\n }\n },\n [onError]\n );\n\n const onDragEnterCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n dragTargetsRef.current = [...dragTargetsRef.current, event.target];\n\n if (isEvtWithFiles(event)) {\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n return;\n }\n\n const fileCount = files.length;\n const isDragAccept =\n fileCount > 0 &&\n allFilesAccepted({\n files: files as File[],\n accept: acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n });\n const isDragReject = fileCount > 0 && !isDragAccept;\n\n dispatch({\n isDragAccept,\n isDragReject,\n isDragActive: true,\n type: \"setDraggedFiles\"\n });\n\n if (onDragEnter) {\n onDragEnter(event);\n }\n })\n .catch(e => onErrCb(e));\n }\n },\n [\n getFilesFromEvent,\n onDragEnter,\n onErrCb,\n noDragEventsBubbling,\n acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n ]\n );\n\n const onDragOverCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n const hasFiles = isEvtWithFiles(event);\n if (hasFiles && event.dataTransfer) {\n try {\n event.dataTransfer.dropEffect = \"copy\";\n } catch {\n /* no-op */\n }\n }\n\n if (hasFiles && onDragOver) {\n onDragOver(event);\n }\n\n return false;\n },\n [onDragOver, noDragEventsBubbling]\n );\n\n const onDragLeaveCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n // Only deactivate once the dropzone and all children have been left\n const targets = dragTargetsRef.current.filter(target => rootRef.current?.contains(target as Node));\n // Make sure to remove a target present multiple times only once\n // (Firefox may fire dragenter/dragleave multiple times on the same element)\n const targetIdx = targets.indexOf(event.target);\n if (targetIdx !== -1) {\n targets.splice(targetIdx, 1);\n }\n dragTargetsRef.current = targets;\n if (targets.length > 0) {\n return;\n }\n\n dispatch({\n type: \"setDraggedFiles\",\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false\n });\n\n if (isEvtWithFiles(event) && onDragLeave) {\n onDragLeave(event);\n }\n },\n [rootRef, onDragLeave, noDragEventsBubbling]\n );\n\n const setFiles = useCallback(\n (files: FileWithPath[], event: any) => {\n const acceptedFiles: FileWithPath[] = [];\n const fileRejections: FileRejection[] = [];\n\n files.forEach(file => {\n const [accepted, acceptError] = fileAccepted(file, inputAcceptAttr);\n const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);\n const customErrors = validator ? validator(file) : null;\n\n if (accepted && sizeMatch && !customErrors) {\n acceptedFiles.push(file);\n } else {\n let errors: Array<FileError | null> = [acceptError, sizeError];\n\n if (customErrors) {\n errors = errors.concat(customErrors);\n }\n\n fileRejections.push({\n file,\n errors: errors.filter((e): e is FileError => e != null)\n });\n }\n });\n\n if ((!multiple && acceptedFiles.length > 1) || (multiple && maxFiles >= 1 && acceptedFiles.length > maxFiles)) {\n // Reject everything and empty accepted files\n acceptedFiles.forEach(file => {\n fileRejections.push({file, errors: [TOO_MANY_FILES_REJECTION]});\n });\n acceptedFiles.splice(0);\n }\n\n dispatch({\n acceptedFiles,\n fileRejections,\n type: \"setFiles\"\n });\n\n if (onDrop) {\n onDrop(acceptedFiles, fileRejections, event);\n }\n\n if (fileRejections.length > 0 && onDropRejected) {\n onDropRejected(fileRejections, event);\n }\n\n if (acceptedFiles.length > 0 && onDropAccepted) {\n onDropAccepted(acceptedFiles, event);\n }\n },\n [dispatch, multiple, inputAcceptAttr, minSize, maxSize, maxFiles, onDrop, onDropAccepted, onDropRejected, validator]\n );\n\n const onDropCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n dragTargetsRef.current = [];\n\n if (isEvtWithFiles(event)) {\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n return;\n }\n setFiles(files as FileWithPath[], event);\n })\n .catch(e => onErrCb(e));\n }\n dispatch({type: \"reset\"});\n },\n [getFilesFromEvent, setFiles, onErrCb, noDragEventsBubbling]\n );\n\n // Fn for opening the file dialog programmatically\n const openFileDialog = useCallback(() => {\n // No point to use FS access APIs if context is not secure\n // https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#feature_detection\n if (fsAccessApiWorksRef.current) {\n dispatch({type: \"openDialog\"});\n onFileDialogOpenCb();\n // https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker\n const opts = {\n multiple,\n types: pickerTypes\n };\n (window as any)\n .showOpenFilePicker(opts)\n .then((handles: any) => getFilesFromEvent(handles))\n .then((files: Array<File | DataTransferItem>) => {\n setFiles(files as FileWithPath[], null);\n dispatch({type: \"closeDialog\"});\n })\n .catch((e: any) => {\n // AbortError means the user canceled\n if (isAbort(e)) {\n onFileDialogCancelCb(e);\n dispatch({type: \"closeDialog\"});\n } else if (isSecurityError(e)) {\n fsAccessApiWorksRef.current = false;\n // CORS, so cannot use this API\n // Try using the input\n if (inputRef.current) {\n inputRef.current.value = \"\";\n inputRef.current.click();\n } else {\n onErrCb(\n new Error(\n \"Cannot open the file picker because the https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API is not supported and no <input> was provided.\"\n )\n );\n }\n } else {\n onErrCb(e);\n }\n });\n return;\n }\n\n if (inputRef.current) {\n dispatch({type: \"openDialog\"});\n onFileDialogOpenCb();\n inputRef.current.value = \"\";\n inputRef.current.click();\n }\n }, [dispatch, onFileDialogOpenCb, onFileDialogCancelCb, useFsAccessApi, setFiles, onErrCb, pickerTypes, multiple]);\n\n // Cb to open the file dialog when SPACE/ENTER occurs on the dropzone\n const onKeyDownCb = useCallback(\n (event: any) => {\n // Ignore keyboard events bubbling up the DOM tree\n if (!rootRef.current?.isEqualNode(event.target)) {\n return;\n }\n\n if (event.key === \" \" || event.key === \"Enter\" || event.keyCode === 32 || event.keyCode === 13) {\n event.preventDefault();\n openFileDialog();\n }\n },\n [rootRef, openFileDialog]\n );\n\n // Update focus state for the dropzone\n const onFocusCb = useCallback(() => {\n dispatch({type: \"focus\"});\n }, []);\n const onBlurCb = useCallback(() => {\n dispatch({type: \"blur\"});\n }, []);\n\n // Cb to open the file dialog when click occurs on the dropzone\n const onClickCb = useCallback(() => {\n if (noClick) {\n return;\n }\n\n // In IE11/Edge the file-browser dialog is blocking, therefore, use setTimeout()\n // to ensure React can handle state changes\n // See: https://github.com/react-dropzone/react-dropzone/issues/450\n if (isIeOrEdge()) {\n setTimeout(openFileDialog, 0);\n } else {\n openFileDialog();\n }\n }, [noClick, openFileDialog]);\n\n const composeHandler = (fn: any) => {\n return disabled ? null : fn;\n };\n\n const composeKeyboardHandler = (fn: any) => {\n return noKeyboard ? null : composeHandler(fn);\n };\n\n const composeDragHandler = (fn: any) => {\n return noDrag ? null : composeHandler(fn);\n };\n\n const stopPropagation = (event: any) => {\n if (noDragEventsBubbling) {\n event.stopPropagation();\n }\n };\n\n const getRootProps = useMemo(\n () =>\n ({\n refKey = \"ref\",\n role,\n onKeyDown,\n onFocus,\n onBlur,\n onClick,\n onDragEnter,\n onDragOver,\n onDragLeave,\n onDrop,\n ...rest\n }: DropzoneRootProps = {}) => ({\n onKeyDown: composeKeyboardHandler(composeEventHandlers(onKeyDown, onKeyDownCb)),\n onFocus: composeKeyboardHandler(composeEventHandlers(onFocus, onFocusCb)),\n onBlur: composeKeyboardHandler(composeEventHandlers(onBlur, onBlurCb)),\n onClick: composeHandler(composeEventHandlers(onClick, onClickCb)),\n onDragEnter: composeDragHandler(composeEventHandlers(onDragEnter, onDragEnterCb)),\n onDragOver: composeDragHandler(composeEventHandlers(onDragOver, onDragOverCb)),\n onDragLeave: composeDragHandler(composeEventHandlers(onDragLeave, onDragLeaveCb)),\n onDrop: composeDragHandler(composeEventHandlers(onDrop, onDropCb)),\n role: typeof role === \"string\" && role !== \"\" ? role : \"presentation\",\n [refKey]: rootRef,\n ...(!disabled && !noKeyboard ? {tabIndex: 0} : {}),\n ...(disabled ? {\"aria-disabled\": true} : {}),\n ...rest\n }),\n [\n rootRef,\n onKeyDownCb,\n onFocusCb,\n onBlurCb,\n onClickCb,\n onDragEnterCb,\n onDragOverCb,\n onDragLeaveCb,\n onDropCb,\n noKeyboard,\n noDrag,\n disabled\n ]\n );\n\n const onInputElementClick = useCallback((event: any) => {\n event.stopPropagation();\n }, []);\n\n const getInputProps = useMemo(\n () =>\n ({refKey = \"ref\", onChange, onClick, ...rest}: DropzoneInputProps = {}) => {\n const inputProps = {\n accept: inputAcceptAttr,\n multiple,\n type: \"file\",\n \"aria-label\": \"file upload\",\n style: {\n border: 0,\n clip: \"rect(0, 0, 0, 0)\",\n clipPath: \"inset(50%)\",\n height: \"1px\",\n margin: \"0 -1px -1px 0\",\n overflow: \"hidden\",\n padding: 0,\n position: \"absolute\",\n width: \"1px\",\n whiteSpace: \"nowrap\"\n },\n onChange: composeHandler(composeEventHandlers(onChange, onDropCb)),\n onClick: composeHandler(composeEventHandlers(onClick, onInputElementClick)),\n tabIndex: -1,\n [refKey]: inputRef\n };\n\n return {\n ...inputProps,\n ...rest\n };\n },\n [inputRef, accept, multiple, onDropCb, disabled]\n );\n\n return {\n ...state,\n isFocused: isFocused && !disabled,\n getRootProps,\n getInputProps,\n rootRef,\n inputRef,\n open: composeHandler(openFileDialog)\n } as unknown as DropzoneState;\n}\n\nfunction reducer(state: DropzoneInternalState, action: any): DropzoneInternalState {\n switch (action.type) {\n case \"focus\":\n return {\n ...state,\n isFocused: true\n };\n case \"blur\":\n return {\n ...state,\n isFocused: false\n };\n case \"openDialog\":\n return {\n ...initialState,\n isFileDialogActive: true\n };\n case \"closeDialog\":\n return {\n ...state,\n isFileDialogActive: false\n };\n case \"setDraggedFiles\":\n return {\n ...state,\n isDragActive: action.isDragActive,\n isDragAccept: action.isDragAccept,\n isDragReject: action.isDragReject\n };\n case \"setFiles\":\n return {\n ...state,\n acceptedFiles: action.acceptedFiles,\n fileRejections: action.fileRejections,\n isDragReject: false\n };\n case \"setDragGlobal\":\n return {\n ...state,\n isDragGlobal: action.isDragGlobal\n };\n case \"reset\":\n return {\n ...initialState\n };\n default:\n return state;\n }\n}\n\nfunction noop() {}\n"],"mappings":";;;;;AAKA,MAAM,UACJ,OAAO,eAAe,aAAa,aAAc,WAAuD;AAkB1G,MAAa,oBAAoB;AACjC,MAAa,iBAAiB;AAC9B,MAAa,iBAAiB;AAC9B,MAAa,iBAAiB;AAE9B,IAAY,YAAL,yBAAA,WAAA;CACL,UAAA,qBAAA;CACA,UAAA,kBAAA;CACA,UAAA,kBAAA;CACA,UAAA,kBAAA;;AACF,EAAA,CAAA,CAAA;AAEA,SAAgB,2BAA2B,SAAiB,IAAe;CACzE,MAAM,YAAY,OAAO,MAAM,GAAG;CAClC,MAAM,MAAM,UAAU,SAAS,IAAI,UAAU,UAAU,KAAK,IAAI,MAAM,UAAU;CAEhF,OAAO;EACL,MAAM;EACN,SAAS,qBAAqB;CAChC;AACF;AAEA,MAAM,kBAAkB;CAAC;CAAM;CAAM;CAAM;CAAM;AAAI;;;;;AAMrD,SAAS,YAAY,OAAuB;CAC1C,IAAI,QAAQ,MACV,OAAO,GAAG,MAAM,GAAG,UAAU,IAAI,SAAS;CAG5C,IAAI,OAAO,QAAQ;CACnB,IAAI,YAAY;CAChB,OAAO,QAAQ,QAAQ,YAAY,gBAAgB,SAAS,GAAG;EAC7D,QAAQ;EACR;CACF;CAGA,OAAO,GAAG,OAAO,KAAK,QAAQ,CAAC,CAAC,EAAE,GAAG,gBAAgB;AACvD;AAEA,SAAgB,wBAAwB,SAA4B;CAClE,OAAO;EACL,MAAM;EACN,SAAS,uBAAuB,YAAY,OAAO;CACrD;AACF;AAEA,SAAgB,wBAAwB,SAA4B;CAClE,OAAO;EACL,MAAM;EACN,SAAS,wBAAwB,YAAY,OAAO;CACtD;AACF;AAEA,MAAa,2BAAsC;CACjD,MAAM;CACN,SAAS;AACX;;;;;;;;AASA,SAAgB,gCAAgC,MAAwC;CACtF,OAAO,KAAK,SAAS,MAAM,OAAQ,KAA0B,cAAc;AAC7E;;;;;;;;;;AAWA,SAAgB,aAAa,MAAY,QAA8C;CACrF,MAAM,eACJ,KAAK,SAAS,4BAA4B,QAAQ,MAAM,UAAU,EAAE,KAAK,gCAAgC,IAAI;CAC/G,OAAO,CAAC,cAAc,eAAe,OAAO,2BAA2B,MAAM,CAAC;AAChF;AAEA,SAAgB,cACd,MACA,SACA,SAC6B;CAC7B,IAAI,UAAU,KAAK,IAAI;MACjB,UAAU,OAAO,KAAK,UAAU,OAAO,GAAG;GAC5C,IAAI,KAAK,OAAO,SAAS,OAAO,CAAC,OAAO,wBAAwB,OAAO,CAAC;GACxE,IAAI,KAAK,OAAO,SAAS,OAAO,CAAC,OAAO,wBAAwB,OAAO,CAAC;EAC1E,OAAO,IAAI,UAAU,OAAO,KAAK,KAAK,OAAO,SAC3C,OAAO,CAAC,OAAO,wBAAwB,OAAO,CAAC;OAC1C,IAAI,UAAU,OAAO,KAAK,KAAK,OAAO,SAC3C,OAAO,CAAC,OAAO,wBAAwB,OAAO,CAAC;CAAA;CAGnD,OAAO,CAAC,MAAM,IAAI;AACpB;AAEA,SAAS,UAAa,OAAmC;CACvD,OAAO,UAAU,KAAA,KAAa,UAAU;AAC1C;AAEA,SAAgB,iBAAiB,EAC/B,OACA,QACA,SACA,SACA,UACA,WAAW,GACX,aASU;CACV,IAAK,CAAC,YAAY,MAAM,SAAS,KAAO,YAAY,YAAY,KAAK,MAAM,SAAS,UAClF,OAAO;CAGT,OAAO,MAAM,OAAM,SAAQ;EACzB,MAAM,CAAC,YAAY,aAAa,MAAM,MAAM;EAC5C,MAAM,CAAC,aAAa,cAAc,MAAM,SAAS,OAAO;EACxD,MAAM,eAAe,YAAY,UAAU,IAAI,IAAI;EACnD,OAAO,YAAY,aAAa,CAAC;CACnC,CAAC;AACH;AAKA,SAAgB,qBAAqB,OAAqB;CACxD,IAAI,OAAO,MAAM,yBAAyB,YACxC,OAAO,MAAM,qBAAqB;MAC7B,IAAI,OAAO,MAAM,iBAAiB,aACvC,OAAO,MAAM;CAEf,OAAO;AACT;AAEA,SAAgB,eAAe,OAAqB;CAClD,IAAI,CAAC,MAAM,cACT,OAAO,CAAC,CAAC,MAAM,UAAU,CAAC,CAAC,MAAM,OAAO;CAI1C,OAAO,MAAM,UAAU,KAAK,KAC1B,MAAM,aAAa,QAClB,SAAiB,SAAS,WAAW,SAAS,wBACjD;AACF;AAOA,SAAgB,mBAAmB,OAAoB;CACrD,MAAM,eAAe;AACvB;AAEA,SAAS,KAAK,WAA4B;CACxC,OAAO,UAAU,QAAQ,MAAM,MAAM,MAAM,UAAU,QAAQ,UAAU,MAAM;AAC/E;AAEA,SAAS,OAAO,WAA4B;CAC1C,OAAO,UAAU,QAAQ,OAAO,MAAM;AACxC;AAEA,SAAgB,WAAW,YAAoB,OAAO,UAAU,WAAoB;CAClF,OAAO,KAAK,SAAS,KAAK,OAAO,SAAS;AAC5C;;;;;;;;AASA,SAAgB,qBACd,GAAG,KACsC;CACzC,QAAQ,OAAY,GAAG,SACrB,IAAI,MAAK,OAAM;EACb,IAAI,CAAC,qBAAqB,KAAK,KAAK,IAClC,GAAG,OAAO,GAAG,IAAI;EAEnB,OAAO,qBAAqB,KAAK;CACnC,CAAC;AACL;;;;AAKA,SAAgB,4BAAqC;CACnD,OAAO,wBAAwB;AACjC;;;;AAKA,SAAgB,wBAAwB,QAA2E;CACjH,IAAI,UAAU,MAAM,GAuBlB,OAAO,CACL;EAEE,aAAa;EACb,QA1BoB,OAAO,QAAQ,MAAM,CAAC,CAC3C,QAAQ,CAAC,UAAU,SAAS;GAC3B,IAAI,KAAK;GAET,IAAI,CAAC,WAAW,QAAQ,GAAG;IACzB,QAAQ,KACN,YAAY,SAAS,sKACvB;IACA,KAAK;GACP;GAEA,IAAI,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,MAAM,KAAK,GAAG;IAC5C,QAAQ,KAAK,YAAY,SAAS,kDAAkD;IACpF,KAAK;GACP;GAEA,OAAO;EACT,CAAC,CAAC,CACD,QAAgB,KAAK,CAAC,UAAU,SAAS;GACxC,IAAI,YAAY;GAChB,OAAO;EACT,GAAG,CAAC,CAKoB;CACxB,CACF;AAGJ;;;;;;;;;;;;;AAcA,SAAgB,uBACd,QACA,EAAC,sCAAsC,UAA0D,CAAC,GAC9E;CACpB,IAAI,UAAU,MAAM,GAClB,OACE,OAAO,QAAQ,MAAM,CAAC,CACnB,QAAkB,GAAG,CAAC,UAAU,SAAS;EACxC,IAAI,uCAAuC,mBAAmB,QAAQ,KAAK,IAAI,KAAK,KAAK,GACvF,EAAE,KAAK,GAAG,GAAG;OAEb,EAAE,KAAK,UAAU,GAAG,GAAG;EAEzB,OAAO;CACT,GAAG,CAAC,CAAC,CAAC,CAEL,QAAO,MAAK,WAAW,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CACtC,KAAK,GAAG;AAKjB;;;;AAKA,SAAgB,QAAQ,GAAiB;CACvC,OAAO,aAAa,iBAAiB,EAAE,SAAS,gBAAgB,EAAE,SAAS,EAAE;AAC/E;;;;AAKA,SAAgB,gBAAgB,GAAiB;CAC/C,OAAO,aAAa,iBAAiB,EAAE,SAAS,mBAAmB,EAAE,SAAS,EAAE;AAClF;;;;AAKA,SAAgB,WAAW,GAAoB;CAC7C,OACE,MAAM,aACN,MAAM,aACN,MAAM,aACN,MAAM,YACN,MAAM,mBACN,iBAAiB,KAAK,CAAC;AAE3B;;;;AAKA,SAAgB,mBAAmB,GAAoB;CACrD,OAAO,EAAE,SAAS,IAAI;AACxB;;;;AAKA,SAAgB,MAAM,GAAoB;CACxC,OAAO,cAAc,KAAK,CAAC;AAC7B;;;;;;;;;;;;;;;;;ACrPA,MAAM,WAA8F,YAGjG,EAAC,UAAU,GAAG,UAAS,QAAQ;CAChC,MAAM,EAAC,MAAM,GAAG,UAAS,YAAY,MAAM;CAE3C,oBAAoB,YAAY,EAAC,KAAI,IAAI,CAAC,IAAI,CAAC;CAE/C,OAAO,oBAAA,UAAA,EAAA,UAAG,WAAW;EAAC,GAAG;EAAO;CAAI,CAAC,EAAI,CAAA;AAC3C,CAAC;AAED,SAAS,cAAc;AAevB,MAAM,eAAsC;CAC1C,WAAW;CACX,oBAAoB;CACpB,cAAc;CACd,cAAc;CACd,cAAc;CACd,cAAc;CACd,eAAe,CAAC;CAChB,gBAAgB,CAAC;AACnB;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,YAAY,QAAyB,CAAC,GAAkB;CACtE,MAAM,EACJ,QACA,WAAW,OACX,oBAAoB,WACpB,UAAU,OAAO,mBACjB,UAAU,GACV,WAAW,MACX,WAAW,GACX,aACA,aACA,YACA,QACA,gBACA,gBACA,oBACA,kBACA,iBAAiB,OACjB,YAAY,OACZ,wBAAwB,MACxB,UAAU,OACV,aAAa,OACb,SAAS,OACT,uBAAuB,OACvB,SACA,cACE;CAKJ,MAAM,aAAa,cAAc,uBAAuB,MAAM,GAAG,CAAC,MAAM,CAAC;CAIzE,MAAM,kBAAkB,cAEpB,uBAAuB,QAAQ,EAC7B,qCAAqC,KACvC,CAAC,GACH,CAAC,MAAM,CACT;CACA,MAAM,cAAc,cAAc,wBAAwB,MAAM,GAAG,CAAC,MAAM,CAAC;CAE3E,MAAM,qBAAqB,cAClB,OAAO,qBAAqB,aAAa,mBAAmB,MACnE,CAAC,gBAAgB,CACnB;CACA,MAAM,uBAAuB,cACpB,OAAO,uBAAuB,aAAa,qBAAqB,MACvE,CAAC,kBAAkB,CACrB;CAEA,MAAM,UAAU,OAAoB,IAAI;CACxC,MAAM,WAAW,OAAyB,IAAI;CAE9C,MAAM,CAAC,OAAO,YAAY,WAAW,SAAS,YAAY;CAC1D,MAAM,EAAC,WAAW,uBAAsB;CAExC,MAAM,sBAAsB,OAC1B,OAAO,WAAW,eAAe,OAAO,mBAAmB,kBAAkB,0BAA0B,CACzG;CAGA,MAAM,sBAAsB;EAE1B,IAAI,CAAC,oBAAoB,WAAW,oBAClC,iBAAiB;GACf,IAAI,SAAS,SAAS;IACpB,MAAM,EAAC,UAAS,SAAS;IAEzB,IAAI,CAAC,OAAO,QAAQ;KAClB,SAAS,EAAC,MAAM,cAAa,CAAC;KAC9B,qBAAqB;IACvB;GACF;EACF,GAAG,GAAG;CAEV;CACA,gBAAgB;EACd,OAAO,iBAAiB,SAAS,eAAe,KAAK;EACrD,aAAa;GACX,OAAO,oBAAoB,SAAS,eAAe,KAAK;EAC1D;CACF,GAAG;EAAC;EAAU;EAAoB;EAAsB;CAAmB,CAAC;CAE5E,MAAM,iBAAiB,OAAsB,CAAC,CAAC;CAC/C,MAAM,uBAAuB,OAAsB,CAAC,CAAC;CACrD,MAAM,kBAAkB,UAAqB;EAC3C,IAAI,QAAQ,WAAW,MAAM,UAAU,QAAQ,QAAQ,SAAS,MAAM,MAAc,GAElF;EAEF,MAAM,eAAe;EACrB,eAAe,UAAU,CAAC;CAC5B;CAEA,gBAAgB;EACd,IAAI,uBAAuB;GACzB,SAAS,iBAAiB,YAAY,oBAAoB,KAAK;GAC/D,SAAS,iBAAiB,QAAQ,gBAAgB,KAAK;EACzD;EAEA,aAAa;GACX,IAAI,uBAAuB;IACzB,SAAS,oBAAoB,YAAY,kBAAkB;IAC3D,SAAS,oBAAoB,QAAQ,cAAc;GACrD;EACF;CACF,GAAG,CAAC,SAAS,qBAAqB,CAAC;CAGnC,gBAAgB;EACd,MAAM,uBAAuB,UAAqB;GAChD,IAAI,MAAM,QACR,qBAAqB,UAAU,CAAC,GAAG,qBAAqB,SAAS,MAAM,MAAM;GAG/E,IAAI,eAAe,KAAK,GACtB,SAAS;IAAC,cAAc;IAAM,MAAM;GAAe,CAAC;EAExD;EAEA,MAAM,uBAAuB,UAAqB;GAEhD,qBAAqB,UAAU,qBAAqB,QAAQ,QAAO,OAAM,OAAO,MAAM,UAAU,OAAO,IAAI;GAE3G,IAAI,qBAAqB,QAAQ,SAAS,GACxC;GAGF,SAAS;IAAC,cAAc;IAAO,MAAM;GAAe,CAAC;EACvD;EAEA,MAAM,0BAA0B;GAC9B,qBAAqB,UAAU,CAAC;GAChC,SAAS;IAAC,cAAc;IAAO,MAAM;GAAe,CAAC;EACvD;EAEA,MAAM,6BAA6B;GACjC,qBAAqB,UAAU,CAAC;GAChC,SAAS;IAAC,cAAc;IAAO,MAAM;GAAe,CAAC;EACvD;EAEA,SAAS,iBAAiB,aAAa,qBAAqB,KAAK;EACjE,SAAS,iBAAiB,aAAa,qBAAqB,KAAK;EACjE,SAAS,iBAAiB,WAAW,mBAAmB,KAAK;EAC7D,SAAS,iBAAiB,QAAQ,sBAAsB,KAAK;EAE7D,aAAa;GACX,SAAS,oBAAoB,aAAa,mBAAmB;GAC7D,SAAS,oBAAoB,aAAa,mBAAmB;GAC7D,SAAS,oBAAoB,WAAW,iBAAiB;GACzD,SAAS,oBAAoB,QAAQ,oBAAoB;EAC3D;CACF,GAAG,CAAC,OAAO,CAAC;CAGZ,gBAAgB;EACd,IAAI,CAAC,YAAY,aAAa,QAAQ,SACpC,QAAQ,QAAQ,MAAM;EAExB,aAAa,CAAC;CAChB,GAAG;EAAC;EAAS;EAAW;CAAQ,CAAC;CAEjC,MAAM,UAAU,aACb,MAAa;EACZ,IAAI,SACF,QAAQ,CAAC;OAGT,QAAQ,MAAM,CAAC;CAEnB,GACA,CAAC,OAAO,CACV;CAEA,MAAM,gBAAgB,aACnB,UAAe;EACd,MAAM,eAAe;EAErB,MAAM,UAAU;EAChB,gBAAgB,KAAK;EAErB,eAAe,UAAU,CAAC,GAAG,eAAe,SAAS,MAAM,MAAM;EAEjE,IAAI,eAAe,KAAK,GACtB,QAAQ,QAAQ,kBAAkB,KAAK,CAAC,CAAC,CACtC,MAAK,UAAS;GACb,IAAI,qBAAqB,KAAK,KAAK,CAAC,sBAClC;GAGF,MAAM,YAAY,MAAM;GACxB,MAAM,eACJ,YAAY,KACZ,iBAAiB;IACR;IACP,QAAQ;IACR;IACA;IACA;IACA;IACA;GACF,CAAC;GAGH,SAAS;IACP;IACA,cAJmB,YAAY,KAAK,CAAC;IAKrC,cAAc;IACd,MAAM;GACR,CAAC;GAED,IAAI,aACF,YAAY,KAAK;EAErB,CAAC,CAAC,CACD,OAAM,MAAK,QAAQ,CAAC,CAAC;CAE5B,GACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF;CAEA,MAAM,eAAe,aAClB,UAAe;EACd,MAAM,eAAe;EACrB,MAAM,UAAU;EAChB,gBAAgB,KAAK;EAErB,MAAM,WAAW,eAAe,KAAK;EACrC,IAAI,YAAY,MAAM,cACpB,IAAI;GACF,MAAM,aAAa,aAAa;EAClC,QAAQ,CAER;EAGF,IAAI,YAAY,YACd,WAAW,KAAK;EAGlB,OAAO;CACT,GACA,CAAC,YAAY,oBAAoB,CACnC;CAEA,MAAM,gBAAgB,aACnB,UAAe;EACd,MAAM,eAAe;EACrB,MAAM,UAAU;EAChB,gBAAgB,KAAK;EAGrB,MAAM,UAAU,eAAe,QAAQ,QAAO,WAAU,QAAQ,SAAS,SAAS,MAAc,CAAC;EAGjG,MAAM,YAAY,QAAQ,QAAQ,MAAM,MAAM;EAC9C,IAAI,cAAc,IAChB,QAAQ,OAAO,WAAW,CAAC;EAE7B,eAAe,UAAU;EACzB,IAAI,QAAQ,SAAS,GACnB;EAGF,SAAS;GACP,MAAM;GACN,cAAc;GACd,cAAc;GACd,cAAc;EAChB,CAAC;EAED,IAAI,eAAe,KAAK,KAAK,aAC3B,YAAY,KAAK;CAErB,GACA;EAAC;EAAS;EAAa;CAAoB,CAC7C;CAEA,MAAM,WAAW,aACd,OAAuB,UAAe;EACrC,MAAM,gBAAgC,CAAC;EACvC,MAAM,iBAAkC,CAAC;EAEzC,MAAM,SAAQ,SAAQ;GACpB,MAAM,CAAC,UAAU,eAAe,aAAa,MAAM,eAAe;GAClE,MAAM,CAAC,WAAW,aAAa,cAAc,MAAM,SAAS,OAAO;GACnE,MAAM,eAAe,YAAY,UAAU,IAAI,IAAI;GAEnD,IAAI,YAAY,aAAa,CAAC,cAC5B,cAAc,KAAK,IAAI;QAClB;IACL,IAAI,SAAkC,CAAC,aAAa,SAAS;IAE7D,IAAI,cACF,SAAS,OAAO,OAAO,YAAY;IAGrC,eAAe,KAAK;KAClB;KACA,QAAQ,OAAO,QAAQ,MAAsB,KAAK,IAAI;IACxD,CAAC;GACH;EACF,CAAC;EAED,IAAK,CAAC,YAAY,cAAc,SAAS,KAAO,YAAY,YAAY,KAAK,cAAc,SAAS,UAAW;GAE7G,cAAc,SAAQ,SAAQ;IAC5B,eAAe,KAAK;KAAC;KAAM,QAAQ,CAAC,wBAAwB;IAAC,CAAC;GAChE,CAAC;GACD,cAAc,OAAO,CAAC;EACxB;EAEA,SAAS;GACP;GACA;GACA,MAAM;EACR,CAAC;EAED,IAAI,QACF,OAAO,eAAe,gBAAgB,KAAK;EAG7C,IAAI,eAAe,SAAS,KAAK,gBAC/B,eAAe,gBAAgB,KAAK;EAGtC,IAAI,cAAc,SAAS,KAAK,gBAC9B,eAAe,eAAe,KAAK;CAEvC,GACA;EAAC;EAAU;EAAU;EAAiB;EAAS;EAAS;EAAU;EAAQ;EAAgB;EAAgB;CAAS,CACrH;CAEA,MAAM,WAAW,aACd,UAAe;EACd,MAAM,eAAe;EAErB,MAAM,UAAU;EAChB,gBAAgB,KAAK;EAErB,eAAe,UAAU,CAAC;EAE1B,IAAI,eAAe,KAAK,GACtB,QAAQ,QAAQ,kBAAkB,KAAK,CAAC,CAAC,CACtC,MAAK,UAAS;GACb,IAAI,qBAAqB,KAAK,KAAK,CAAC,sBAClC;GAEF,SAAS,OAAyB,KAAK;EACzC,CAAC,CAAC,CACD,OAAM,MAAK,QAAQ,CAAC,CAAC;EAE1B,SAAS,EAAC,MAAM,QAAO,CAAC;CAC1B,GACA;EAAC;EAAmB;EAAU;EAAS;CAAoB,CAC7D;CAGA,MAAM,iBAAiB,kBAAkB;EAGvC,IAAI,oBAAoB,SAAS;GAC/B,SAAS,EAAC,MAAM,aAAY,CAAC;GAC7B,mBAAmB;GAEnB,MAAM,OAAO;IACX;IACA,OAAO;GACT;GACA,OACG,mBAAmB,IAAI,CAAC,CACxB,MAAM,YAAiB,kBAAkB,OAAO,CAAC,CAAC,CAClD,MAAM,UAA0C;IAC/C,SAAS,OAAyB,IAAI;IACtC,SAAS,EAAC,MAAM,cAAa,CAAC;GAChC,CAAC,CAAC,CACD,OAAO,MAAW;IAEjB,IAAI,QAAQ,CAAC,GAAG;KACd,qBAAqB,CAAC;KACtB,SAAS,EAAC,MAAM,cAAa,CAAC;IAChC,OAAO,IAAI,gBAAgB,CAAC,GAAG;KAC7B,oBAAoB,UAAU;KAG9B,IAAI,SAAS,SAAS;MACpB,SAAS,QAAQ,QAAQ;MACzB,SAAS,QAAQ,MAAM;KACzB,OACE,wBACE,IAAI,MACF,+JACF,CACF;IAEJ,OACE,QAAQ,CAAC;GAEb,CAAC;GACH;EACF;EAEA,IAAI,SAAS,SAAS;GACpB,SAAS,EAAC,MAAM,aAAY,CAAC;GAC7B,mBAAmB;GACnB,SAAS,QAAQ,QAAQ;GACzB,SAAS,QAAQ,MAAM;EACzB;CACF,GAAG;EAAC;EAAU;EAAoB;EAAsB;EAAgB;EAAU;EAAS;EAAa;CAAQ,CAAC;CAGjH,MAAM,cAAc,aACjB,UAAe;EAEd,IAAI,CAAC,QAAQ,SAAS,YAAY,MAAM,MAAM,GAC5C;EAGF,IAAI,MAAM,QAAQ,OAAO,MAAM,QAAQ,WAAW,MAAM,YAAY,MAAM,MAAM,YAAY,IAAI;GAC9F,MAAM,eAAe;GACrB,eAAe;EACjB;CACF,GACA,CAAC,SAAS,cAAc,CAC1B;CAGA,MAAM,YAAY,kBAAkB;EAClC,SAAS,EAAC,MAAM,QAAO,CAAC;CAC1B,GAAG,CAAC,CAAC;CACL,MAAM,WAAW,kBAAkB;EACjC,SAAS,EAAC,MAAM,OAAM,CAAC;CACzB,GAAG,CAAC,CAAC;CAGL,MAAM,YAAY,kBAAkB;EAClC,IAAI,SACF;EAMF,IAAI,WAAW,GACb,WAAW,gBAAgB,CAAC;OAE5B,eAAe;CAEnB,GAAG,CAAC,SAAS,cAAc,CAAC;CAE5B,MAAM,kBAAkB,OAAY;EAClC,OAAO,WAAW,OAAO;CAC3B;CAEA,MAAM,0BAA0B,OAAY;EAC1C,OAAO,aAAa,OAAO,eAAe,EAAE;CAC9C;CAEA,MAAM,sBAAsB,OAAY;EACtC,OAAO,SAAS,OAAO,eAAe,EAAE;CAC1C;CAEA,MAAM,mBAAmB,UAAe;EACtC,IAAI,sBACF,MAAM,gBAAgB;CAE1B;CAEA,MAAM,eAAe,eAEhB,EACC,SAAS,OACT,MACA,WACA,SACA,QACA,SACA,aACA,YACA,aACA,QACA,GAAG,SACkB,CAAC,OAAO;EAC7B,WAAW,uBAAuB,qBAAqB,WAAW,WAAW,CAAC;EAC9E,SAAS,uBAAuB,qBAAqB,SAAS,SAAS,CAAC;EACxE,QAAQ,uBAAuB,qBAAqB,QAAQ,QAAQ,CAAC;EACrE,SAAS,eAAe,qBAAqB,SAAS,SAAS,CAAC;EAChE,aAAa,mBAAmB,qBAAqB,aAAa,aAAa,CAAC;EAChF,YAAY,mBAAmB,qBAAqB,YAAY,YAAY,CAAC;EAC7E,aAAa,mBAAmB,qBAAqB,aAAa,aAAa,CAAC;EAChF,QAAQ,mBAAmB,qBAAqB,QAAQ,QAAQ,CAAC;EACjE,MAAM,OAAO,SAAS,YAAY,SAAS,KAAK,OAAO;GACtD,SAAS;EACV,GAAI,CAAC,YAAY,CAAC,aAAa,EAAC,UAAU,EAAC,IAAI,CAAC;EAChD,GAAI,WAAW,EAAC,iBAAiB,KAAI,IAAI,CAAC;EAC1C,GAAG;CACL,IACF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF;CAEA,MAAM,sBAAsB,aAAa,UAAe;EACtD,MAAM,gBAAgB;CACxB,GAAG,CAAC,CAAC;CAEL,MAAM,gBAAgB,eAEjB,EAAC,SAAS,OAAO,UAAU,SAAS,GAAG,SAA4B,CAAC,MAAM;EAwBzE,OAAO;GAtBL,QAAQ;GACR;GACA,MAAM;GACN,cAAc;GACd,OAAO;IACL,QAAQ;IACR,MAAM;IACN,UAAU;IACV,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,SAAS;IACT,UAAU;IACV,OAAO;IACP,YAAY;GACd;GACA,UAAU,eAAe,qBAAqB,UAAU,QAAQ,CAAC;GACjE,SAAS,eAAe,qBAAqB,SAAS,mBAAmB,CAAC;GAC1E,UAAU;IACT,SAAS;GAKV,GAAG;EACL;CACF,GACF;EAAC;EAAU;EAAQ;EAAU;EAAU;CAAQ,CACjD;CAEA,OAAO;EACL,GAAG;EACH,WAAW,aAAa,CAAC;EACzB;EACA;EACA;EACA;EACA,MAAM,eAAe,cAAc;CACrC;AACF;AAEA,SAAS,QAAQ,OAA8B,QAAoC;CACjF,QAAQ,OAAO,MAAf;EACE,KAAK,SACH,OAAO;GACL,GAAG;GACH,WAAW;EACb;EACF,KAAK,QACH,OAAO;GACL,GAAG;GACH,WAAW;EACb;EACF,KAAK,cACH,OAAO;GACL,GAAG;GACH,oBAAoB;EACtB;EACF,KAAK,eACH,OAAO;GACL,GAAG;GACH,oBAAoB;EACtB;EACF,KAAK,mBACH,OAAO;GACL,GAAG;GACH,cAAc,OAAO;GACrB,cAAc,OAAO;GACrB,cAAc,OAAO;EACvB;EACF,KAAK,YACH,OAAO;GACL,GAAG;GACH,eAAe,OAAO;GACtB,gBAAgB,OAAO;GACvB,cAAc;EAChB;EACF,KAAK,iBACH,OAAO;GACL,GAAG;GACH,cAAc,OAAO;EACvB;EACF,KAAK,SACH,OAAO,EACL,GAAG,aACL;EACF,SACE,OAAO;CACX;AACF;AAEA,SAAS,OAAO,CAAC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/utils/index.ts","../src/index.tsx"],"sourcesContent":["import attrAccept from \"attr-accept\";\n\n// attr-accept ships as a CommonJS module (`module.exports = { __esModule: true, default: fn }`).\n// Bundler interop surfaces its default export inconsistently — as the function under Node/Vitest,\n// but as `{ default: fn }` in some browser bundles. Normalize to the function.\nconst accepts =\n typeof attrAccept === \"function\" ? attrAccept : (attrAccept as unknown as {default: typeof attrAccept}).default;\n\n/**\n * A map of accepted MIME types to file extensions, as passed to the `accept` prop.\n */\nexport interface Accept {\n [key: string]: readonly string[];\n}\n\n/**\n * A file rejection error.\n */\nexport interface FileError {\n message: string;\n code: ErrorCode | string;\n}\n\n// Error codes\nexport const FILE_INVALID_TYPE = \"file-invalid-type\";\nexport const FILE_TOO_LARGE = \"file-too-large\";\nexport const FILE_TOO_SMALL = \"file-too-small\";\nexport const TOO_MANY_FILES = \"too-many-files\";\n\nexport enum ErrorCode {\n FileInvalidType = \"file-invalid-type\",\n FileTooLarge = \"file-too-large\",\n FileTooSmall = \"file-too-small\",\n TooManyFiles = \"too-many-files\"\n}\n\nexport function getInvalidTypeRejectionErr(accept: string = \"\"): FileError {\n const acceptArr = accept.split(\",\");\n const msg = acceptArr.length > 1 ? `one of ${acceptArr.join(\", \")}` : acceptArr[0];\n\n return {\n code: FILE_INVALID_TYPE,\n message: `File type must be ${msg}`\n };\n}\n\nconst FILE_SIZE_UNITS = [\"KB\", \"MB\", \"GB\", \"TB\", \"PB\"];\n\n/**\n * Format a byte count into a human-readable string, e.g. `1111` -> `1.08 KB`.\n * Values below 1 KB are kept in bytes to preserve the singular/plural wording.\n */\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} ${bytes === 1 ? \"byte\" : \"bytes\"}`;\n }\n\n let size = bytes / 1024;\n let unitIndex = 0;\n while (size >= 1024 && unitIndex < FILE_SIZE_UNITS.length - 1) {\n size /= 1024;\n unitIndex++;\n }\n\n // Round to 2 decimals, then drop trailing zeros (1.00 -> 1, 1.50 -> 1.5).\n return `${Number(size.toFixed(2))} ${FILE_SIZE_UNITS[unitIndex]}`;\n}\n\nexport function getTooLargeRejectionErr(maxSize: number): FileError {\n return {\n code: FILE_TOO_LARGE,\n message: `File is larger than ${formatBytes(maxSize)}`\n };\n}\n\nexport function getTooSmallRejectionErr(minSize: number): FileError {\n return {\n code: FILE_TOO_SMALL,\n message: `File is smaller than ${formatBytes(minSize)}`\n };\n}\n\nexport const TOO_MANY_FILES_REJECTION: FileError = {\n code: TOO_MANY_FILES,\n message: \"Too many files\"\n};\n\n/**\n * Check if the given file is a DataTransferItem with an empty type.\n *\n * During drag events, browsers may return DataTransferItem objects instead of File objects.\n * Some browsers (e.g., Chrome) return an empty MIME type for certain file types (like .md files)\n * on DataTransferItem during drag events, even though the type is correctly set during drop.\n */\nexport function isDataTransferItemWithEmptyType(file: File | DataTransferItem): boolean {\n return file.type === \"\" && typeof (file as DataTransferItem).getAsFile === \"function\";\n}\n\n/**\n * Check if file is accepted.\n *\n * Firefox versions prior to 53 return a bogus MIME type for every file drag,\n * so dragovers with that MIME type will always be accepted.\n *\n * Chrome/other browsers may return an empty MIME type for files during drag events,\n * so we accept those as well (we'll validate properly on drop).\n */\nexport function fileAccepted(file: File, accept?: string): [boolean, FileError | null] {\n const isAcceptable =\n file.type === \"application/x-moz-file\" || accepts(file, accept ?? \"\") || isDataTransferItemWithEmptyType(file);\n return [isAcceptable, isAcceptable ? null : getInvalidTypeRejectionErr(accept)];\n}\n\nexport function fileMatchSize(\n file: {size?: number | null},\n minSize?: number,\n maxSize?: number\n): [boolean, FileError | null] {\n if (isDefined(file.size)) {\n if (isDefined(minSize) && isDefined(maxSize)) {\n if (file.size > maxSize) return [false, getTooLargeRejectionErr(maxSize)];\n if (file.size < minSize) return [false, getTooSmallRejectionErr(minSize)];\n } else if (isDefined(minSize) && file.size < minSize) {\n return [false, getTooSmallRejectionErr(minSize)];\n } else if (isDefined(maxSize) && file.size > maxSize) {\n return [false, getTooLargeRejectionErr(maxSize)];\n }\n }\n return [true, null];\n}\n\nfunction isDefined<T>(value: T): value is NonNullable<T> {\n return value !== undefined && value !== null;\n}\n\nexport function allFilesAccepted({\n files,\n accept,\n minSize,\n maxSize,\n multiple,\n maxFiles = 0,\n validator\n}: {\n files: File[];\n accept?: string;\n minSize?: number;\n maxSize?: number;\n multiple?: boolean;\n maxFiles?: number;\n validator?: (file: File) => FileError | readonly FileError[] | null;\n}): boolean {\n if ((!multiple && files.length > 1) || (multiple && maxFiles >= 1 && files.length > maxFiles)) {\n return false;\n }\n\n return files.every(file => {\n const [accepted] = fileAccepted(file, accept);\n const [sizeMatch] = fileMatchSize(file, minSize, maxSize);\n const customErrors = validator ? validator(file) : null;\n return accepted && sizeMatch && !customErrors;\n });\n}\n\n// React's synthetic events has event.isPropagationStopped,\n// but to remain compatibility with other libs (Preact) fall back\n// to check event.cancelBubble\nexport function isPropagationStopped(event: any): boolean {\n if (typeof event.isPropagationStopped === \"function\") {\n return event.isPropagationStopped();\n } else if (typeof event.cancelBubble !== \"undefined\") {\n return event.cancelBubble;\n }\n return false;\n}\n\nexport function isEvtWithFiles(event: any): boolean {\n if (!event.dataTransfer) {\n return !!event.target && !!event.target.files;\n }\n // https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/types\n // https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#file\n return Array.prototype.some.call(\n event.dataTransfer.types,\n (type: string) => type === \"Files\" || type === \"application/x-moz-file\"\n );\n}\n\nexport function isKindFile(item: any): boolean {\n return typeof item === \"object\" && item !== null && item.kind === \"file\";\n}\n\n// allow the entire document to be a drag target\nexport function onDocumentDragOver(event: Event): void {\n event.preventDefault();\n}\n\nfunction isIe(userAgent: string): boolean {\n return userAgent.indexOf(\"MSIE\") !== -1 || userAgent.indexOf(\"Trident/\") !== -1;\n}\n\nfunction isEdge(userAgent: string): boolean {\n return userAgent.indexOf(\"Edge/\") !== -1;\n}\n\nexport function isIeOrEdge(userAgent: string = window.navigator.userAgent): boolean {\n return isIe(userAgent) || isEdge(userAgent);\n}\n\n/**\n * This is intended to be used to compose event handlers.\n * They are executed in order until one of them calls `event.isPropagationStopped()`.\n * Note that the check is done on the first invoke too,\n * meaning that if propagation was stopped before invoking the fns,\n * no handlers will be executed.\n */\nexport function composeEventHandlers(\n ...fns: Array<((event: any, ...args: any[]) => void) | null | undefined>\n): (event: any, ...args: any[]) => boolean {\n return (event: any, ...args: any[]) =>\n fns.some(fn => {\n if (!isPropagationStopped(event) && fn) {\n fn(event, ...args);\n }\n return isPropagationStopped(event);\n });\n}\n\n/**\n * canUseFileSystemAccessAPI checks if the File System Access API is supported by the browser.\n */\nexport function canUseFileSystemAccessAPI(): boolean {\n return \"showOpenFilePicker\" in window;\n}\n\n/**\n * Convert the `{accept}` dropzone prop to the `{types}` option for showOpenFilePicker.\n */\nexport function pickerOptionsFromAccept(accept?: Accept): Array<{description: string; accept: Accept}> | undefined {\n if (isDefined(accept)) {\n const acceptForPicker = Object.entries(accept)\n .filter(([mimeType, ext]) => {\n let ok = true;\n\n if (!isMIMEType(mimeType)) {\n console.warn(\n `Skipped \"${mimeType}\" because it is not a valid MIME type. Check https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types for a list of valid MIME types.`\n );\n ok = false;\n }\n\n if (!Array.isArray(ext) || !ext.every(isExt)) {\n console.warn(`Skipped \"${mimeType}\" because an invalid file extension was provided.`);\n ok = false;\n }\n\n return ok;\n })\n .reduce<Accept>((agg, [mimeType, ext]) => {\n agg[mimeType] = ext;\n return agg;\n }, {});\n return [\n {\n // description is required due to https://crbug.com/1264708\n description: \"Files\",\n accept: acceptForPicker\n }\n ];\n }\n return undefined;\n}\n\n/**\n * Convert the `{accept}` dropzone prop to a comma-separated accept attribute string.\n *\n * When `omitWildcardMimeTypesWithExtensions` is set, a wildcard MIME type (e.g. `image/*`)\n * that is paired with explicit extensions is dropped in favour of those extensions. The\n * accept attribute is an OR list, so leaving `image/*` in would make both the native file\n * picker and the drop-time validator accept ANY file of that type, ignoring the extension\n * restriction. The drag-time `isDragAccept` check keeps the wildcard because file names\n * (and therefore extensions) aren't readable during a drag.\n *\n * See https://github.com/react-dropzone/react-dropzone/issues/1220\n */\nexport function acceptPropAsAcceptAttr(\n accept?: Accept,\n {omitWildcardMimeTypesWithExtensions = false}: {omitWildcardMimeTypesWithExtensions?: boolean} = {}\n): string | undefined {\n if (isDefined(accept)) {\n return (\n Object.entries(accept)\n .reduce<string[]>((a, [mimeType, ext]) => {\n if (omitWildcardMimeTypesWithExtensions && isMIMETypeWildcard(mimeType) && ext.some(isExt)) {\n a.push(...ext);\n } else {\n a.push(mimeType, ...ext);\n }\n return a;\n }, [])\n // Silently discard invalid entries as pickerOptionsFromAccept warns about these\n .filter(v => isMIMEType(v) || isExt(v))\n .join(\",\")\n );\n }\n\n return undefined;\n}\n\n/**\n * Check if v is an exception caused by aborting a request (e.g window.showOpenFilePicker()).\n */\nexport function isAbort(v: any): boolean {\n return v instanceof DOMException && (v.name === \"AbortError\" || v.code === v.ABORT_ERR);\n}\n\n/**\n * Check if v is a security error.\n */\nexport function isSecurityError(v: any): boolean {\n return v instanceof DOMException && (v.name === \"SecurityError\" || v.code === v.SECURITY_ERR);\n}\n\n/**\n * Check if v is a \"not allowed\" error.\n *\n * Some browsers/configurations block `window.showOpenFilePicker()` outright and reject with a\n * `NotAllowedError` instead of showing the picker (e.g. Microsoft Edge for Business, or other\n * restrictive enterprise/security policies). We treat this like a security error and fall back\n * to the native `<input>`. See https://github.com/react-dropzone/react-dropzone/issues/1429\n */\nexport function isNotAllowedError(v: any): boolean {\n return v instanceof DOMException && v.name === \"NotAllowedError\";\n}\n\n/**\n * Check if v is a MIME type string.\n */\nexport function isMIMEType(v: string): boolean {\n return (\n v === \"audio/*\" ||\n v === \"video/*\" ||\n v === \"image/*\" ||\n v === \"text/*\" ||\n v === \"application/*\" ||\n /\\w+\\/[-+.\\w]+/g.test(v)\n );\n}\n\n/**\n * Check if v is a wildcard MIME type (e.g. `image/*`).\n */\nexport function isMIMETypeWildcard(v: string): boolean {\n return v.endsWith(\"/*\");\n}\n\n/**\n * Check if v is a file extension.\n */\nexport function isExt(v: string): boolean {\n return /^.*\\.[\\w]+$/.test(v);\n}\n","import {fromEvent} from \"file-selector\";\nimport type {FileWithPath} from \"file-selector\";\nimport type * as React from \"react\";\nimport {forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useReducer, useRef} from \"react\";\nimport {\n acceptPropAsAcceptAttr,\n allFilesAccepted,\n canUseFileSystemAccessAPI,\n composeEventHandlers,\n ErrorCode,\n fileAccepted,\n fileMatchSize,\n isAbort,\n isEvtWithFiles,\n isIeOrEdge,\n isNotAllowedError,\n isPropagationStopped,\n isSecurityError,\n onDocumentDragOver,\n pickerOptionsFromAccept,\n TOO_MANY_FILES_REJECTION\n} from \"./utils\";\nimport type {Accept, FileError} from \"./utils\";\n\nexport type {Accept, FileError, FileWithPath};\nexport {ErrorCode};\n\nexport interface DropzoneProps extends DropzoneOptions {\n children?: (state: DropzoneState) => React.ReactElement;\n}\n\nexport interface FileRejection {\n file: FileWithPath;\n errors: readonly FileError[];\n}\n\ntype SharedProps = \"multiple\" | \"onDragEnter\" | \"onDragOver\" | \"onDragLeave\";\n\nexport type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> & {\n accept?: Accept;\n minSize?: number;\n maxSize?: number;\n maxFiles?: number;\n preventDropOnDocument?: boolean;\n noClick?: boolean;\n noKeyboard?: boolean;\n noDrag?: boolean;\n noDragEventsBubbling?: boolean;\n disabled?: boolean;\n onDrop?: <T extends File>(acceptedFiles: T[], fileRejections: FileRejection[], event: DropEvent) => void;\n onDropAccepted?: <T extends File>(files: T[], event: DropEvent) => void;\n onDropRejected?: (fileRejections: FileRejection[], event: DropEvent) => void;\n getFilesFromEvent?: (event: DropEvent | Array<FileSystemFileHandle>) => Promise<Array<File | DataTransferItem>>;\n onFileDialogCancel?: () => void;\n onFileDialogOpen?: () => void;\n onError?: (err: Error) => void;\n validator?: <T extends File>(file: T) => FileError | readonly FileError[] | null;\n /**\n * Override the message of any rejection error (built-in or custom). Called once per error;\n * receives the error and the file it belongs to and returns the message to use. Return\n * `error.message` for codes you don't want to change. Useful for localizing error messages.\n */\n getErrorMessage?: (error: FileError, file: File) => string;\n useFsAccessApi?: boolean;\n autoFocus?: boolean;\n};\n\nexport type DropEvent = React.DragEvent<HTMLElement> | React.ChangeEvent<HTMLInputElement> | DragEvent | Event;\n\nexport interface DropzoneRef {\n open: () => void;\n}\n\nexport type DropzoneState = DropzoneRef & {\n isFocused: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragGlobal: boolean;\n isFileDialogActive: boolean;\n acceptedFiles: readonly FileWithPath[];\n fileRejections: readonly FileRejection[];\n rootRef: React.RefObject<HTMLElement>;\n inputRef: React.RefObject<HTMLInputElement>;\n getRootProps: <T extends DropzoneRootProps>(props?: T) => T;\n getInputProps: <T extends DropzoneInputProps>(props?: T) => T;\n};\n\nexport interface DropzoneRootProps extends React.HTMLAttributes<HTMLElement> {\n refKey?: string;\n [key: string]: any;\n}\n\nexport interface DropzoneInputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n refKey?: string;\n}\n\n/**\n * Convenience wrapper component for the `useDropzone` hook\n *\n * ```jsx\n * <Dropzone>\n * {({getRootProps, getInputProps}) => (\n * <div {...getRootProps()}>\n * <input {...getInputProps()} />\n * <p>Drag 'n' drop some files here, or click to select files</p>\n * </div>\n * )}\n * </Dropzone>\n * ```\n */\nconst Dropzone: React.ForwardRefExoticComponent<DropzoneProps & React.RefAttributes<DropzoneRef>> = forwardRef<\n DropzoneRef,\n DropzoneProps\n>(({children, ...params}, ref) => {\n const {open, ...props} = useDropzone(params);\n\n useImperativeHandle(ref, () => ({open}), [open]);\n\n return <>{children?.({...props, open})}</>;\n});\n\nDropzone.displayName = \"Dropzone\";\n\nexport default Dropzone;\n\ninterface DropzoneInternalState {\n isFocused: boolean;\n isFileDialogActive: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragGlobal: boolean;\n acceptedFiles: FileWithPath[];\n fileRejections: FileRejection[];\n}\n\nconst initialState: DropzoneInternalState = {\n isFocused: false,\n isFileDialogActive: false,\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false,\n isDragGlobal: false,\n acceptedFiles: [],\n fileRejections: []\n};\n\n/**\n * A React hook that creates a drag 'n' drop area.\n *\n * ```jsx\n * function MyDropzone(props) {\n * const {getRootProps, getInputProps} = useDropzone({\n * onDrop: acceptedFiles => {\n * // do something with the File objects, e.g. upload to some server\n * }\n * });\n * return (\n * <div {...getRootProps()}>\n * <input {...getInputProps()} />\n * <p>Drag and drop some files here, or click to select files</p>\n * </div>\n * )\n * }\n * ```\n */\nexport function useDropzone(props: DropzoneOptions = {}): DropzoneState {\n const {\n accept,\n disabled = false,\n getFilesFromEvent = fromEvent,\n maxSize = Number.POSITIVE_INFINITY,\n minSize = 0,\n multiple = true,\n maxFiles = 0,\n onDragEnter,\n onDragLeave,\n onDragOver,\n onDrop,\n onDropAccepted,\n onDropRejected,\n onFileDialogCancel,\n onFileDialogOpen,\n useFsAccessApi = false,\n autoFocus = false,\n preventDropOnDocument = true,\n noClick = false,\n noKeyboard = false,\n noDrag = false,\n noDragEventsBubbling = false,\n onError,\n validator,\n getErrorMessage\n } = props;\n\n // `acceptAttr` keeps wildcard MIME types (e.g. `image/*`) so the drag-time\n // `isDragAccept`/`isDragReject` check can react to a file's MIME type - file names\n // (hence extensions) aren't readable during a drag.\n const acceptAttr = useMemo(() => acceptPropAsAcceptAttr(accept), [accept]);\n // `inputAcceptAttr` drops a wildcard MIME type when it is paired with extensions, so the\n // native picker and drop-time validation enforce the extensions instead of accepting any\n // file of that type. See https://github.com/react-dropzone/react-dropzone/issues/1220\n const inputAcceptAttr = useMemo(\n () =>\n acceptPropAsAcceptAttr(accept, {\n omitWildcardMimeTypesWithExtensions: true\n }),\n [accept]\n );\n const pickerTypes = useMemo(() => pickerOptionsFromAccept(accept), [accept]);\n\n const onFileDialogOpenCb = useMemo<(...args: any[]) => void>(\n () => (typeof onFileDialogOpen === \"function\" ? onFileDialogOpen : noop),\n [onFileDialogOpen]\n );\n const onFileDialogCancelCb = useMemo<(...args: any[]) => void>(\n () => (typeof onFileDialogCancel === \"function\" ? onFileDialogCancel : noop),\n [onFileDialogCancel]\n );\n\n const rootRef = useRef<HTMLElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [state, dispatch] = useReducer(reducer, initialState);\n const {isFocused, isFileDialogActive} = state;\n\n const fsAccessApiWorksRef = useRef(\n typeof window !== \"undefined\" && window.isSecureContext && useFsAccessApi && canUseFileSystemAccessAPI()\n );\n\n // Update file dialog active state when the window is focused on\n const onWindowFocus = () => {\n // Execute the timeout only if the file dialog is opened in the browser\n if (!fsAccessApiWorksRef.current && isFileDialogActive) {\n setTimeout(() => {\n if (inputRef.current) {\n const {files} = inputRef.current;\n\n if (!files?.length) {\n dispatch({type: \"closeDialog\"});\n onFileDialogCancelCb();\n }\n }\n }, 300);\n }\n };\n useEffect(() => {\n window.addEventListener(\"focus\", onWindowFocus, false);\n return () => {\n window.removeEventListener(\"focus\", onWindowFocus, false);\n };\n }, [inputRef, isFileDialogActive, onFileDialogCancelCb, fsAccessApiWorksRef]);\n\n const dragTargetsRef = useRef<EventTarget[]>([]);\n const globalDragTargetsRef = useRef<EventTarget[]>([]);\n const onDocumentDrop = (event: DragEvent) => {\n if (rootRef.current && event.target && rootRef.current.contains(event.target as Node)) {\n // If we intercepted an event for our instance, let it propagate down to the instance's onDrop handler\n return;\n }\n event.preventDefault();\n dragTargetsRef.current = [];\n };\n\n useEffect(() => {\n if (preventDropOnDocument) {\n document.addEventListener(\"dragover\", onDocumentDragOver, false);\n document.addEventListener(\"drop\", onDocumentDrop, false);\n }\n\n return () => {\n if (preventDropOnDocument) {\n document.removeEventListener(\"dragover\", onDocumentDragOver);\n document.removeEventListener(\"drop\", onDocumentDrop);\n }\n };\n }, [rootRef, preventDropOnDocument]);\n\n // Track global drag state for document-level drag events\n useEffect(() => {\n const onDocumentDragEnter = (event: DragEvent) => {\n if (event.target) {\n globalDragTargetsRef.current = [...globalDragTargetsRef.current, event.target];\n }\n\n if (isEvtWithFiles(event)) {\n dispatch({isDragGlobal: true, type: \"setDragGlobal\"});\n }\n };\n\n const onDocumentDragLeave = (event: DragEvent) => {\n // Only deactivate once we've left all children\n globalDragTargetsRef.current = globalDragTargetsRef.current.filter(el => el !== event.target && el !== null);\n\n if (globalDragTargetsRef.current.length > 0) {\n return;\n }\n\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDragEnd = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDropGlobal = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n document.addEventListener(\"dragenter\", onDocumentDragEnter, false);\n document.addEventListener(\"dragleave\", onDocumentDragLeave, false);\n document.addEventListener(\"dragend\", onDocumentDragEnd, false);\n document.addEventListener(\"drop\", onDocumentDropGlobal, false);\n\n return () => {\n document.removeEventListener(\"dragenter\", onDocumentDragEnter);\n document.removeEventListener(\"dragleave\", onDocumentDragLeave);\n document.removeEventListener(\"dragend\", onDocumentDragEnd);\n document.removeEventListener(\"drop\", onDocumentDropGlobal);\n };\n }, [rootRef]);\n\n // Auto focus the root when autoFocus is true\n useEffect(() => {\n if (!disabled && autoFocus && rootRef.current) {\n rootRef.current.focus();\n }\n return () => {};\n }, [rootRef, autoFocus, disabled]);\n\n const onErrCb = useCallback(\n (e: Error) => {\n if (onError) {\n onError(e);\n } else {\n // Let the user know something's gone wrong if they haven't provided the onError cb.\n console.error(e);\n }\n },\n [onError]\n );\n\n const onDragEnterCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n dragTargetsRef.current = [...dragTargetsRef.current, event.target];\n\n if (isEvtWithFiles(event)) {\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n return;\n }\n\n const fileCount = files.length;\n const isDragAccept =\n fileCount > 0 &&\n allFilesAccepted({\n files: files as File[],\n accept: acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n });\n const isDragReject = fileCount > 0 && !isDragAccept;\n\n dispatch({\n isDragAccept,\n isDragReject,\n isDragActive: true,\n type: \"setDraggedFiles\"\n });\n\n if (onDragEnter) {\n onDragEnter(event);\n }\n })\n .catch(e => onErrCb(e));\n }\n },\n [\n getFilesFromEvent,\n onDragEnter,\n onErrCb,\n noDragEventsBubbling,\n acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n ]\n );\n\n const onDragOverCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n const hasFiles = isEvtWithFiles(event);\n if (hasFiles && event.dataTransfer) {\n try {\n event.dataTransfer.dropEffect = \"copy\";\n } catch {\n /* no-op */\n }\n }\n\n if (hasFiles && onDragOver) {\n onDragOver(event);\n }\n\n return false;\n },\n [onDragOver, noDragEventsBubbling]\n );\n\n const onDragLeaveCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n // Only deactivate once the dropzone and all children have been left\n const targets = dragTargetsRef.current.filter(target => rootRef.current?.contains(target as Node));\n // Make sure to remove a target present multiple times only once\n // (Firefox may fire dragenter/dragleave multiple times on the same element)\n const targetIdx = targets.indexOf(event.target);\n if (targetIdx !== -1) {\n targets.splice(targetIdx, 1);\n }\n dragTargetsRef.current = targets;\n if (targets.length > 0) {\n return;\n }\n\n dispatch({\n type: \"setDraggedFiles\",\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false\n });\n\n if (isEvtWithFiles(event) && onDragLeave) {\n onDragLeave(event);\n }\n },\n [rootRef, onDragLeave, noDragEventsBubbling]\n );\n\n const setFiles = useCallback(\n (files: FileWithPath[], event: any) => {\n const acceptedFiles: FileWithPath[] = [];\n const fileRejections: FileRejection[] = [];\n\n const localizeError = (error: FileError, file: File): FileError =>\n getErrorMessage ? {...error, message: getErrorMessage(error, file)} : error;\n\n files.forEach(file => {\n const [accepted, acceptError] = fileAccepted(file, inputAcceptAttr);\n const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);\n const customErrors = validator ? validator(file) : null;\n\n if (accepted && sizeMatch && !customErrors) {\n acceptedFiles.push(file);\n } else {\n let errors: Array<FileError | null> = [acceptError, sizeError];\n\n if (customErrors) {\n errors = errors.concat(customErrors);\n }\n\n fileRejections.push({\n file,\n errors: errors.filter((e): e is FileError => e != null).map(error => localizeError(error, file))\n });\n }\n });\n\n if ((!multiple && acceptedFiles.length > 1) || (multiple && maxFiles >= 1 && acceptedFiles.length > maxFiles)) {\n // Reject everything and empty accepted files\n acceptedFiles.forEach(file => {\n fileRejections.push({file, errors: [localizeError(TOO_MANY_FILES_REJECTION, file)]});\n });\n acceptedFiles.splice(0);\n }\n\n dispatch({\n acceptedFiles,\n fileRejections,\n type: \"setFiles\"\n });\n\n if (onDrop) {\n onDrop(acceptedFiles, fileRejections, event);\n }\n\n if (fileRejections.length > 0 && onDropRejected) {\n onDropRejected(fileRejections, event);\n }\n\n if (acceptedFiles.length > 0 && onDropAccepted) {\n onDropAccepted(acceptedFiles, event);\n }\n },\n [\n dispatch,\n multiple,\n inputAcceptAttr,\n minSize,\n maxSize,\n maxFiles,\n onDrop,\n onDropAccepted,\n onDropRejected,\n validator,\n getErrorMessage\n ]\n );\n\n const onDropCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n dragTargetsRef.current = [];\n\n if (isEvtWithFiles(event)) {\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n return;\n }\n setFiles(files as FileWithPath[], event);\n })\n .catch(e => onErrCb(e));\n }\n dispatch({type: \"reset\"});\n },\n [getFilesFromEvent, setFiles, onErrCb, noDragEventsBubbling]\n );\n\n // Fn for opening the file dialog programmatically\n const openFileDialog = useCallback(() => {\n // No point to use FS access APIs if context is not secure\n // https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#feature_detection\n if (fsAccessApiWorksRef.current) {\n dispatch({type: \"openDialog\"});\n onFileDialogOpenCb();\n // https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker\n const opts = {\n multiple,\n types: pickerTypes\n };\n (window as any)\n .showOpenFilePicker(opts)\n .then((handles: any) => getFilesFromEvent(handles))\n .then((files: Array<File | DataTransferItem>) => {\n setFiles(files as FileWithPath[], null);\n dispatch({type: \"closeDialog\"});\n })\n .catch((e: any) => {\n // AbortError means the user canceled\n if (isAbort(e)) {\n onFileDialogCancelCb(e);\n dispatch({type: \"closeDialog\"});\n } else if (isSecurityError(e) || isNotAllowedError(e)) {\n // The FS access API is unusable here: either the context forbids it (SecurityError,\n // e.g. CORS) or the browser/platform blocked the picker (NotAllowedError, e.g. Edge\n // for Business - see https://github.com/react-dropzone/react-dropzone/issues/1429).\n // Stop using it and fall back to the native <input>.\n fsAccessApiWorksRef.current = false;\n if (inputRef.current) {\n inputRef.current.value = \"\";\n inputRef.current.click();\n } else {\n onErrCb(\n new Error(\n \"Cannot open the file picker because the https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API is not supported and no <input> was provided.\"\n )\n );\n }\n } else {\n onErrCb(e);\n }\n });\n return;\n }\n\n if (inputRef.current) {\n dispatch({type: \"openDialog\"});\n onFileDialogOpenCb();\n inputRef.current.value = \"\";\n inputRef.current.click();\n }\n }, [dispatch, onFileDialogOpenCb, onFileDialogCancelCb, useFsAccessApi, setFiles, onErrCb, pickerTypes, multiple]);\n\n // Cb to open the file dialog when SPACE/ENTER occurs on the dropzone\n const onKeyDownCb = useCallback(\n (event: any) => {\n // Ignore keyboard events bubbling up the DOM tree\n if (!rootRef.current?.isEqualNode(event.target)) {\n return;\n }\n\n if (event.key === \" \" || event.key === \"Enter\" || event.keyCode === 32 || event.keyCode === 13) {\n event.preventDefault();\n openFileDialog();\n }\n },\n [rootRef, openFileDialog]\n );\n\n // Update focus state for the dropzone\n const onFocusCb = useCallback(() => {\n dispatch({type: \"focus\"});\n }, []);\n const onBlurCb = useCallback(() => {\n dispatch({type: \"blur\"});\n }, []);\n\n // Cb to open the file dialog when click occurs on the dropzone\n const onClickCb = useCallback(() => {\n if (noClick) {\n return;\n }\n\n // In IE11/Edge the file-browser dialog is blocking, therefore, use setTimeout()\n // to ensure React can handle state changes\n // See: https://github.com/react-dropzone/react-dropzone/issues/450\n if (isIeOrEdge()) {\n setTimeout(openFileDialog, 0);\n } else {\n openFileDialog();\n }\n }, [noClick, openFileDialog]);\n\n const composeHandler = (fn: any) => {\n return disabled ? null : fn;\n };\n\n const composeKeyboardHandler = (fn: any) => {\n return noKeyboard ? null : composeHandler(fn);\n };\n\n const composeDragHandler = (fn: any) => {\n return noDrag ? null : composeHandler(fn);\n };\n\n const stopPropagation = (event: any) => {\n if (noDragEventsBubbling) {\n event.stopPropagation();\n }\n };\n\n const getRootProps = useMemo(\n () =>\n ({\n refKey = \"ref\",\n role,\n onKeyDown,\n onFocus,\n onBlur,\n onClick,\n onDragEnter,\n onDragOver,\n onDragLeave,\n onDrop,\n ...rest\n }: DropzoneRootProps = {}) => ({\n onKeyDown: composeKeyboardHandler(composeEventHandlers(onKeyDown, onKeyDownCb)),\n onFocus: composeKeyboardHandler(composeEventHandlers(onFocus, onFocusCb)),\n onBlur: composeKeyboardHandler(composeEventHandlers(onBlur, onBlurCb)),\n onClick: composeHandler(composeEventHandlers(onClick, onClickCb)),\n onDragEnter: composeDragHandler(composeEventHandlers(onDragEnter, onDragEnterCb)),\n onDragOver: composeDragHandler(composeEventHandlers(onDragOver, onDragOverCb)),\n onDragLeave: composeDragHandler(composeEventHandlers(onDragLeave, onDragLeaveCb)),\n onDrop: composeDragHandler(composeEventHandlers(onDrop, onDropCb)),\n role: typeof role === \"string\" && role !== \"\" ? role : \"presentation\",\n [refKey]: rootRef,\n ...(!disabled && !noKeyboard ? {tabIndex: 0} : {}),\n ...(disabled ? {\"aria-disabled\": true} : {}),\n ...rest\n }),\n [\n rootRef,\n onKeyDownCb,\n onFocusCb,\n onBlurCb,\n onClickCb,\n onDragEnterCb,\n onDragOverCb,\n onDragLeaveCb,\n onDropCb,\n noKeyboard,\n noDrag,\n disabled\n ]\n );\n\n const onInputElementClick = useCallback((event: any) => {\n event.stopPropagation();\n }, []);\n\n const getInputProps = useMemo(\n () =>\n ({refKey = \"ref\", onChange, onClick, ...rest}: DropzoneInputProps = {}) => {\n const inputProps = {\n accept: inputAcceptAttr,\n multiple,\n type: \"file\",\n \"aria-label\": \"file upload\",\n style: {\n border: 0,\n clip: \"rect(0, 0, 0, 0)\",\n clipPath: \"inset(50%)\",\n height: \"1px\",\n margin: \"0 -1px -1px 0\",\n overflow: \"hidden\",\n padding: 0,\n position: \"absolute\",\n width: \"1px\",\n whiteSpace: \"nowrap\"\n },\n onChange: composeHandler(composeEventHandlers(onChange, onDropCb)),\n onClick: composeHandler(composeEventHandlers(onClick, onInputElementClick)),\n tabIndex: -1,\n [refKey]: inputRef\n };\n\n return {\n ...inputProps,\n ...rest\n };\n },\n [inputRef, accept, multiple, onDropCb, disabled]\n );\n\n return {\n ...state,\n isFocused: isFocused && !disabled,\n getRootProps,\n getInputProps,\n rootRef,\n inputRef,\n open: composeHandler(openFileDialog)\n } as unknown as DropzoneState;\n}\n\nfunction reducer(state: DropzoneInternalState, action: any): DropzoneInternalState {\n switch (action.type) {\n case \"focus\":\n return {\n ...state,\n isFocused: true\n };\n case \"blur\":\n return {\n ...state,\n isFocused: false\n };\n case \"openDialog\":\n return {\n ...initialState,\n isFileDialogActive: true\n };\n case \"closeDialog\":\n return {\n ...state,\n isFileDialogActive: false\n };\n case \"setDraggedFiles\":\n return {\n ...state,\n isDragActive: action.isDragActive,\n isDragAccept: action.isDragAccept,\n isDragReject: action.isDragReject\n };\n case \"setFiles\":\n return {\n ...state,\n acceptedFiles: action.acceptedFiles,\n fileRejections: action.fileRejections,\n isDragReject: false\n };\n case \"setDragGlobal\":\n return {\n ...state,\n isDragGlobal: action.isDragGlobal\n };\n case \"reset\":\n return {\n ...initialState\n };\n default:\n return state;\n }\n}\n\nfunction noop() {}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-dropzone",
3
- "version": "18.1.0",
3
+ "version": "18.2.1",
4
4
  "description": "Simple HTML5 drag-drop zone with React.js",
5
5
  "keywords": [
6
6
  "drag",
package/src/index.tsx CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  isAbort,
14
14
  isEvtWithFiles,
15
15
  isIeOrEdge,
16
+ isNotAllowedError,
16
17
  isPropagationStopped,
17
18
  isSecurityError,
18
19
  onDocumentDragOver,
@@ -54,6 +55,12 @@ export type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> &
54
55
  onFileDialogOpen?: () => void;
55
56
  onError?: (err: Error) => void;
56
57
  validator?: <T extends File>(file: T) => FileError | readonly FileError[] | null;
58
+ /**
59
+ * Override the message of any rejection error (built-in or custom). Called once per error;
60
+ * receives the error and the file it belongs to and returns the message to use. Return
61
+ * `error.message` for codes you don't want to change. Useful for localizing error messages.
62
+ */
63
+ getErrorMessage?: (error: FileError, file: File) => string;
57
64
  useFsAccessApi?: boolean;
58
65
  autoFocus?: boolean;
59
66
  };
@@ -183,7 +190,8 @@ export function useDropzone(props: DropzoneOptions = {}): DropzoneState {
183
190
  noDrag = false,
184
191
  noDragEventsBubbling = false,
185
192
  onError,
186
- validator
193
+ validator,
194
+ getErrorMessage
187
195
  } = props;
188
196
 
189
197
  // `acceptAttr` keeps wildcard MIME types (e.g. `image/*`) so the drag-time
@@ -455,6 +463,9 @@ export function useDropzone(props: DropzoneOptions = {}): DropzoneState {
455
463
  const acceptedFiles: FileWithPath[] = [];
456
464
  const fileRejections: FileRejection[] = [];
457
465
 
466
+ const localizeError = (error: FileError, file: File): FileError =>
467
+ getErrorMessage ? {...error, message: getErrorMessage(error, file)} : error;
468
+
458
469
  files.forEach(file => {
459
470
  const [accepted, acceptError] = fileAccepted(file, inputAcceptAttr);
460
471
  const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);
@@ -471,7 +482,7 @@ export function useDropzone(props: DropzoneOptions = {}): DropzoneState {
471
482
 
472
483
  fileRejections.push({
473
484
  file,
474
- errors: errors.filter((e): e is FileError => e != null)
485
+ errors: errors.filter((e): e is FileError => e != null).map(error => localizeError(error, file))
475
486
  });
476
487
  }
477
488
  });
@@ -479,7 +490,7 @@ export function useDropzone(props: DropzoneOptions = {}): DropzoneState {
479
490
  if ((!multiple && acceptedFiles.length > 1) || (multiple && maxFiles >= 1 && acceptedFiles.length > maxFiles)) {
480
491
  // Reject everything and empty accepted files
481
492
  acceptedFiles.forEach(file => {
482
- fileRejections.push({file, errors: [TOO_MANY_FILES_REJECTION]});
493
+ fileRejections.push({file, errors: [localizeError(TOO_MANY_FILES_REJECTION, file)]});
483
494
  });
484
495
  acceptedFiles.splice(0);
485
496
  }
@@ -502,7 +513,19 @@ export function useDropzone(props: DropzoneOptions = {}): DropzoneState {
502
513
  onDropAccepted(acceptedFiles, event);
503
514
  }
504
515
  },
505
- [dispatch, multiple, inputAcceptAttr, minSize, maxSize, maxFiles, onDrop, onDropAccepted, onDropRejected, validator]
516
+ [
517
+ dispatch,
518
+ multiple,
519
+ inputAcceptAttr,
520
+ minSize,
521
+ maxSize,
522
+ maxFiles,
523
+ onDrop,
524
+ onDropAccepted,
525
+ onDropRejected,
526
+ validator,
527
+ getErrorMessage
528
+ ]
506
529
  );
507
530
 
508
531
  const onDropCb = useCallback(
@@ -553,10 +576,12 @@ export function useDropzone(props: DropzoneOptions = {}): DropzoneState {
553
576
  if (isAbort(e)) {
554
577
  onFileDialogCancelCb(e);
555
578
  dispatch({type: "closeDialog"});
556
- } else if (isSecurityError(e)) {
579
+ } else if (isSecurityError(e) || isNotAllowedError(e)) {
580
+ // The FS access API is unusable here: either the context forbids it (SecurityError,
581
+ // e.g. CORS) or the browser/platform blocked the picker (NotAllowedError, e.g. Edge
582
+ // for Business - see https://github.com/react-dropzone/react-dropzone/issues/1429).
583
+ // Stop using it and fall back to the native <input>.
557
584
  fsAccessApiWorksRef.current = false;
558
- // CORS, so cannot use this API
559
- // Try using the input
560
585
  if (inputRef.current) {
561
586
  inputRef.current.value = "";
562
587
  inputRef.current.click();
@@ -321,6 +321,18 @@ export function isSecurityError(v: any): boolean {
321
321
  return v instanceof DOMException && (v.name === "SecurityError" || v.code === v.SECURITY_ERR);
322
322
  }
323
323
 
324
+ /**
325
+ * Check if v is a "not allowed" error.
326
+ *
327
+ * Some browsers/configurations block `window.showOpenFilePicker()` outright and reject with a
328
+ * `NotAllowedError` instead of showing the picker (e.g. Microsoft Edge for Business, or other
329
+ * restrictive enterprise/security policies). We treat this like a security error and fall back
330
+ * to the native `<input>`. See https://github.com/react-dropzone/react-dropzone/issues/1429
331
+ */
332
+ export function isNotAllowedError(v: any): boolean {
333
+ return v instanceof DOMException && v.name === "NotAllowedError";
334
+ }
335
+
324
336
  /**
325
337
  * Check if v is a MIME type string.
326
338
  */