react-dropzone 18.2.1 → 18.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -123,14 +123,31 @@ function fileMatchSize(file, minSize, maxSize) {
123
123
  function isDefined(value) {
124
124
  return value !== void 0 && value !== null;
125
125
  }
126
- function allFilesAccepted({ files, accept, minSize, maxSize, multiple, maxFiles = 0, validator }) {
127
- if (!multiple && files.length > 1 || multiple && maxFiles >= 1 && files.length > maxFiles) return false;
128
- return files.every((file) => {
126
+ /**
127
+ * Classify a set of dragged files for the `isDragAccept`/`isDragReject`/`isDragUnknown` states.
128
+ *
129
+ * During `dragenter`/`dragover` the browser only exposes `DataTransferItem`s, which carry a MIME
130
+ * `type` but no file name, extension or size (see https://html.spec.whatwg.org/multipage/dnd.html#dndevents).
131
+ * So the drag-time check is deliberately optimistic about anything it can't see:
132
+ *
133
+ * - The custom `validator` is **never** run here. It is typed `(file: File) => ...` and users
134
+ * routinely read `file.name`/`file.size`, which are `undefined` on a `DataTransferItem` - running
135
+ * it would throw and abort the whole drag handler (leaving `isDragActive` stuck at `false`).
136
+ * See https://github.com/react-dropzone/react-dropzone/issues/1408
137
+ * - When a `validator` is configured we therefore can't promise the files are acceptable, so the
138
+ * verdict is `unknown` rather than a misleading `reject` (or a premature `accept`).
139
+ * See https://github.com/react-dropzone/react-dropzone/issues/1244
140
+ *
141
+ * The full check (including the `validator`) still runs on drop in {@link fileAccepted}/`setFiles`.
142
+ */
143
+ function getDragVerdict({ files, accept, minSize, maxSize, multiple, maxFiles = 0, validator }) {
144
+ if (!multiple && files.length > 1 || multiple && maxFiles >= 1 && files.length > maxFiles) return "reject";
145
+ if (files.some((file) => {
129
146
  const [accepted] = fileAccepted(file, accept);
130
147
  const [sizeMatch] = fileMatchSize(file, minSize, maxSize);
131
- const customErrors = validator ? validator(file) : null;
132
- return accepted && sizeMatch && !customErrors;
133
- });
148
+ return !accepted || !sizeMatch;
149
+ })) return "reject";
150
+ return validator ? "unknown" : "accept";
134
151
  }
135
152
  function isPropagationStopped(event) {
136
153
  if (typeof event.isPropagationStopped === "function") return event.isPropagationStopped();
@@ -286,6 +303,7 @@ const initialState = {
286
303
  isDragActive: false,
287
304
  isDragAccept: false,
288
305
  isDragReject: false,
306
+ isDragUnknown: false,
289
307
  isDragGlobal: false,
290
308
  acceptedFiles: [],
291
309
  fileRejections: []
@@ -346,7 +364,7 @@ function useDropzone(props = {}) {
346
364
  const dragTargetsRef = (0, react.useRef)([]);
347
365
  const globalDragTargetsRef = (0, react.useRef)([]);
348
366
  const onDocumentDrop = (event) => {
349
- if (rootRef.current && event.target && rootRef.current.contains(event.target)) return;
367
+ if (rootRef.current && event.target && rootRef.current.contains(event.target) && event.defaultPrevented) return;
350
368
  event.preventDefault();
351
369
  dragTargetsRef.current = [];
352
370
  };
@@ -422,8 +440,7 @@ function useDropzone(props = {}) {
422
440
  dragTargetsRef.current = [...dragTargetsRef.current, event.target];
423
441
  if (isEvtWithFiles(event)) Promise.resolve(getFilesFromEvent(event)).then((files) => {
424
442
  if (isPropagationStopped(event) && !noDragEventsBubbling) return;
425
- const fileCount = files.length;
426
- const isDragAccept = fileCount > 0 && allFilesAccepted({
443
+ const verdict = files.length > 0 ? getDragVerdict({
427
444
  files,
428
445
  accept: acceptAttr,
429
446
  minSize,
@@ -431,10 +448,11 @@ function useDropzone(props = {}) {
431
448
  multiple,
432
449
  maxFiles,
433
450
  validator
434
- });
451
+ }) : null;
435
452
  dispatch({
436
- isDragAccept,
437
- isDragReject: fileCount > 0 && !isDragAccept,
453
+ isDragAccept: verdict === "accept",
454
+ isDragReject: verdict === "reject",
455
+ isDragUnknown: verdict === "unknown",
438
456
  isDragActive: true,
439
457
  type: "setDraggedFiles"
440
458
  });
@@ -476,7 +494,8 @@ function useDropzone(props = {}) {
476
494
  type: "setDraggedFiles",
477
495
  isDragActive: false,
478
496
  isDragAccept: false,
479
- isDragReject: false
497
+ isDragReject: false,
498
+ isDragUnknown: false
480
499
  });
481
500
  if (isEvtWithFiles(event) && onDragLeave) onDragLeave(event);
482
501
  }, [
@@ -716,13 +735,15 @@ function reducer(state, action) {
716
735
  ...state,
717
736
  isDragActive: action.isDragActive,
718
737
  isDragAccept: action.isDragAccept,
719
- isDragReject: action.isDragReject
738
+ isDragReject: action.isDragReject,
739
+ isDragUnknown: action.isDragUnknown
720
740
  };
721
741
  case "setFiles": return {
722
742
  ...state,
723
743
  acceptedFiles: action.acceptedFiles,
724
744
  fileRejections: action.fileRejections,
725
- isDragReject: false
745
+ isDragReject: false,
746
+ isDragUnknown: false
726
747
  };
727
748
  case "setDragGlobal": return {
728
749
  ...state,
@@ -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 \"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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"}
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/**\n * The outcome of the drag-time acceptance check.\n *\n * - `accept` - every file passes the checks we can evaluate during a drag.\n * - `reject` - at least one file confidently fails a check we can fully evaluate during a\n * drag (the file count, or a non-empty MIME type that doesn't match `accept`).\n * - `unknown` - nothing confidently fails, but the outcome can't be confirmed until drop,\n * because a custom `validator` is configured and can't be evaluated yet.\n */\nexport type DragVerdict = \"accept\" | \"reject\" | \"unknown\";\n\n/**\n * Classify a set of dragged files for the `isDragAccept`/`isDragReject`/`isDragUnknown` states.\n *\n * During `dragenter`/`dragover` the browser only exposes `DataTransferItem`s, which carry a MIME\n * `type` but no file name, extension or size (see https://html.spec.whatwg.org/multipage/dnd.html#dndevents).\n * So the drag-time check is deliberately optimistic about anything it can't see:\n *\n * - The custom `validator` is **never** run here. It is typed `(file: File) => ...` and users\n * routinely read `file.name`/`file.size`, which are `undefined` on a `DataTransferItem` - running\n * it would throw and abort the whole drag handler (leaving `isDragActive` stuck at `false`).\n * See https://github.com/react-dropzone/react-dropzone/issues/1408\n * - When a `validator` is configured we therefore can't promise the files are acceptable, so the\n * verdict is `unknown` rather than a misleading `reject` (or a premature `accept`).\n * See https://github.com/react-dropzone/react-dropzone/issues/1244\n *\n * The full check (including the `validator`) still runs on drop in {@link fileAccepted}/`setFiles`.\n */\nexport function getDragVerdict({\n files,\n accept,\n minSize,\n maxSize,\n multiple,\n maxFiles = 0,\n validator\n}: {\n files: Array<File | DataTransferItem>;\n accept?: string;\n minSize?: number;\n maxSize?: number;\n multiple?: boolean;\n maxFiles?: number;\n validator?: (file: File) => FileError | readonly FileError[] | null;\n}): DragVerdict {\n // The file count is knowable during a drag, so an over-the-limit selection is a confident reject.\n if ((!multiple && files.length > 1) || (multiple && maxFiles >= 1 && files.length > maxFiles)) {\n return \"reject\";\n }\n\n const confidentlyRejected = files.some(file => {\n const [accepted] = fileAccepted(file as File, accept);\n const [sizeMatch] = fileMatchSize(file as File, minSize, maxSize);\n return !accepted || !sizeMatch;\n });\n if (confidentlyRejected) {\n return \"reject\";\n }\n\n // Built-in checks pass. A custom validator can only ever add rejections on drop, never rescue\n // one - so with a validator present the drag outcome is unknown until we have real Files.\n return validator ? \"unknown\" : \"accept\";\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 canUseFileSystemAccessAPI,\n composeEventHandlers,\n ErrorCode,\n fileAccepted,\n fileMatchSize,\n getDragVerdict,\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 isDragUnknown: 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 isDragUnknown: 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 isDragUnknown: 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 // This is a document-level, bubble-phase listener, so it runs *after* the event has already\n // bubbled through the dropzone root. If the drop landed inside the root and the instance's own\n // onDrop handler already prevented the default, there's nothing left to do.\n //\n // We must NOT bail out on `contains()` alone: when the dropzone is `disabled` or has `noDrag`,\n // the root has no onDrop handler, so nothing prevents the browser's default action and the file\n // is opened in the tab. Falling through to `preventDefault()` here keeps that from happening.\n // See https://github.com/react-dropzone/react-dropzone/issues/1362\n if (rootRef.current && event.target && rootRef.current.contains(event.target as Node) && event.defaultPrevented) {\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 // During a drag we only have DataTransferItems (MIME type, no name/size), so the\n // custom validator can't run yet - a validator-configured dropzone is \"unknown\" until\n // drop rather than a misleading accept/reject. See getDragVerdict for the details.\n const verdict =\n fileCount > 0\n ? getDragVerdict({\n files: files as Array<File | DataTransferItem>,\n accept: acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n })\n : null;\n\n dispatch({\n isDragAccept: verdict === \"accept\",\n isDragReject: verdict === \"reject\",\n isDragUnknown: verdict === \"unknown\",\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 isDragUnknown: 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 isDragUnknown: action.isDragUnknown\n };\n case \"setFiles\":\n return {\n ...state,\n acceptedFiles: action.acceptedFiles,\n fileRejections: action.fileRejections,\n isDragReject: false,\n isDragUnknown: 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
@@ -67,6 +67,7 @@ type DropzoneState = DropzoneRef & {
67
67
  isDragActive: boolean;
68
68
  isDragAccept: boolean;
69
69
  isDragReject: boolean;
70
+ isDragUnknown: boolean;
70
71
  isDragGlobal: boolean;
71
72
  isFileDialogActive: boolean;
72
73
  acceptedFiles: readonly FileWithPath[];
package/dist/index.d.ts CHANGED
@@ -67,6 +67,7 @@ type DropzoneState = DropzoneRef & {
67
67
  isDragActive: boolean;
68
68
  isDragAccept: boolean;
69
69
  isDragReject: boolean;
70
+ isDragUnknown: boolean;
70
71
  isDragGlobal: boolean;
71
72
  isFileDialogActive: boolean;
72
73
  acceptedFiles: readonly FileWithPath[];
package/dist/index.js CHANGED
@@ -96,14 +96,31 @@ function fileMatchSize(file, minSize, maxSize) {
96
96
  function isDefined(value) {
97
97
  return value !== void 0 && value !== null;
98
98
  }
99
- function allFilesAccepted({ files, accept, minSize, maxSize, multiple, maxFiles = 0, validator }) {
100
- if (!multiple && files.length > 1 || multiple && maxFiles >= 1 && files.length > maxFiles) return false;
101
- return files.every((file) => {
99
+ /**
100
+ * Classify a set of dragged files for the `isDragAccept`/`isDragReject`/`isDragUnknown` states.
101
+ *
102
+ * During `dragenter`/`dragover` the browser only exposes `DataTransferItem`s, which carry a MIME
103
+ * `type` but no file name, extension or size (see https://html.spec.whatwg.org/multipage/dnd.html#dndevents).
104
+ * So the drag-time check is deliberately optimistic about anything it can't see:
105
+ *
106
+ * - The custom `validator` is **never** run here. It is typed `(file: File) => ...` and users
107
+ * routinely read `file.name`/`file.size`, which are `undefined` on a `DataTransferItem` - running
108
+ * it would throw and abort the whole drag handler (leaving `isDragActive` stuck at `false`).
109
+ * See https://github.com/react-dropzone/react-dropzone/issues/1408
110
+ * - When a `validator` is configured we therefore can't promise the files are acceptable, so the
111
+ * verdict is `unknown` rather than a misleading `reject` (or a premature `accept`).
112
+ * See https://github.com/react-dropzone/react-dropzone/issues/1244
113
+ *
114
+ * The full check (including the `validator`) still runs on drop in {@link fileAccepted}/`setFiles`.
115
+ */
116
+ function getDragVerdict({ files, accept, minSize, maxSize, multiple, maxFiles = 0, validator }) {
117
+ if (!multiple && files.length > 1 || multiple && maxFiles >= 1 && files.length > maxFiles) return "reject";
118
+ if (files.some((file) => {
102
119
  const [accepted] = fileAccepted(file, accept);
103
120
  const [sizeMatch] = fileMatchSize(file, minSize, maxSize);
104
- const customErrors = validator ? validator(file) : null;
105
- return accepted && sizeMatch && !customErrors;
106
- });
121
+ return !accepted || !sizeMatch;
122
+ })) return "reject";
123
+ return validator ? "unknown" : "accept";
107
124
  }
108
125
  function isPropagationStopped(event) {
109
126
  if (typeof event.isPropagationStopped === "function") return event.isPropagationStopped();
@@ -259,6 +276,7 @@ const initialState = {
259
276
  isDragActive: false,
260
277
  isDragAccept: false,
261
278
  isDragReject: false,
279
+ isDragUnknown: false,
262
280
  isDragGlobal: false,
263
281
  acceptedFiles: [],
264
282
  fileRejections: []
@@ -319,7 +337,7 @@ function useDropzone(props = {}) {
319
337
  const dragTargetsRef = useRef([]);
320
338
  const globalDragTargetsRef = useRef([]);
321
339
  const onDocumentDrop = (event) => {
322
- if (rootRef.current && event.target && rootRef.current.contains(event.target)) return;
340
+ if (rootRef.current && event.target && rootRef.current.contains(event.target) && event.defaultPrevented) return;
323
341
  event.preventDefault();
324
342
  dragTargetsRef.current = [];
325
343
  };
@@ -395,8 +413,7 @@ function useDropzone(props = {}) {
395
413
  dragTargetsRef.current = [...dragTargetsRef.current, event.target];
396
414
  if (isEvtWithFiles(event)) Promise.resolve(getFilesFromEvent(event)).then((files) => {
397
415
  if (isPropagationStopped(event) && !noDragEventsBubbling) return;
398
- const fileCount = files.length;
399
- const isDragAccept = fileCount > 0 && allFilesAccepted({
416
+ const verdict = files.length > 0 ? getDragVerdict({
400
417
  files,
401
418
  accept: acceptAttr,
402
419
  minSize,
@@ -404,10 +421,11 @@ function useDropzone(props = {}) {
404
421
  multiple,
405
422
  maxFiles,
406
423
  validator
407
- });
424
+ }) : null;
408
425
  dispatch({
409
- isDragAccept,
410
- isDragReject: fileCount > 0 && !isDragAccept,
426
+ isDragAccept: verdict === "accept",
427
+ isDragReject: verdict === "reject",
428
+ isDragUnknown: verdict === "unknown",
411
429
  isDragActive: true,
412
430
  type: "setDraggedFiles"
413
431
  });
@@ -449,7 +467,8 @@ function useDropzone(props = {}) {
449
467
  type: "setDraggedFiles",
450
468
  isDragActive: false,
451
469
  isDragAccept: false,
452
- isDragReject: false
470
+ isDragReject: false,
471
+ isDragUnknown: false
453
472
  });
454
473
  if (isEvtWithFiles(event) && onDragLeave) onDragLeave(event);
455
474
  }, [
@@ -689,13 +708,15 @@ function reducer(state, action) {
689
708
  ...state,
690
709
  isDragActive: action.isDragActive,
691
710
  isDragAccept: action.isDragAccept,
692
- isDragReject: action.isDragReject
711
+ isDragReject: action.isDragReject,
712
+ isDragUnknown: action.isDragUnknown
693
713
  };
694
714
  case "setFiles": return {
695
715
  ...state,
696
716
  acceptedFiles: action.acceptedFiles,
697
717
  fileRejections: action.fileRejections,
698
- isDragReject: false
718
+ isDragReject: false,
719
+ isDragUnknown: false
699
720
  };
700
721
  case "setDragGlobal": return {
701
722
  ...state,
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 \"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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"}
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/**\n * The outcome of the drag-time acceptance check.\n *\n * - `accept` - every file passes the checks we can evaluate during a drag.\n * - `reject` - at least one file confidently fails a check we can fully evaluate during a\n * drag (the file count, or a non-empty MIME type that doesn't match `accept`).\n * - `unknown` - nothing confidently fails, but the outcome can't be confirmed until drop,\n * because a custom `validator` is configured and can't be evaluated yet.\n */\nexport type DragVerdict = \"accept\" | \"reject\" | \"unknown\";\n\n/**\n * Classify a set of dragged files for the `isDragAccept`/`isDragReject`/`isDragUnknown` states.\n *\n * During `dragenter`/`dragover` the browser only exposes `DataTransferItem`s, which carry a MIME\n * `type` but no file name, extension or size (see https://html.spec.whatwg.org/multipage/dnd.html#dndevents).\n * So the drag-time check is deliberately optimistic about anything it can't see:\n *\n * - The custom `validator` is **never** run here. It is typed `(file: File) => ...` and users\n * routinely read `file.name`/`file.size`, which are `undefined` on a `DataTransferItem` - running\n * it would throw and abort the whole drag handler (leaving `isDragActive` stuck at `false`).\n * See https://github.com/react-dropzone/react-dropzone/issues/1408\n * - When a `validator` is configured we therefore can't promise the files are acceptable, so the\n * verdict is `unknown` rather than a misleading `reject` (or a premature `accept`).\n * See https://github.com/react-dropzone/react-dropzone/issues/1244\n *\n * The full check (including the `validator`) still runs on drop in {@link fileAccepted}/`setFiles`.\n */\nexport function getDragVerdict({\n files,\n accept,\n minSize,\n maxSize,\n multiple,\n maxFiles = 0,\n validator\n}: {\n files: Array<File | DataTransferItem>;\n accept?: string;\n minSize?: number;\n maxSize?: number;\n multiple?: boolean;\n maxFiles?: number;\n validator?: (file: File) => FileError | readonly FileError[] | null;\n}): DragVerdict {\n // The file count is knowable during a drag, so an over-the-limit selection is a confident reject.\n if ((!multiple && files.length > 1) || (multiple && maxFiles >= 1 && files.length > maxFiles)) {\n return \"reject\";\n }\n\n const confidentlyRejected = files.some(file => {\n const [accepted] = fileAccepted(file as File, accept);\n const [sizeMatch] = fileMatchSize(file as File, minSize, maxSize);\n return !accepted || !sizeMatch;\n });\n if (confidentlyRejected) {\n return \"reject\";\n }\n\n // Built-in checks pass. A custom validator can only ever add rejections on drop, never rescue\n // one - so with a validator present the drag outcome is unknown until we have real Files.\n return validator ? \"unknown\" : \"accept\";\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 canUseFileSystemAccessAPI,\n composeEventHandlers,\n ErrorCode,\n fileAccepted,\n fileMatchSize,\n getDragVerdict,\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 isDragUnknown: 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 isDragUnknown: 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 isDragUnknown: 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 // This is a document-level, bubble-phase listener, so it runs *after* the event has already\n // bubbled through the dropzone root. If the drop landed inside the root and the instance's own\n // onDrop handler already prevented the default, there's nothing left to do.\n //\n // We must NOT bail out on `contains()` alone: when the dropzone is `disabled` or has `noDrag`,\n // the root has no onDrop handler, so nothing prevents the browser's default action and the file\n // is opened in the tab. Falling through to `preventDefault()` here keeps that from happening.\n // See https://github.com/react-dropzone/react-dropzone/issues/1362\n if (rootRef.current && event.target && rootRef.current.contains(event.target as Node) && event.defaultPrevented) {\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 // During a drag we only have DataTransferItems (MIME type, no name/size), so the\n // custom validator can't run yet - a validator-configured dropzone is \"unknown\" until\n // drop rather than a misleading accept/reject. See getDragVerdict for the details.\n const verdict =\n fileCount > 0\n ? getDragVerdict({\n files: files as Array<File | DataTransferItem>,\n accept: acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n })\n : null;\n\n dispatch({\n isDragAccept: verdict === \"accept\",\n isDragReject: verdict === \"reject\",\n isDragUnknown: verdict === \"unknown\",\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 isDragUnknown: 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 isDragUnknown: action.isDragUnknown\n };\n case \"setFiles\":\n return {\n ...state,\n acceptedFiles: action.acceptedFiles,\n fileRejections: action.fileRejections,\n isDragReject: false,\n isDragUnknown: 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.2.1",
3
+ "version": "18.3.0",
4
4
  "description": "Simple HTML5 drag-drop zone with React.js",
5
5
  "keywords": [
6
6
  "drag",
package/src/index.tsx CHANGED
@@ -4,12 +4,12 @@ import type * as React from "react";
4
4
  import {forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useReducer, useRef} from "react";
5
5
  import {
6
6
  acceptPropAsAcceptAttr,
7
- allFilesAccepted,
8
7
  canUseFileSystemAccessAPI,
9
8
  composeEventHandlers,
10
9
  ErrorCode,
11
10
  fileAccepted,
12
11
  fileMatchSize,
12
+ getDragVerdict,
13
13
  isAbort,
14
14
  isEvtWithFiles,
15
15
  isIeOrEdge,
@@ -76,6 +76,7 @@ export type DropzoneState = DropzoneRef & {
76
76
  isDragActive: boolean;
77
77
  isDragAccept: boolean;
78
78
  isDragReject: boolean;
79
+ isDragUnknown: boolean;
79
80
  isDragGlobal: boolean;
80
81
  isFileDialogActive: boolean;
81
82
  acceptedFiles: readonly FileWithPath[];
@@ -130,6 +131,7 @@ interface DropzoneInternalState {
130
131
  isDragActive: boolean;
131
132
  isDragAccept: boolean;
132
133
  isDragReject: boolean;
134
+ isDragUnknown: boolean;
133
135
  isDragGlobal: boolean;
134
136
  acceptedFiles: FileWithPath[];
135
137
  fileRejections: FileRejection[];
@@ -141,6 +143,7 @@ const initialState: DropzoneInternalState = {
141
143
  isDragActive: false,
142
144
  isDragAccept: false,
143
145
  isDragReject: false,
146
+ isDragUnknown: false,
144
147
  isDragGlobal: false,
145
148
  acceptedFiles: [],
146
149
  fileRejections: []
@@ -255,8 +258,15 @@ export function useDropzone(props: DropzoneOptions = {}): DropzoneState {
255
258
  const dragTargetsRef = useRef<EventTarget[]>([]);
256
259
  const globalDragTargetsRef = useRef<EventTarget[]>([]);
257
260
  const onDocumentDrop = (event: DragEvent) => {
258
- if (rootRef.current && event.target && rootRef.current.contains(event.target as Node)) {
259
- // If we intercepted an event for our instance, let it propagate down to the instance's onDrop handler
261
+ // This is a document-level, bubble-phase listener, so it runs *after* the event has already
262
+ // bubbled through the dropzone root. If the drop landed inside the root and the instance's own
263
+ // onDrop handler already prevented the default, there's nothing left to do.
264
+ //
265
+ // We must NOT bail out on `contains()` alone: when the dropzone is `disabled` or has `noDrag`,
266
+ // the root has no onDrop handler, so nothing prevents the browser's default action and the file
267
+ // is opened in the tab. Falling through to `preventDefault()` here keeps that from happening.
268
+ // See https://github.com/react-dropzone/react-dropzone/issues/1362
269
+ if (rootRef.current && event.target && rootRef.current.contains(event.target as Node) && event.defaultPrevented) {
260
270
  return;
261
271
  }
262
272
  event.preventDefault();
@@ -360,22 +370,26 @@ export function useDropzone(props: DropzoneOptions = {}): DropzoneState {
360
370
  }
361
371
 
362
372
  const fileCount = files.length;
363
- const isDragAccept =
364
- fileCount > 0 &&
365
- allFilesAccepted({
366
- files: files as File[],
367
- accept: acceptAttr,
368
- minSize,
369
- maxSize,
370
- multiple,
371
- maxFiles,
372
- validator
373
- });
374
- const isDragReject = fileCount > 0 && !isDragAccept;
373
+ // During a drag we only have DataTransferItems (MIME type, no name/size), so the
374
+ // custom validator can't run yet - a validator-configured dropzone is "unknown" until
375
+ // drop rather than a misleading accept/reject. See getDragVerdict for the details.
376
+ const verdict =
377
+ fileCount > 0
378
+ ? getDragVerdict({
379
+ files: files as Array<File | DataTransferItem>,
380
+ accept: acceptAttr,
381
+ minSize,
382
+ maxSize,
383
+ multiple,
384
+ maxFiles,
385
+ validator
386
+ })
387
+ : null;
375
388
 
376
389
  dispatch({
377
- isDragAccept,
378
- isDragReject,
390
+ isDragAccept: verdict === "accept",
391
+ isDragReject: verdict === "reject",
392
+ isDragUnknown: verdict === "unknown",
379
393
  isDragActive: true,
380
394
  type: "setDraggedFiles"
381
395
  });
@@ -448,7 +462,8 @@ export function useDropzone(props: DropzoneOptions = {}): DropzoneState {
448
462
  type: "setDraggedFiles",
449
463
  isDragActive: false,
450
464
  isDragAccept: false,
451
- isDragReject: false
465
+ isDragReject: false,
466
+ isDragUnknown: false
452
467
  });
453
468
 
454
469
  if (isEvtWithFiles(event) && onDragLeave) {
@@ -786,14 +801,16 @@ function reducer(state: DropzoneInternalState, action: any): DropzoneInternalSta
786
801
  ...state,
787
802
  isDragActive: action.isDragActive,
788
803
  isDragAccept: action.isDragAccept,
789
- isDragReject: action.isDragReject
804
+ isDragReject: action.isDragReject,
805
+ isDragUnknown: action.isDragUnknown
790
806
  };
791
807
  case "setFiles":
792
808
  return {
793
809
  ...state,
794
810
  acceptedFiles: action.acceptedFiles,
795
811
  fileRejections: action.fileRejections,
796
- isDragReject: false
812
+ isDragReject: false,
813
+ isDragUnknown: false
797
814
  };
798
815
  case "setDragGlobal":
799
816
  return {
@@ -162,6 +162,70 @@ export function allFilesAccepted({
162
162
  });
163
163
  }
164
164
 
165
+ /**
166
+ * The outcome of the drag-time acceptance check.
167
+ *
168
+ * - `accept` - every file passes the checks we can evaluate during a drag.
169
+ * - `reject` - at least one file confidently fails a check we can fully evaluate during a
170
+ * drag (the file count, or a non-empty MIME type that doesn't match `accept`).
171
+ * - `unknown` - nothing confidently fails, but the outcome can't be confirmed until drop,
172
+ * because a custom `validator` is configured and can't be evaluated yet.
173
+ */
174
+ export type DragVerdict = "accept" | "reject" | "unknown";
175
+
176
+ /**
177
+ * Classify a set of dragged files for the `isDragAccept`/`isDragReject`/`isDragUnknown` states.
178
+ *
179
+ * During `dragenter`/`dragover` the browser only exposes `DataTransferItem`s, which carry a MIME
180
+ * `type` but no file name, extension or size (see https://html.spec.whatwg.org/multipage/dnd.html#dndevents).
181
+ * So the drag-time check is deliberately optimistic about anything it can't see:
182
+ *
183
+ * - The custom `validator` is **never** run here. It is typed `(file: File) => ...` and users
184
+ * routinely read `file.name`/`file.size`, which are `undefined` on a `DataTransferItem` - running
185
+ * it would throw and abort the whole drag handler (leaving `isDragActive` stuck at `false`).
186
+ * See https://github.com/react-dropzone/react-dropzone/issues/1408
187
+ * - When a `validator` is configured we therefore can't promise the files are acceptable, so the
188
+ * verdict is `unknown` rather than a misleading `reject` (or a premature `accept`).
189
+ * See https://github.com/react-dropzone/react-dropzone/issues/1244
190
+ *
191
+ * The full check (including the `validator`) still runs on drop in {@link fileAccepted}/`setFiles`.
192
+ */
193
+ export function getDragVerdict({
194
+ files,
195
+ accept,
196
+ minSize,
197
+ maxSize,
198
+ multiple,
199
+ maxFiles = 0,
200
+ validator
201
+ }: {
202
+ files: Array<File | DataTransferItem>;
203
+ accept?: string;
204
+ minSize?: number;
205
+ maxSize?: number;
206
+ multiple?: boolean;
207
+ maxFiles?: number;
208
+ validator?: (file: File) => FileError | readonly FileError[] | null;
209
+ }): DragVerdict {
210
+ // The file count is knowable during a drag, so an over-the-limit selection is a confident reject.
211
+ if ((!multiple && files.length > 1) || (multiple && maxFiles >= 1 && files.length > maxFiles)) {
212
+ return "reject";
213
+ }
214
+
215
+ const confidentlyRejected = files.some(file => {
216
+ const [accepted] = fileAccepted(file as File, accept);
217
+ const [sizeMatch] = fileMatchSize(file as File, minSize, maxSize);
218
+ return !accepted || !sizeMatch;
219
+ });
220
+ if (confidentlyRejected) {
221
+ return "reject";
222
+ }
223
+
224
+ // Built-in checks pass. A custom validator can only ever add rejections on drop, never rescue
225
+ // one - so with a validator present the drag outcome is unknown until we have real Files.
226
+ return validator ? "unknown" : "accept";
227
+ }
228
+
165
229
  // React's synthetic events has event.isPropagationStopped,
166
230
  // but to remain compatibility with other libs (Preact) fall back
167
231
  // to check event.cancelBubble