react-dropzone 18.0.0 → 18.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -175,11 +175,21 @@ function pickerOptionsFromAccept(accept) {
175
175
  }];
176
176
  }
177
177
  /**
178
- * Convert the `{accept}` dropzone prop to an array of MIME types/extensions.
178
+ * Convert the `{accept}` dropzone prop to a comma-separated accept attribute string.
179
+ *
180
+ * When `omitWildcardMimeTypesWithExtensions` is set, a wildcard MIME type (e.g. `image/*`)
181
+ * that is paired with explicit extensions is dropped in favour of those extensions. The
182
+ * accept attribute is an OR list, so leaving `image/*` in would make both the native file
183
+ * picker and the drop-time validator accept ANY file of that type, ignoring the extension
184
+ * restriction. The drag-time `isDragAccept` check keeps the wildcard because file names
185
+ * (and therefore extensions) aren't readable during a drag.
186
+ *
187
+ * See https://github.com/react-dropzone/react-dropzone/issues/1220
179
188
  */
180
- function acceptPropAsAcceptAttr(accept) {
189
+ function acceptPropAsAcceptAttr(accept, { omitWildcardMimeTypesWithExtensions = false } = {}) {
181
190
  if (isDefined(accept)) return Object.entries(accept).reduce((a, [mimeType, ext]) => {
182
- a.push(mimeType, ...ext);
191
+ if (omitWildcardMimeTypesWithExtensions && isMIMETypeWildcard(mimeType) && ext.some(isExt)) a.push(...ext);
192
+ else a.push(mimeType, ...ext);
183
193
  return a;
184
194
  }, []).filter((v) => isMIMEType(v) || isExt(v)).join(",");
185
195
  }
@@ -202,6 +212,12 @@ function isMIMEType(v) {
202
212
  return v === "audio/*" || v === "video/*" || v === "image/*" || v === "text/*" || v === "application/*" || /\w+\/[-+.\w]+/g.test(v);
203
213
  }
204
214
  /**
215
+ * Check if v is a wildcard MIME type (e.g. `image/*`).
216
+ */
217
+ function isMIMETypeWildcard(v) {
218
+ return v.endsWith("/*");
219
+ }
220
+ /**
205
221
  * Check if v is a file extension.
206
222
  */
207
223
  function isExt(v) {
@@ -264,6 +280,7 @@ const initialState = {
264
280
  function useDropzone(props = {}) {
265
281
  const { accept, disabled = false, getFilesFromEvent = file_selector.fromEvent, maxSize = Number.POSITIVE_INFINITY, minSize = 0, multiple = true, maxFiles = 0, onDragEnter, onDragLeave, onDragOver, onDrop, onDropAccepted, onDropRejected, onFileDialogCancel, onFileDialogOpen, useFsAccessApi = false, autoFocus = false, preventDropOnDocument = true, noClick = false, noKeyboard = false, noDrag = false, noDragEventsBubbling = false, onError, validator } = props;
266
282
  const acceptAttr = (0, react.useMemo)(() => acceptPropAsAcceptAttr(accept), [accept]);
283
+ const inputAcceptAttr = (0, react.useMemo)(() => acceptPropAsAcceptAttr(accept, { omitWildcardMimeTypesWithExtensions: true }), [accept]);
267
284
  const pickerTypes = (0, react.useMemo)(() => pickerOptionsFromAccept(accept), [accept]);
268
285
  const onFileDialogOpenCb = (0, react.useMemo)(() => typeof onFileDialogOpen === "function" ? onFileDialogOpen : noop, [onFileDialogOpen]);
269
286
  const onFileDialogCancelCb = (0, react.useMemo)(() => typeof onFileDialogCancel === "function" ? onFileDialogCancel : noop, [onFileDialogCancel]);
@@ -439,7 +456,7 @@ function useDropzone(props = {}) {
439
456
  const acceptedFiles = [];
440
457
  const fileRejections = [];
441
458
  files.forEach((file) => {
442
- const [accepted, acceptError] = fileAccepted(file, acceptAttr);
459
+ const [accepted, acceptError] = fileAccepted(file, inputAcceptAttr);
443
460
  const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);
444
461
  const customErrors = validator ? validator(file) : null;
445
462
  if (accepted && sizeMatch && !customErrors) acceptedFiles.push(file);
@@ -472,7 +489,7 @@ function useDropzone(props = {}) {
472
489
  }, [
473
490
  dispatch,
474
491
  multiple,
475
- acceptAttr,
492
+ inputAcceptAttr,
476
493
  minSize,
477
494
  maxSize,
478
495
  maxFiles,
@@ -580,6 +597,7 @@ function useDropzone(props = {}) {
580
597
  role: typeof role === "string" && role !== "" ? role : "presentation",
581
598
  [refKey]: rootRef,
582
599
  ...!disabled && !noKeyboard ? { tabIndex: 0 } : {},
600
+ ...disabled ? { "aria-disabled": true } : {},
583
601
  ...rest
584
602
  }), [
585
603
  rootRef,
@@ -600,9 +618,10 @@ function useDropzone(props = {}) {
600
618
  }, []);
601
619
  const getInputProps = (0, react.useMemo)(() => ({ refKey = "ref", onChange, onClick, ...rest } = {}) => {
602
620
  return {
603
- accept: acceptAttr,
621
+ accept: inputAcceptAttr,
604
622
  multiple,
605
623
  type: "file",
624
+ "aria-label": "file upload",
606
625
  style: {
607
626
  border: 0,
608
627
  clip: "rect(0, 0, 0, 0)",
@@ -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\nexport function getTooLargeRejectionErr(maxSize: number): FileError {\n return {\n code: FILE_TOO_LARGE,\n message: `File is larger than ${maxSize} ${maxSize === 1 ? \"byte\" : \"bytes\"}`\n };\n}\n\nexport function getTooSmallRejectionErr(minSize: number): FileError {\n return {\n code: FILE_TOO_SMALL,\n message: `File is smaller than ${minSize} ${minSize === 1 ? \"byte\" : \"bytes\"}`\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 an array of MIME types/extensions.\n */\nexport function acceptPropAsAcceptAttr(accept?: Accept): string | undefined {\n if (isDefined(accept)) {\n return (\n Object.entries(accept)\n .reduce<string[]>((a, [mimeType, ext]) => {\n a.push(mimeType, ...ext);\n return a;\n }, [])\n // Silently discard invalid entries as pickerOptionsFromAccept warns about these\n .filter(v => isMIMEType(v) || isExt(v))\n .join(\",\")\n );\n }\n\n return undefined;\n}\n\n/**\n * Check if v is an exception caused by aborting a request (e.g window.showOpenFilePicker()).\n */\nexport function isAbort(v: any): boolean {\n return v instanceof DOMException && (v.name === \"AbortError\" || v.code === v.ABORT_ERR);\n}\n\n/**\n * Check if v is a security error.\n */\nexport function isSecurityError(v: any): boolean {\n return v instanceof DOMException && (v.name === \"SecurityError\" || v.code === v.SECURITY_ERR);\n}\n\n/**\n * Check if v is a MIME type string.\n */\nexport function isMIMEType(v: string): boolean {\n return (\n v === \"audio/*\" ||\n v === \"video/*\" ||\n v === \"image/*\" ||\n v === \"text/*\" ||\n v === \"application/*\" ||\n /\\w+\\/[-+.\\w]+/g.test(v)\n );\n}\n\n/**\n * Check if v is a file extension.\n */\nexport function isExt(v: string): boolean {\n return /^.*\\.[\\w]+$/.test(v);\n}\n","import {fromEvent} from \"file-selector\";\nimport type {FileWithPath} from \"file-selector\";\nimport type * as React from \"react\";\nimport {forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useReducer, useRef} from \"react\";\nimport {\n acceptPropAsAcceptAttr,\n allFilesAccepted,\n canUseFileSystemAccessAPI,\n composeEventHandlers,\n ErrorCode,\n fileAccepted,\n fileMatchSize,\n isAbort,\n isEvtWithFiles,\n isIeOrEdge,\n isPropagationStopped,\n isSecurityError,\n onDocumentDragOver,\n pickerOptionsFromAccept,\n TOO_MANY_FILES_REJECTION\n} from \"./utils\";\nimport type {Accept, FileError} from \"./utils\";\n\nexport type {Accept, FileError, FileWithPath};\nexport {ErrorCode};\n\nexport interface DropzoneProps extends DropzoneOptions {\n children?: (state: DropzoneState) => React.ReactElement;\n}\n\nexport interface FileRejection {\n file: FileWithPath;\n errors: readonly FileError[];\n}\n\ntype SharedProps = \"multiple\" | \"onDragEnter\" | \"onDragOver\" | \"onDragLeave\";\n\nexport type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> & {\n accept?: Accept;\n minSize?: number;\n maxSize?: number;\n maxFiles?: number;\n preventDropOnDocument?: boolean;\n noClick?: boolean;\n noKeyboard?: boolean;\n noDrag?: boolean;\n noDragEventsBubbling?: boolean;\n disabled?: boolean;\n onDrop?: <T extends File>(acceptedFiles: T[], fileRejections: FileRejection[], event: DropEvent) => void;\n onDropAccepted?: <T extends File>(files: T[], event: DropEvent) => void;\n onDropRejected?: (fileRejections: FileRejection[], event: DropEvent) => void;\n getFilesFromEvent?: (event: DropEvent) => Promise<Array<File | DataTransferItem>>;\n onFileDialogCancel?: () => void;\n onFileDialogOpen?: () => void;\n onError?: (err: Error) => void;\n validator?: <T extends File>(file: T) => FileError | readonly FileError[] | null;\n useFsAccessApi?: boolean;\n autoFocus?: boolean;\n};\n\nexport type DropEvent =\n | React.DragEvent<HTMLElement>\n | React.ChangeEvent<HTMLInputElement>\n | DragEvent\n | Event\n | Array<FileSystemFileHandle>;\n\nexport interface DropzoneRef {\n open: () => void;\n}\n\nexport type DropzoneState = DropzoneRef & {\n isFocused: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragGlobal: boolean;\n isFileDialogActive: boolean;\n acceptedFiles: readonly FileWithPath[];\n fileRejections: readonly FileRejection[];\n rootRef: React.RefObject<HTMLElement>;\n inputRef: React.RefObject<HTMLInputElement>;\n getRootProps: <T extends DropzoneRootProps>(props?: T) => T;\n getInputProps: <T extends DropzoneInputProps>(props?: T) => T;\n};\n\nexport interface DropzoneRootProps extends React.HTMLAttributes<HTMLElement> {\n refKey?: string;\n [key: string]: any;\n}\n\nexport interface DropzoneInputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n refKey?: string;\n}\n\n/**\n * Convenience wrapper component for the `useDropzone` hook\n *\n * ```jsx\n * <Dropzone>\n * {({getRootProps, getInputProps}) => (\n * <div {...getRootProps()}>\n * <input {...getInputProps()} />\n * <p>Drag 'n' drop some files here, or click to select files</p>\n * </div>\n * )}\n * </Dropzone>\n * ```\n */\nconst Dropzone: React.ForwardRefExoticComponent<DropzoneProps & React.RefAttributes<DropzoneRef>> = forwardRef<\n DropzoneRef,\n DropzoneProps\n>(({children, ...params}, ref) => {\n const {open, ...props} = useDropzone(params);\n\n useImperativeHandle(ref, () => ({open}), [open]);\n\n return <>{children?.({...props, open})}</>;\n});\n\nDropzone.displayName = \"Dropzone\";\n\nexport default Dropzone;\n\ninterface DropzoneInternalState {\n isFocused: boolean;\n isFileDialogActive: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragGlobal: boolean;\n acceptedFiles: FileWithPath[];\n fileRejections: FileRejection[];\n}\n\nconst initialState: DropzoneInternalState = {\n isFocused: false,\n isFileDialogActive: false,\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false,\n isDragGlobal: false,\n acceptedFiles: [],\n fileRejections: []\n};\n\n/**\n * A React hook that creates a drag 'n' drop area.\n *\n * ```jsx\n * function MyDropzone(props) {\n * const {getRootProps, getInputProps} = useDropzone({\n * onDrop: acceptedFiles => {\n * // do something with the File objects, e.g. upload to some server\n * }\n * });\n * return (\n * <div {...getRootProps()}>\n * <input {...getInputProps()} />\n * <p>Drag and drop some files here, or click to select files</p>\n * </div>\n * )\n * }\n * ```\n */\nexport function useDropzone(props: DropzoneOptions = {}): DropzoneState {\n const {\n accept,\n disabled = false,\n getFilesFromEvent = fromEvent,\n maxSize = Number.POSITIVE_INFINITY,\n minSize = 0,\n multiple = true,\n maxFiles = 0,\n onDragEnter,\n onDragLeave,\n onDragOver,\n onDrop,\n onDropAccepted,\n onDropRejected,\n onFileDialogCancel,\n onFileDialogOpen,\n useFsAccessApi = false,\n autoFocus = false,\n preventDropOnDocument = true,\n noClick = false,\n noKeyboard = false,\n noDrag = false,\n noDragEventsBubbling = false,\n onError,\n validator\n } = props;\n\n const acceptAttr = useMemo(() => acceptPropAsAcceptAttr(accept), [accept]);\n const pickerTypes = useMemo(() => pickerOptionsFromAccept(accept), [accept]);\n\n const onFileDialogOpenCb = useMemo<(...args: any[]) => void>(\n () => (typeof onFileDialogOpen === \"function\" ? onFileDialogOpen : noop),\n [onFileDialogOpen]\n );\n const onFileDialogCancelCb = useMemo<(...args: any[]) => void>(\n () => (typeof onFileDialogCancel === \"function\" ? onFileDialogCancel : noop),\n [onFileDialogCancel]\n );\n\n const rootRef = useRef<HTMLElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [state, dispatch] = useReducer(reducer, initialState);\n const {isFocused, isFileDialogActive} = state;\n\n const fsAccessApiWorksRef = useRef(\n typeof window !== \"undefined\" && window.isSecureContext && useFsAccessApi && canUseFileSystemAccessAPI()\n );\n\n // Update file dialog active state when the window is focused on\n const onWindowFocus = () => {\n // Execute the timeout only if the file dialog is opened in the browser\n if (!fsAccessApiWorksRef.current && isFileDialogActive) {\n setTimeout(() => {\n if (inputRef.current) {\n const {files} = inputRef.current;\n\n if (!files?.length) {\n dispatch({type: \"closeDialog\"});\n onFileDialogCancelCb();\n }\n }\n }, 300);\n }\n };\n useEffect(() => {\n window.addEventListener(\"focus\", onWindowFocus, false);\n return () => {\n window.removeEventListener(\"focus\", onWindowFocus, false);\n };\n }, [inputRef, isFileDialogActive, onFileDialogCancelCb, fsAccessApiWorksRef]);\n\n const dragTargetsRef = useRef<EventTarget[]>([]);\n const globalDragTargetsRef = useRef<EventTarget[]>([]);\n const onDocumentDrop = (event: DragEvent) => {\n if (rootRef.current && event.target && rootRef.current.contains(event.target as Node)) {\n // If we intercepted an event for our instance, let it propagate down to the instance's onDrop handler\n return;\n }\n event.preventDefault();\n dragTargetsRef.current = [];\n };\n\n useEffect(() => {\n if (preventDropOnDocument) {\n document.addEventListener(\"dragover\", onDocumentDragOver, false);\n document.addEventListener(\"drop\", onDocumentDrop, false);\n }\n\n return () => {\n if (preventDropOnDocument) {\n document.removeEventListener(\"dragover\", onDocumentDragOver);\n document.removeEventListener(\"drop\", onDocumentDrop);\n }\n };\n }, [rootRef, preventDropOnDocument]);\n\n // Track global drag state for document-level drag events\n useEffect(() => {\n const onDocumentDragEnter = (event: DragEvent) => {\n if (event.target) {\n globalDragTargetsRef.current = [...globalDragTargetsRef.current, event.target];\n }\n\n if (isEvtWithFiles(event)) {\n dispatch({isDragGlobal: true, type: \"setDragGlobal\"});\n }\n };\n\n const onDocumentDragLeave = (event: DragEvent) => {\n // Only deactivate once we've left all children\n globalDragTargetsRef.current = globalDragTargetsRef.current.filter(el => el !== event.target && el !== null);\n\n if (globalDragTargetsRef.current.length > 0) {\n return;\n }\n\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDragEnd = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDropGlobal = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n document.addEventListener(\"dragenter\", onDocumentDragEnter, false);\n document.addEventListener(\"dragleave\", onDocumentDragLeave, false);\n document.addEventListener(\"dragend\", onDocumentDragEnd, false);\n document.addEventListener(\"drop\", onDocumentDropGlobal, false);\n\n return () => {\n document.removeEventListener(\"dragenter\", onDocumentDragEnter);\n document.removeEventListener(\"dragleave\", onDocumentDragLeave);\n document.removeEventListener(\"dragend\", onDocumentDragEnd);\n document.removeEventListener(\"drop\", onDocumentDropGlobal);\n };\n }, [rootRef]);\n\n // Auto focus the root when autoFocus is true\n useEffect(() => {\n if (!disabled && autoFocus && rootRef.current) {\n rootRef.current.focus();\n }\n return () => {};\n }, [rootRef, autoFocus, disabled]);\n\n const onErrCb = useCallback(\n (e: Error) => {\n if (onError) {\n onError(e);\n } else {\n // Let the user know something's gone wrong if they haven't provided the onError cb.\n console.error(e);\n }\n },\n [onError]\n );\n\n const onDragEnterCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n dragTargetsRef.current = [...dragTargetsRef.current, event.target];\n\n if (isEvtWithFiles(event)) {\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n return;\n }\n\n const fileCount = files.length;\n const isDragAccept =\n fileCount > 0 &&\n allFilesAccepted({\n files: files as File[],\n accept: acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n });\n const isDragReject = fileCount > 0 && !isDragAccept;\n\n dispatch({\n isDragAccept,\n isDragReject,\n isDragActive: true,\n type: \"setDraggedFiles\"\n });\n\n if (onDragEnter) {\n onDragEnter(event);\n }\n })\n .catch(e => onErrCb(e));\n }\n },\n [\n getFilesFromEvent,\n onDragEnter,\n onErrCb,\n noDragEventsBubbling,\n acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n ]\n );\n\n const onDragOverCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n const hasFiles = isEvtWithFiles(event);\n if (hasFiles && event.dataTransfer) {\n try {\n event.dataTransfer.dropEffect = \"copy\";\n } catch {\n /* no-op */\n }\n }\n\n if (hasFiles && onDragOver) {\n onDragOver(event);\n }\n\n return false;\n },\n [onDragOver, noDragEventsBubbling]\n );\n\n const onDragLeaveCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n // Only deactivate once the dropzone and all children have been left\n const targets = dragTargetsRef.current.filter(target => rootRef.current?.contains(target as Node));\n // Make sure to remove a target present multiple times only once\n // (Firefox may fire dragenter/dragleave multiple times on the same element)\n const targetIdx = targets.indexOf(event.target);\n if (targetIdx !== -1) {\n targets.splice(targetIdx, 1);\n }\n dragTargetsRef.current = targets;\n if (targets.length > 0) {\n return;\n }\n\n dispatch({\n type: \"setDraggedFiles\",\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false\n });\n\n if (isEvtWithFiles(event) && onDragLeave) {\n onDragLeave(event);\n }\n },\n [rootRef, onDragLeave, noDragEventsBubbling]\n );\n\n const setFiles = useCallback(\n (files: FileWithPath[], event: any) => {\n const acceptedFiles: FileWithPath[] = [];\n const fileRejections: FileRejection[] = [];\n\n files.forEach(file => {\n const [accepted, acceptError] = fileAccepted(file, acceptAttr);\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({file, errors: errors.filter((e): e is FileError => e != null)});\n }\n });\n\n if ((!multiple && acceptedFiles.length > 1) || (multiple && maxFiles >= 1 && acceptedFiles.length > maxFiles)) {\n // Reject everything and empty accepted files\n acceptedFiles.forEach(file => {\n fileRejections.push({file, errors: [TOO_MANY_FILES_REJECTION]});\n });\n acceptedFiles.splice(0);\n }\n\n dispatch({\n acceptedFiles,\n fileRejections,\n type: \"setFiles\"\n });\n\n if (onDrop) {\n onDrop(acceptedFiles, fileRejections, event);\n }\n\n if (fileRejections.length > 0 && onDropRejected) {\n onDropRejected(fileRejections, event);\n }\n\n if (acceptedFiles.length > 0 && onDropAccepted) {\n onDropAccepted(acceptedFiles, event);\n }\n },\n [dispatch, multiple, acceptAttr, minSize, maxSize, maxFiles, onDrop, onDropAccepted, onDropRejected, validator]\n );\n\n const onDropCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n dragTargetsRef.current = [];\n\n if (isEvtWithFiles(event)) {\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n return;\n }\n setFiles(files as FileWithPath[], event);\n })\n .catch(e => onErrCb(e));\n }\n dispatch({type: \"reset\"});\n },\n [getFilesFromEvent, setFiles, onErrCb, noDragEventsBubbling]\n );\n\n // Fn for opening the file dialog programmatically\n const openFileDialog = useCallback(() => {\n // No point to use FS access APIs if context is not secure\n // https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#feature_detection\n if (fsAccessApiWorksRef.current) {\n dispatch({type: \"openDialog\"});\n onFileDialogOpenCb();\n // https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker\n const opts = {\n multiple,\n types: pickerTypes\n };\n (window as any)\n .showOpenFilePicker(opts)\n .then((handles: any) => getFilesFromEvent(handles))\n .then((files: Array<File | DataTransferItem>) => {\n setFiles(files as FileWithPath[], null);\n dispatch({type: \"closeDialog\"});\n })\n .catch((e: any) => {\n // AbortError means the user canceled\n if (isAbort(e)) {\n onFileDialogCancelCb(e);\n dispatch({type: \"closeDialog\"});\n } else if (isSecurityError(e)) {\n fsAccessApiWorksRef.current = false;\n // CORS, so cannot use this API\n // Try using the input\n if (inputRef.current) {\n inputRef.current.value = \"\";\n inputRef.current.click();\n } else {\n onErrCb(\n new Error(\n \"Cannot open the file picker because the https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API is not supported and no <input> was provided.\"\n )\n );\n }\n } else {\n onErrCb(e);\n }\n });\n return;\n }\n\n if (inputRef.current) {\n dispatch({type: \"openDialog\"});\n onFileDialogOpenCb();\n inputRef.current.value = \"\";\n inputRef.current.click();\n }\n }, [dispatch, onFileDialogOpenCb, onFileDialogCancelCb, useFsAccessApi, setFiles, onErrCb, pickerTypes, multiple]);\n\n // Cb to open the file dialog when SPACE/ENTER occurs on the dropzone\n const onKeyDownCb = useCallback(\n (event: any) => {\n // Ignore keyboard events bubbling up the DOM tree\n if (!rootRef.current?.isEqualNode(event.target)) {\n return;\n }\n\n if (event.key === \" \" || event.key === \"Enter\" || event.keyCode === 32 || event.keyCode === 13) {\n event.preventDefault();\n openFileDialog();\n }\n },\n [rootRef, openFileDialog]\n );\n\n // Update focus state for the dropzone\n const onFocusCb = useCallback(() => {\n dispatch({type: \"focus\"});\n }, []);\n const onBlurCb = useCallback(() => {\n dispatch({type: \"blur\"});\n }, []);\n\n // Cb to open the file dialog when click occurs on the dropzone\n const onClickCb = useCallback(() => {\n if (noClick) {\n return;\n }\n\n // In IE11/Edge the file-browser dialog is blocking, therefore, use setTimeout()\n // to ensure React can handle state changes\n // See: https://github.com/react-dropzone/react-dropzone/issues/450\n if (isIeOrEdge()) {\n setTimeout(openFileDialog, 0);\n } else {\n openFileDialog();\n }\n }, [noClick, openFileDialog]);\n\n const composeHandler = (fn: any) => {\n return disabled ? null : fn;\n };\n\n const composeKeyboardHandler = (fn: any) => {\n return noKeyboard ? null : composeHandler(fn);\n };\n\n const composeDragHandler = (fn: any) => {\n return noDrag ? null : composeHandler(fn);\n };\n\n const stopPropagation = (event: any) => {\n if (noDragEventsBubbling) {\n event.stopPropagation();\n }\n };\n\n const getRootProps = useMemo(\n () =>\n ({\n refKey = \"ref\",\n role,\n onKeyDown,\n onFocus,\n onBlur,\n onClick,\n onDragEnter,\n onDragOver,\n onDragLeave,\n onDrop,\n ...rest\n }: DropzoneRootProps = {}) => ({\n onKeyDown: composeKeyboardHandler(composeEventHandlers(onKeyDown, onKeyDownCb)),\n onFocus: composeKeyboardHandler(composeEventHandlers(onFocus, onFocusCb)),\n onBlur: composeKeyboardHandler(composeEventHandlers(onBlur, onBlurCb)),\n onClick: composeHandler(composeEventHandlers(onClick, onClickCb)),\n onDragEnter: composeDragHandler(composeEventHandlers(onDragEnter, onDragEnterCb)),\n onDragOver: composeDragHandler(composeEventHandlers(onDragOver, onDragOverCb)),\n onDragLeave: composeDragHandler(composeEventHandlers(onDragLeave, onDragLeaveCb)),\n onDrop: composeDragHandler(composeEventHandlers(onDrop, onDropCb)),\n role: typeof role === \"string\" && role !== \"\" ? role : \"presentation\",\n [refKey]: rootRef,\n ...(!disabled && !noKeyboard ? {tabIndex: 0} : {}),\n ...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: acceptAttr,\n multiple,\n type: \"file\",\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\nexport function getTooLargeRejectionErr(maxSize: number): FileError {\n return {\n code: FILE_TOO_LARGE,\n message: `File is larger than ${maxSize} ${maxSize === 1 ? \"byte\" : \"bytes\"}`\n };\n}\n\nexport function getTooSmallRejectionErr(minSize: number): FileError {\n return {\n code: FILE_TOO_SMALL,\n message: `File is smaller than ${minSize} ${minSize === 1 ? \"byte\" : \"bytes\"}`\n };\n}\n\nexport const TOO_MANY_FILES_REJECTION: FileError = {\n code: TOO_MANY_FILES,\n message: \"Too many files\"\n};\n\n/**\n * Check if the given file is a DataTransferItem with an empty type.\n *\n * During drag events, browsers may return DataTransferItem objects instead of File objects.\n * Some browsers (e.g., Chrome) return an empty MIME type for certain file types (like .md files)\n * on DataTransferItem during drag events, even though the type is correctly set during drop.\n */\nexport function isDataTransferItemWithEmptyType(file: File | DataTransferItem): boolean {\n return file.type === \"\" && typeof (file as DataTransferItem).getAsFile === \"function\";\n}\n\n/**\n * Check if file is accepted.\n *\n * Firefox versions prior to 53 return a bogus MIME type for every file drag,\n * so dragovers with that MIME type will always be accepted.\n *\n * Chrome/other browsers may return an empty MIME type for files during drag events,\n * so we accept those as well (we'll validate properly on drop).\n */\nexport function fileAccepted(file: File, accept?: string): [boolean, FileError | null] {\n const isAcceptable =\n file.type === \"application/x-moz-file\" || accepts(file, accept ?? \"\") || isDataTransferItemWithEmptyType(file);\n return [isAcceptable, isAcceptable ? null : getInvalidTypeRejectionErr(accept)];\n}\n\nexport function fileMatchSize(\n file: {size?: number | null},\n minSize?: number,\n maxSize?: number\n): [boolean, FileError | null] {\n if (isDefined(file.size)) {\n if (isDefined(minSize) && isDefined(maxSize)) {\n if (file.size > maxSize) return [false, getTooLargeRejectionErr(maxSize)];\n if (file.size < minSize) return [false, getTooSmallRejectionErr(minSize)];\n } else if (isDefined(minSize) && file.size < minSize) {\n return [false, getTooSmallRejectionErr(minSize)];\n } else if (isDefined(maxSize) && file.size > maxSize) {\n return [false, getTooLargeRejectionErr(maxSize)];\n }\n }\n return [true, null];\n}\n\nfunction isDefined<T>(value: T): value is NonNullable<T> {\n return value !== undefined && value !== null;\n}\n\nexport function allFilesAccepted({\n files,\n accept,\n minSize,\n maxSize,\n multiple,\n maxFiles = 0,\n validator\n}: {\n files: File[];\n accept?: string;\n minSize?: number;\n maxSize?: number;\n multiple?: boolean;\n maxFiles?: number;\n validator?: (file: File) => FileError | readonly FileError[] | null;\n}): boolean {\n if ((!multiple && files.length > 1) || (multiple && maxFiles >= 1 && files.length > maxFiles)) {\n return false;\n }\n\n return files.every(file => {\n const [accepted] = fileAccepted(file, accept);\n const [sizeMatch] = fileMatchSize(file, minSize, maxSize);\n const customErrors = validator ? validator(file) : null;\n return accepted && sizeMatch && !customErrors;\n });\n}\n\n// React's synthetic events has event.isPropagationStopped,\n// but to remain compatibility with other libs (Preact) fall back\n// to check event.cancelBubble\nexport function isPropagationStopped(event: any): boolean {\n if (typeof event.isPropagationStopped === \"function\") {\n return event.isPropagationStopped();\n } else if (typeof event.cancelBubble !== \"undefined\") {\n return event.cancelBubble;\n }\n return false;\n}\n\nexport function isEvtWithFiles(event: any): boolean {\n if (!event.dataTransfer) {\n return !!event.target && !!event.target.files;\n }\n // https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/types\n // https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#file\n return Array.prototype.some.call(\n event.dataTransfer.types,\n (type: string) => type === \"Files\" || type === \"application/x-moz-file\"\n );\n}\n\nexport function isKindFile(item: any): boolean {\n return typeof item === \"object\" && item !== null && item.kind === \"file\";\n}\n\n// allow the entire document to be a drag target\nexport function onDocumentDragOver(event: Event): void {\n event.preventDefault();\n}\n\nfunction isIe(userAgent: string): boolean {\n return userAgent.indexOf(\"MSIE\") !== -1 || userAgent.indexOf(\"Trident/\") !== -1;\n}\n\nfunction isEdge(userAgent: string): boolean {\n return userAgent.indexOf(\"Edge/\") !== -1;\n}\n\nexport function isIeOrEdge(userAgent: string = window.navigator.userAgent): boolean {\n return isIe(userAgent) || isEdge(userAgent);\n}\n\n/**\n * This is intended to be used to compose event handlers.\n * They are executed in order until one of them calls `event.isPropagationStopped()`.\n * Note that the check is done on the first invoke too,\n * meaning that if propagation was stopped before invoking the fns,\n * no handlers will be executed.\n */\nexport function composeEventHandlers(\n ...fns: Array<((event: any, ...args: any[]) => void) | null | undefined>\n): (event: any, ...args: any[]) => boolean {\n return (event: any, ...args: any[]) =>\n fns.some(fn => {\n if (!isPropagationStopped(event) && fn) {\n fn(event, ...args);\n }\n return isPropagationStopped(event);\n });\n}\n\n/**\n * canUseFileSystemAccessAPI checks if the File System Access API is supported by the browser.\n */\nexport function canUseFileSystemAccessAPI(): boolean {\n return \"showOpenFilePicker\" in window;\n}\n\n/**\n * Convert the `{accept}` dropzone prop to the `{types}` option for showOpenFilePicker.\n */\nexport function pickerOptionsFromAccept(accept?: Accept): Array<{description: string; accept: Accept}> | undefined {\n if (isDefined(accept)) {\n const acceptForPicker = Object.entries(accept)\n .filter(([mimeType, ext]) => {\n let ok = true;\n\n if (!isMIMEType(mimeType)) {\n console.warn(\n `Skipped \"${mimeType}\" because it is not a valid MIME type. Check https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types for a list of valid MIME types.`\n );\n ok = false;\n }\n\n if (!Array.isArray(ext) || !ext.every(isExt)) {\n console.warn(`Skipped \"${mimeType}\" because an invalid file extension was provided.`);\n ok = false;\n }\n\n return ok;\n })\n .reduce<Accept>((agg, [mimeType, ext]) => {\n agg[mimeType] = ext;\n return agg;\n }, {});\n return [\n {\n // description is required due to https://crbug.com/1264708\n description: \"Files\",\n accept: acceptForPicker\n }\n ];\n }\n return undefined;\n}\n\n/**\n * Convert the `{accept}` dropzone prop to a comma-separated accept attribute string.\n *\n * When `omitWildcardMimeTypesWithExtensions` is set, a wildcard MIME type (e.g. `image/*`)\n * that is paired with explicit extensions is dropped in favour of those extensions. The\n * accept attribute is an OR list, so leaving `image/*` in would make both the native file\n * picker and the drop-time validator accept ANY file of that type, ignoring the extension\n * restriction. The drag-time `isDragAccept` check keeps the wildcard because file names\n * (and therefore extensions) aren't readable during a drag.\n *\n * See https://github.com/react-dropzone/react-dropzone/issues/1220\n */\nexport function acceptPropAsAcceptAttr(\n accept?: Accept,\n {omitWildcardMimeTypesWithExtensions = false}: {omitWildcardMimeTypesWithExtensions?: boolean} = {}\n): string | undefined {\n if (isDefined(accept)) {\n return (\n Object.entries(accept)\n .reduce<string[]>((a, [mimeType, ext]) => {\n if (omitWildcardMimeTypesWithExtensions && isMIMETypeWildcard(mimeType) && ext.some(isExt)) {\n a.push(...ext);\n } else {\n a.push(mimeType, ...ext);\n }\n return a;\n }, [])\n // Silently discard invalid entries as pickerOptionsFromAccept warns about these\n .filter(v => isMIMEType(v) || isExt(v))\n .join(\",\")\n );\n }\n\n return undefined;\n}\n\n/**\n * Check if v is an exception caused by aborting a request (e.g window.showOpenFilePicker()).\n */\nexport function isAbort(v: any): boolean {\n return v instanceof DOMException && (v.name === \"AbortError\" || v.code === v.ABORT_ERR);\n}\n\n/**\n * Check if v is a security error.\n */\nexport function isSecurityError(v: any): boolean {\n return v instanceof DOMException && (v.name === \"SecurityError\" || v.code === v.SECURITY_ERR);\n}\n\n/**\n * Check if v is a MIME type string.\n */\nexport function isMIMEType(v: string): boolean {\n return (\n v === \"audio/*\" ||\n v === \"video/*\" ||\n v === \"image/*\" ||\n v === \"text/*\" ||\n v === \"application/*\" ||\n /\\w+\\/[-+.\\w]+/g.test(v)\n );\n}\n\n/**\n * Check if v is a wildcard MIME type (e.g. `image/*`).\n */\nexport function isMIMETypeWildcard(v: string): boolean {\n return v.endsWith(\"/*\");\n}\n\n/**\n * Check if v is a file extension.\n */\nexport function isExt(v: string): boolean {\n return /^.*\\.[\\w]+$/.test(v);\n}\n","import {fromEvent} from \"file-selector\";\nimport type {FileWithPath} from \"file-selector\";\nimport type * as React from \"react\";\nimport {forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useReducer, useRef} from \"react\";\nimport {\n acceptPropAsAcceptAttr,\n allFilesAccepted,\n canUseFileSystemAccessAPI,\n composeEventHandlers,\n ErrorCode,\n fileAccepted,\n fileMatchSize,\n isAbort,\n isEvtWithFiles,\n isIeOrEdge,\n isPropagationStopped,\n isSecurityError,\n onDocumentDragOver,\n pickerOptionsFromAccept,\n TOO_MANY_FILES_REJECTION\n} from \"./utils\";\nimport type {Accept, FileError} from \"./utils\";\n\nexport type {Accept, FileError, FileWithPath};\nexport {ErrorCode};\n\nexport interface DropzoneProps extends DropzoneOptions {\n children?: (state: DropzoneState) => React.ReactElement;\n}\n\nexport interface FileRejection {\n file: FileWithPath;\n errors: readonly FileError[];\n}\n\ntype SharedProps = \"multiple\" | \"onDragEnter\" | \"onDragOver\" | \"onDragLeave\";\n\nexport type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> & {\n accept?: Accept;\n minSize?: number;\n maxSize?: number;\n maxFiles?: number;\n preventDropOnDocument?: boolean;\n noClick?: boolean;\n noKeyboard?: boolean;\n noDrag?: boolean;\n noDragEventsBubbling?: boolean;\n disabled?: boolean;\n onDrop?: <T extends File>(acceptedFiles: T[], fileRejections: FileRejection[], event: DropEvent) => void;\n onDropAccepted?: <T extends File>(files: T[], event: DropEvent) => void;\n onDropRejected?: (fileRejections: FileRejection[], event: DropEvent) => void;\n getFilesFromEvent?: (event: DropEvent | Array<FileSystemFileHandle>) => Promise<Array<File | DataTransferItem>>;\n onFileDialogCancel?: () => void;\n onFileDialogOpen?: () => void;\n onError?: (err: Error) => void;\n validator?: <T extends File>(file: T) => FileError | readonly FileError[] | null;\n useFsAccessApi?: boolean;\n autoFocus?: boolean;\n};\n\nexport type DropEvent = React.DragEvent<HTMLElement> | React.ChangeEvent<HTMLInputElement> | DragEvent | Event;\n\nexport interface DropzoneRef {\n open: () => void;\n}\n\nexport type DropzoneState = DropzoneRef & {\n isFocused: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragGlobal: boolean;\n isFileDialogActive: boolean;\n acceptedFiles: readonly FileWithPath[];\n fileRejections: readonly FileRejection[];\n rootRef: React.RefObject<HTMLElement>;\n inputRef: React.RefObject<HTMLInputElement>;\n getRootProps: <T extends DropzoneRootProps>(props?: T) => T;\n getInputProps: <T extends DropzoneInputProps>(props?: T) => T;\n};\n\nexport interface DropzoneRootProps extends React.HTMLAttributes<HTMLElement> {\n refKey?: string;\n [key: string]: any;\n}\n\nexport interface DropzoneInputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n refKey?: string;\n}\n\n/**\n * Convenience wrapper component for the `useDropzone` hook\n *\n * ```jsx\n * <Dropzone>\n * {({getRootProps, getInputProps}) => (\n * <div {...getRootProps()}>\n * <input {...getInputProps()} />\n * <p>Drag 'n' drop some files here, or click to select files</p>\n * </div>\n * )}\n * </Dropzone>\n * ```\n */\nconst Dropzone: React.ForwardRefExoticComponent<DropzoneProps & React.RefAttributes<DropzoneRef>> = forwardRef<\n DropzoneRef,\n DropzoneProps\n>(({children, ...params}, ref) => {\n const {open, ...props} = useDropzone(params);\n\n useImperativeHandle(ref, () => ({open}), [open]);\n\n return <>{children?.({...props, open})}</>;\n});\n\nDropzone.displayName = \"Dropzone\";\n\nexport default Dropzone;\n\ninterface DropzoneInternalState {\n isFocused: boolean;\n isFileDialogActive: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragGlobal: boolean;\n acceptedFiles: FileWithPath[];\n fileRejections: FileRejection[];\n}\n\nconst initialState: DropzoneInternalState = {\n isFocused: false,\n isFileDialogActive: false,\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false,\n isDragGlobal: false,\n acceptedFiles: [],\n fileRejections: []\n};\n\n/**\n * A React hook that creates a drag 'n' drop area.\n *\n * ```jsx\n * function MyDropzone(props) {\n * const {getRootProps, getInputProps} = useDropzone({\n * onDrop: acceptedFiles => {\n * // do something with the File objects, e.g. upload to some server\n * }\n * });\n * return (\n * <div {...getRootProps()}>\n * <input {...getInputProps()} />\n * <p>Drag and drop some files here, or click to select files</p>\n * </div>\n * )\n * }\n * ```\n */\nexport function useDropzone(props: DropzoneOptions = {}): DropzoneState {\n const {\n accept,\n disabled = false,\n getFilesFromEvent = fromEvent,\n maxSize = Number.POSITIVE_INFINITY,\n minSize = 0,\n multiple = true,\n maxFiles = 0,\n onDragEnter,\n onDragLeave,\n onDragOver,\n onDrop,\n onDropAccepted,\n onDropRejected,\n onFileDialogCancel,\n onFileDialogOpen,\n useFsAccessApi = false,\n autoFocus = false,\n preventDropOnDocument = true,\n noClick = false,\n noKeyboard = false,\n noDrag = false,\n noDragEventsBubbling = false,\n onError,\n validator\n } = props;\n\n // `acceptAttr` keeps wildcard MIME types (e.g. `image/*`) so the drag-time\n // `isDragAccept`/`isDragReject` check can react to a file's MIME type - file names\n // (hence extensions) aren't readable during a drag.\n const acceptAttr = useMemo(() => acceptPropAsAcceptAttr(accept), [accept]);\n // `inputAcceptAttr` drops a wildcard MIME type when it is paired with extensions, so the\n // native picker and drop-time validation enforce the extensions instead of accepting any\n // file of that type. See https://github.com/react-dropzone/react-dropzone/issues/1220\n const inputAcceptAttr = useMemo(\n () =>\n acceptPropAsAcceptAttr(accept, {\n omitWildcardMimeTypesWithExtensions: true\n }),\n [accept]\n );\n const pickerTypes = useMemo(() => pickerOptionsFromAccept(accept), [accept]);\n\n const onFileDialogOpenCb = useMemo<(...args: any[]) => void>(\n () => (typeof onFileDialogOpen === \"function\" ? onFileDialogOpen : noop),\n [onFileDialogOpen]\n );\n const onFileDialogCancelCb = useMemo<(...args: any[]) => void>(\n () => (typeof onFileDialogCancel === \"function\" ? onFileDialogCancel : noop),\n [onFileDialogCancel]\n );\n\n const rootRef = useRef<HTMLElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [state, dispatch] = useReducer(reducer, initialState);\n const {isFocused, isFileDialogActive} = state;\n\n const fsAccessApiWorksRef = useRef(\n typeof window !== \"undefined\" && window.isSecureContext && useFsAccessApi && canUseFileSystemAccessAPI()\n );\n\n // Update file dialog active state when the window is focused on\n const onWindowFocus = () => {\n // Execute the timeout only if the file dialog is opened in the browser\n if (!fsAccessApiWorksRef.current && isFileDialogActive) {\n setTimeout(() => {\n if (inputRef.current) {\n const {files} = inputRef.current;\n\n if (!files?.length) {\n dispatch({type: \"closeDialog\"});\n onFileDialogCancelCb();\n }\n }\n }, 300);\n }\n };\n useEffect(() => {\n window.addEventListener(\"focus\", onWindowFocus, false);\n return () => {\n window.removeEventListener(\"focus\", onWindowFocus, false);\n };\n }, [inputRef, isFileDialogActive, onFileDialogCancelCb, fsAccessApiWorksRef]);\n\n const dragTargetsRef = useRef<EventTarget[]>([]);\n const globalDragTargetsRef = useRef<EventTarget[]>([]);\n const onDocumentDrop = (event: DragEvent) => {\n if (rootRef.current && event.target && rootRef.current.contains(event.target as Node)) {\n // If we intercepted an event for our instance, let it propagate down to the instance's onDrop handler\n return;\n }\n event.preventDefault();\n dragTargetsRef.current = [];\n };\n\n useEffect(() => {\n if (preventDropOnDocument) {\n document.addEventListener(\"dragover\", onDocumentDragOver, false);\n document.addEventListener(\"drop\", onDocumentDrop, false);\n }\n\n return () => {\n if (preventDropOnDocument) {\n document.removeEventListener(\"dragover\", onDocumentDragOver);\n document.removeEventListener(\"drop\", onDocumentDrop);\n }\n };\n }, [rootRef, preventDropOnDocument]);\n\n // Track global drag state for document-level drag events\n useEffect(() => {\n const onDocumentDragEnter = (event: DragEvent) => {\n if (event.target) {\n globalDragTargetsRef.current = [...globalDragTargetsRef.current, event.target];\n }\n\n if (isEvtWithFiles(event)) {\n dispatch({isDragGlobal: true, type: \"setDragGlobal\"});\n }\n };\n\n const onDocumentDragLeave = (event: DragEvent) => {\n // Only deactivate once we've left all children\n globalDragTargetsRef.current = globalDragTargetsRef.current.filter(el => el !== event.target && el !== null);\n\n if (globalDragTargetsRef.current.length > 0) {\n return;\n }\n\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDragEnd = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDropGlobal = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n document.addEventListener(\"dragenter\", onDocumentDragEnter, false);\n document.addEventListener(\"dragleave\", onDocumentDragLeave, false);\n document.addEventListener(\"dragend\", onDocumentDragEnd, false);\n document.addEventListener(\"drop\", onDocumentDropGlobal, false);\n\n return () => {\n document.removeEventListener(\"dragenter\", onDocumentDragEnter);\n document.removeEventListener(\"dragleave\", onDocumentDragLeave);\n document.removeEventListener(\"dragend\", onDocumentDragEnd);\n document.removeEventListener(\"drop\", onDocumentDropGlobal);\n };\n }, [rootRef]);\n\n // Auto focus the root when autoFocus is true\n useEffect(() => {\n if (!disabled && autoFocus && rootRef.current) {\n rootRef.current.focus();\n }\n return () => {};\n }, [rootRef, autoFocus, disabled]);\n\n const onErrCb = useCallback(\n (e: Error) => {\n if (onError) {\n onError(e);\n } else {\n // Let the user know something's gone wrong if they haven't provided the onError cb.\n console.error(e);\n }\n },\n [onError]\n );\n\n const onDragEnterCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n dragTargetsRef.current = [...dragTargetsRef.current, event.target];\n\n if (isEvtWithFiles(event)) {\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n return;\n }\n\n const fileCount = files.length;\n const isDragAccept =\n fileCount > 0 &&\n allFilesAccepted({\n files: files as File[],\n accept: acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n });\n const isDragReject = fileCount > 0 && !isDragAccept;\n\n dispatch({\n isDragAccept,\n isDragReject,\n isDragActive: true,\n type: \"setDraggedFiles\"\n });\n\n if (onDragEnter) {\n onDragEnter(event);\n }\n })\n .catch(e => onErrCb(e));\n }\n },\n [\n getFilesFromEvent,\n onDragEnter,\n onErrCb,\n noDragEventsBubbling,\n acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n ]\n );\n\n const onDragOverCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n const hasFiles = isEvtWithFiles(event);\n if (hasFiles && event.dataTransfer) {\n try {\n event.dataTransfer.dropEffect = \"copy\";\n } catch {\n /* no-op */\n }\n }\n\n if (hasFiles && onDragOver) {\n onDragOver(event);\n }\n\n return false;\n },\n [onDragOver, noDragEventsBubbling]\n );\n\n const onDragLeaveCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n // Only deactivate once the dropzone and all children have been left\n const targets = dragTargetsRef.current.filter(target => rootRef.current?.contains(target as Node));\n // Make sure to remove a target present multiple times only once\n // (Firefox may fire dragenter/dragleave multiple times on the same element)\n const targetIdx = targets.indexOf(event.target);\n if (targetIdx !== -1) {\n targets.splice(targetIdx, 1);\n }\n dragTargetsRef.current = targets;\n if (targets.length > 0) {\n return;\n }\n\n dispatch({\n type: \"setDraggedFiles\",\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false\n });\n\n if (isEvtWithFiles(event) && onDragLeave) {\n onDragLeave(event);\n }\n },\n [rootRef, onDragLeave, noDragEventsBubbling]\n );\n\n const setFiles = useCallback(\n (files: FileWithPath[], event: any) => {\n const acceptedFiles: FileWithPath[] = [];\n const fileRejections: FileRejection[] = [];\n\n files.forEach(file => {\n const [accepted, acceptError] = fileAccepted(file, inputAcceptAttr);\n const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);\n const customErrors = validator ? validator(file) : null;\n\n if (accepted && sizeMatch && !customErrors) {\n acceptedFiles.push(file);\n } else {\n let errors: Array<FileError | null> = [acceptError, sizeError];\n\n if (customErrors) {\n errors = errors.concat(customErrors);\n }\n\n fileRejections.push({\n file,\n errors: errors.filter((e): e is FileError => e != null)\n });\n }\n });\n\n if ((!multiple && acceptedFiles.length > 1) || (multiple && maxFiles >= 1 && acceptedFiles.length > maxFiles)) {\n // Reject everything and empty accepted files\n acceptedFiles.forEach(file => {\n fileRejections.push({file, errors: [TOO_MANY_FILES_REJECTION]});\n });\n acceptedFiles.splice(0);\n }\n\n dispatch({\n acceptedFiles,\n fileRejections,\n type: \"setFiles\"\n });\n\n if (onDrop) {\n onDrop(acceptedFiles, fileRejections, event);\n }\n\n if (fileRejections.length > 0 && onDropRejected) {\n onDropRejected(fileRejections, event);\n }\n\n if (acceptedFiles.length > 0 && onDropAccepted) {\n onDropAccepted(acceptedFiles, event);\n }\n },\n [dispatch, multiple, inputAcceptAttr, minSize, maxSize, maxFiles, onDrop, onDropAccepted, onDropRejected, validator]\n );\n\n const onDropCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n dragTargetsRef.current = [];\n\n if (isEvtWithFiles(event)) {\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n return;\n }\n setFiles(files as FileWithPath[], event);\n })\n .catch(e => onErrCb(e));\n }\n dispatch({type: \"reset\"});\n },\n [getFilesFromEvent, setFiles, onErrCb, noDragEventsBubbling]\n );\n\n // Fn for opening the file dialog programmatically\n const openFileDialog = useCallback(() => {\n // No point to use FS access APIs if context is not secure\n // https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#feature_detection\n if (fsAccessApiWorksRef.current) {\n dispatch({type: \"openDialog\"});\n onFileDialogOpenCb();\n // https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker\n const opts = {\n multiple,\n types: pickerTypes\n };\n (window as any)\n .showOpenFilePicker(opts)\n .then((handles: any) => getFilesFromEvent(handles))\n .then((files: Array<File | DataTransferItem>) => {\n setFiles(files as FileWithPath[], null);\n dispatch({type: \"closeDialog\"});\n })\n .catch((e: any) => {\n // AbortError means the user canceled\n if (isAbort(e)) {\n onFileDialogCancelCb(e);\n dispatch({type: \"closeDialog\"});\n } else if (isSecurityError(e)) {\n fsAccessApiWorksRef.current = false;\n // CORS, so cannot use this API\n // Try using the input\n if (inputRef.current) {\n inputRef.current.value = \"\";\n inputRef.current.click();\n } else {\n onErrCb(\n new Error(\n \"Cannot open the file picker because the https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API is not supported and no <input> was provided.\"\n )\n );\n }\n } else {\n onErrCb(e);\n }\n });\n return;\n }\n\n if (inputRef.current) {\n dispatch({type: \"openDialog\"});\n onFileDialogOpenCb();\n inputRef.current.value = \"\";\n inputRef.current.click();\n }\n }, [dispatch, onFileDialogOpenCb, onFileDialogCancelCb, useFsAccessApi, setFiles, onErrCb, pickerTypes, multiple]);\n\n // Cb to open the file dialog when SPACE/ENTER occurs on the dropzone\n const onKeyDownCb = useCallback(\n (event: any) => {\n // Ignore keyboard events bubbling up the DOM tree\n if (!rootRef.current?.isEqualNode(event.target)) {\n return;\n }\n\n if (event.key === \" \" || event.key === \"Enter\" || event.keyCode === 32 || event.keyCode === 13) {\n event.preventDefault();\n openFileDialog();\n }\n },\n [rootRef, openFileDialog]\n );\n\n // Update focus state for the dropzone\n const onFocusCb = useCallback(() => {\n dispatch({type: \"focus\"});\n }, []);\n const onBlurCb = useCallback(() => {\n dispatch({type: \"blur\"});\n }, []);\n\n // Cb to open the file dialog when click occurs on the dropzone\n const onClickCb = useCallback(() => {\n if (noClick) {\n return;\n }\n\n // In IE11/Edge the file-browser dialog is blocking, therefore, use setTimeout()\n // to ensure React can handle state changes\n // See: https://github.com/react-dropzone/react-dropzone/issues/450\n if (isIeOrEdge()) {\n setTimeout(openFileDialog, 0);\n } else {\n openFileDialog();\n }\n }, [noClick, openFileDialog]);\n\n const composeHandler = (fn: any) => {\n return disabled ? null : fn;\n };\n\n const composeKeyboardHandler = (fn: any) => {\n return noKeyboard ? null : composeHandler(fn);\n };\n\n const composeDragHandler = (fn: any) => {\n return noDrag ? null : composeHandler(fn);\n };\n\n const stopPropagation = (event: any) => {\n if (noDragEventsBubbling) {\n event.stopPropagation();\n }\n };\n\n const getRootProps = useMemo(\n () =>\n ({\n refKey = \"ref\",\n role,\n onKeyDown,\n onFocus,\n onBlur,\n onClick,\n onDragEnter,\n onDragOver,\n onDragLeave,\n onDrop,\n ...rest\n }: DropzoneRootProps = {}) => ({\n onKeyDown: composeKeyboardHandler(composeEventHandlers(onKeyDown, onKeyDownCb)),\n onFocus: composeKeyboardHandler(composeEventHandlers(onFocus, onFocusCb)),\n onBlur: composeKeyboardHandler(composeEventHandlers(onBlur, onBlurCb)),\n onClick: composeHandler(composeEventHandlers(onClick, onClickCb)),\n onDragEnter: composeDragHandler(composeEventHandlers(onDragEnter, onDragEnterCb)),\n onDragOver: composeDragHandler(composeEventHandlers(onDragOver, onDragOverCb)),\n onDragLeave: composeDragHandler(composeEventHandlers(onDragLeave, onDragLeaveCb)),\n onDrop: composeDragHandler(composeEventHandlers(onDrop, onDropCb)),\n role: typeof role === \"string\" && role !== \"\" ? role : \"presentation\",\n [refKey]: rootRef,\n ...(!disabled && !noKeyboard ? {tabIndex: 0} : {}),\n ...(disabled ? {\"aria-disabled\": true} : {}),\n ...rest\n }),\n [\n rootRef,\n onKeyDownCb,\n onFocusCb,\n onBlurCb,\n onClickCb,\n onDragEnterCb,\n onDragOverCb,\n onDragLeaveCb,\n onDropCb,\n noKeyboard,\n noDrag,\n disabled\n ]\n );\n\n const onInputElementClick = useCallback((event: any) => {\n event.stopPropagation();\n }, []);\n\n const getInputProps = useMemo(\n () =>\n ({refKey = \"ref\", onChange, onClick, ...rest}: DropzoneInputProps = {}) => {\n const inputProps = {\n accept: inputAcceptAttr,\n multiple,\n type: \"file\",\n \"aria-label\": \"file upload\",\n style: {\n border: 0,\n clip: \"rect(0, 0, 0, 0)\",\n clipPath: \"inset(50%)\",\n height: \"1px\",\n margin: \"0 -1px -1px 0\",\n overflow: \"hidden\",\n padding: 0,\n position: \"absolute\",\n width: \"1px\",\n whiteSpace: \"nowrap\"\n },\n onChange: composeHandler(composeEventHandlers(onChange, onDropCb)),\n onClick: composeHandler(composeEventHandlers(onClick, onInputElementClick)),\n tabIndex: -1,\n [refKey]: inputRef\n };\n\n return {\n ...inputProps,\n ...rest\n };\n },\n [inputRef, accept, multiple, onDropCb, disabled]\n );\n\n return {\n ...state,\n isFocused: isFocused && !disabled,\n getRootProps,\n getInputProps,\n rootRef,\n inputRef,\n open: composeHandler(openFileDialog)\n } as unknown as DropzoneState;\n}\n\nfunction reducer(state: DropzoneInternalState, action: any): DropzoneInternalState {\n switch (action.type) {\n case \"focus\":\n return {\n ...state,\n isFocused: true\n };\n case \"blur\":\n return {\n ...state,\n isFocused: false\n };\n case \"openDialog\":\n return {\n ...initialState,\n isFileDialogActive: true\n };\n case \"closeDialog\":\n return {\n ...state,\n isFileDialogActive: false\n };\n case \"setDraggedFiles\":\n return {\n ...state,\n isDragActive: action.isDragActive,\n isDragAccept: action.isDragAccept,\n isDragReject: action.isDragReject\n };\n case \"setFiles\":\n return {\n ...state,\n acceptedFiles: action.acceptedFiles,\n fileRejections: action.fileRejections,\n isDragReject: false\n };\n case \"setDragGlobal\":\n return {\n ...state,\n isDragGlobal: action.isDragGlobal\n };\n case \"reset\":\n return {\n ...initialState\n };\n default:\n return state;\n }\n}\n\nfunction noop() {}\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -44,7 +44,7 @@ type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> & {
44
44
  onDrop?: <T extends File>(acceptedFiles: T[], fileRejections: FileRejection[], event: DropEvent) => void;
45
45
  onDropAccepted?: <T extends File>(files: T[], event: DropEvent) => void;
46
46
  onDropRejected?: (fileRejections: FileRejection[], event: DropEvent) => void;
47
- getFilesFromEvent?: (event: DropEvent) => Promise<Array<File | DataTransferItem>>;
47
+ getFilesFromEvent?: (event: DropEvent | Array<FileSystemFileHandle>) => Promise<Array<File | DataTransferItem>>;
48
48
  onFileDialogCancel?: () => void;
49
49
  onFileDialogOpen?: () => void;
50
50
  onError?: (err: Error) => void;
@@ -52,7 +52,7 @@ type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> & {
52
52
  useFsAccessApi?: boolean;
53
53
  autoFocus?: boolean;
54
54
  };
55
- type DropEvent = React.DragEvent<HTMLElement> | React.ChangeEvent<HTMLInputElement> | DragEvent | Event | Array<FileSystemFileHandle>;
55
+ type DropEvent = React.DragEvent<HTMLElement> | React.ChangeEvent<HTMLInputElement> | DragEvent | Event;
56
56
  interface DropzoneRef {
57
57
  open: () => void;
58
58
  }
package/dist/index.d.ts CHANGED
@@ -44,7 +44,7 @@ type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> & {
44
44
  onDrop?: <T extends File>(acceptedFiles: T[], fileRejections: FileRejection[], event: DropEvent) => void;
45
45
  onDropAccepted?: <T extends File>(files: T[], event: DropEvent) => void;
46
46
  onDropRejected?: (fileRejections: FileRejection[], event: DropEvent) => void;
47
- getFilesFromEvent?: (event: DropEvent) => Promise<Array<File | DataTransferItem>>;
47
+ getFilesFromEvent?: (event: DropEvent | Array<FileSystemFileHandle>) => Promise<Array<File | DataTransferItem>>;
48
48
  onFileDialogCancel?: () => void;
49
49
  onFileDialogOpen?: () => void;
50
50
  onError?: (err: Error) => void;
@@ -52,7 +52,7 @@ type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> & {
52
52
  useFsAccessApi?: boolean;
53
53
  autoFocus?: boolean;
54
54
  };
55
- type DropEvent = React.DragEvent<HTMLElement> | React.ChangeEvent<HTMLInputElement> | DragEvent | Event | Array<FileSystemFileHandle>;
55
+ type DropEvent = React.DragEvent<HTMLElement> | React.ChangeEvent<HTMLInputElement> | DragEvent | Event;
56
56
  interface DropzoneRef {
57
57
  open: () => void;
58
58
  }
package/dist/index.js CHANGED
@@ -148,11 +148,21 @@ function pickerOptionsFromAccept(accept) {
148
148
  }];
149
149
  }
150
150
  /**
151
- * Convert the `{accept}` dropzone prop to an array of MIME types/extensions.
151
+ * Convert the `{accept}` dropzone prop to a comma-separated accept attribute string.
152
+ *
153
+ * When `omitWildcardMimeTypesWithExtensions` is set, a wildcard MIME type (e.g. `image/*`)
154
+ * that is paired with explicit extensions is dropped in favour of those extensions. The
155
+ * accept attribute is an OR list, so leaving `image/*` in would make both the native file
156
+ * picker and the drop-time validator accept ANY file of that type, ignoring the extension
157
+ * restriction. The drag-time `isDragAccept` check keeps the wildcard because file names
158
+ * (and therefore extensions) aren't readable during a drag.
159
+ *
160
+ * See https://github.com/react-dropzone/react-dropzone/issues/1220
152
161
  */
153
- function acceptPropAsAcceptAttr(accept) {
162
+ function acceptPropAsAcceptAttr(accept, { omitWildcardMimeTypesWithExtensions = false } = {}) {
154
163
  if (isDefined(accept)) return Object.entries(accept).reduce((a, [mimeType, ext]) => {
155
- a.push(mimeType, ...ext);
164
+ if (omitWildcardMimeTypesWithExtensions && isMIMETypeWildcard(mimeType) && ext.some(isExt)) a.push(...ext);
165
+ else a.push(mimeType, ...ext);
156
166
  return a;
157
167
  }, []).filter((v) => isMIMEType(v) || isExt(v)).join(",");
158
168
  }
@@ -175,6 +185,12 @@ function isMIMEType(v) {
175
185
  return v === "audio/*" || v === "video/*" || v === "image/*" || v === "text/*" || v === "application/*" || /\w+\/[-+.\w]+/g.test(v);
176
186
  }
177
187
  /**
188
+ * Check if v is a wildcard MIME type (e.g. `image/*`).
189
+ */
190
+ function isMIMETypeWildcard(v) {
191
+ return v.endsWith("/*");
192
+ }
193
+ /**
178
194
  * Check if v is a file extension.
179
195
  */
180
196
  function isExt(v) {
@@ -237,6 +253,7 @@ const initialState = {
237
253
  function useDropzone(props = {}) {
238
254
  const { accept, disabled = false, getFilesFromEvent = fromEvent, maxSize = Number.POSITIVE_INFINITY, minSize = 0, multiple = true, maxFiles = 0, onDragEnter, onDragLeave, onDragOver, onDrop, onDropAccepted, onDropRejected, onFileDialogCancel, onFileDialogOpen, useFsAccessApi = false, autoFocus = false, preventDropOnDocument = true, noClick = false, noKeyboard = false, noDrag = false, noDragEventsBubbling = false, onError, validator } = props;
239
255
  const acceptAttr = useMemo(() => acceptPropAsAcceptAttr(accept), [accept]);
256
+ const inputAcceptAttr = useMemo(() => acceptPropAsAcceptAttr(accept, { omitWildcardMimeTypesWithExtensions: true }), [accept]);
240
257
  const pickerTypes = useMemo(() => pickerOptionsFromAccept(accept), [accept]);
241
258
  const onFileDialogOpenCb = useMemo(() => typeof onFileDialogOpen === "function" ? onFileDialogOpen : noop, [onFileDialogOpen]);
242
259
  const onFileDialogCancelCb = useMemo(() => typeof onFileDialogCancel === "function" ? onFileDialogCancel : noop, [onFileDialogCancel]);
@@ -412,7 +429,7 @@ function useDropzone(props = {}) {
412
429
  const acceptedFiles = [];
413
430
  const fileRejections = [];
414
431
  files.forEach((file) => {
415
- const [accepted, acceptError] = fileAccepted(file, acceptAttr);
432
+ const [accepted, acceptError] = fileAccepted(file, inputAcceptAttr);
416
433
  const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);
417
434
  const customErrors = validator ? validator(file) : null;
418
435
  if (accepted && sizeMatch && !customErrors) acceptedFiles.push(file);
@@ -445,7 +462,7 @@ function useDropzone(props = {}) {
445
462
  }, [
446
463
  dispatch,
447
464
  multiple,
448
- acceptAttr,
465
+ inputAcceptAttr,
449
466
  minSize,
450
467
  maxSize,
451
468
  maxFiles,
@@ -553,6 +570,7 @@ function useDropzone(props = {}) {
553
570
  role: typeof role === "string" && role !== "" ? role : "presentation",
554
571
  [refKey]: rootRef,
555
572
  ...!disabled && !noKeyboard ? { tabIndex: 0 } : {},
573
+ ...disabled ? { "aria-disabled": true } : {},
556
574
  ...rest
557
575
  }), [
558
576
  rootRef,
@@ -573,9 +591,10 @@ function useDropzone(props = {}) {
573
591
  }, []);
574
592
  const getInputProps = useMemo(() => ({ refKey = "ref", onChange, onClick, ...rest } = {}) => {
575
593
  return {
576
- accept: acceptAttr,
594
+ accept: inputAcceptAttr,
577
595
  multiple,
578
596
  type: "file",
597
+ "aria-label": "file upload",
579
598
  style: {
580
599
  border: 0,
581
600
  clip: "rect(0, 0, 0, 0)",
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\nexport function getTooLargeRejectionErr(maxSize: number): FileError {\n return {\n code: FILE_TOO_LARGE,\n message: `File is larger than ${maxSize} ${maxSize === 1 ? \"byte\" : \"bytes\"}`\n };\n}\n\nexport function getTooSmallRejectionErr(minSize: number): FileError {\n return {\n code: FILE_TOO_SMALL,\n message: `File is smaller than ${minSize} ${minSize === 1 ? \"byte\" : \"bytes\"}`\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 an array of MIME types/extensions.\n */\nexport function acceptPropAsAcceptAttr(accept?: Accept): string | undefined {\n if (isDefined(accept)) {\n return (\n Object.entries(accept)\n .reduce<string[]>((a, [mimeType, ext]) => {\n a.push(mimeType, ...ext);\n return a;\n }, [])\n // Silently discard invalid entries as pickerOptionsFromAccept warns about these\n .filter(v => isMIMEType(v) || isExt(v))\n .join(\",\")\n );\n }\n\n return undefined;\n}\n\n/**\n * Check if v is an exception caused by aborting a request (e.g window.showOpenFilePicker()).\n */\nexport function isAbort(v: any): boolean {\n return v instanceof DOMException && (v.name === \"AbortError\" || v.code === v.ABORT_ERR);\n}\n\n/**\n * Check if v is a security error.\n */\nexport function isSecurityError(v: any): boolean {\n return v instanceof DOMException && (v.name === \"SecurityError\" || v.code === v.SECURITY_ERR);\n}\n\n/**\n * Check if v is a MIME type string.\n */\nexport function isMIMEType(v: string): boolean {\n return (\n v === \"audio/*\" ||\n v === \"video/*\" ||\n v === \"image/*\" ||\n v === \"text/*\" ||\n v === \"application/*\" ||\n /\\w+\\/[-+.\\w]+/g.test(v)\n );\n}\n\n/**\n * Check if v is a file extension.\n */\nexport function isExt(v: string): boolean {\n return /^.*\\.[\\w]+$/.test(v);\n}\n","import {fromEvent} from \"file-selector\";\nimport type {FileWithPath} from \"file-selector\";\nimport type * as React from \"react\";\nimport {forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useReducer, useRef} from \"react\";\nimport {\n acceptPropAsAcceptAttr,\n allFilesAccepted,\n canUseFileSystemAccessAPI,\n composeEventHandlers,\n ErrorCode,\n fileAccepted,\n fileMatchSize,\n isAbort,\n isEvtWithFiles,\n isIeOrEdge,\n isPropagationStopped,\n isSecurityError,\n onDocumentDragOver,\n pickerOptionsFromAccept,\n TOO_MANY_FILES_REJECTION\n} from \"./utils\";\nimport type {Accept, FileError} from \"./utils\";\n\nexport type {Accept, FileError, FileWithPath};\nexport {ErrorCode};\n\nexport interface DropzoneProps extends DropzoneOptions {\n children?: (state: DropzoneState) => React.ReactElement;\n}\n\nexport interface FileRejection {\n file: FileWithPath;\n errors: readonly FileError[];\n}\n\ntype SharedProps = \"multiple\" | \"onDragEnter\" | \"onDragOver\" | \"onDragLeave\";\n\nexport type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> & {\n accept?: Accept;\n minSize?: number;\n maxSize?: number;\n maxFiles?: number;\n preventDropOnDocument?: boolean;\n noClick?: boolean;\n noKeyboard?: boolean;\n noDrag?: boolean;\n noDragEventsBubbling?: boolean;\n disabled?: boolean;\n onDrop?: <T extends File>(acceptedFiles: T[], fileRejections: FileRejection[], event: DropEvent) => void;\n onDropAccepted?: <T extends File>(files: T[], event: DropEvent) => void;\n onDropRejected?: (fileRejections: FileRejection[], event: DropEvent) => void;\n getFilesFromEvent?: (event: DropEvent) => Promise<Array<File | DataTransferItem>>;\n onFileDialogCancel?: () => void;\n onFileDialogOpen?: () => void;\n onError?: (err: Error) => void;\n validator?: <T extends File>(file: T) => FileError | readonly FileError[] | null;\n useFsAccessApi?: boolean;\n autoFocus?: boolean;\n};\n\nexport type DropEvent =\n | React.DragEvent<HTMLElement>\n | React.ChangeEvent<HTMLInputElement>\n | DragEvent\n | Event\n | Array<FileSystemFileHandle>;\n\nexport interface DropzoneRef {\n open: () => void;\n}\n\nexport type DropzoneState = DropzoneRef & {\n isFocused: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragGlobal: boolean;\n isFileDialogActive: boolean;\n acceptedFiles: readonly FileWithPath[];\n fileRejections: readonly FileRejection[];\n rootRef: React.RefObject<HTMLElement>;\n inputRef: React.RefObject<HTMLInputElement>;\n getRootProps: <T extends DropzoneRootProps>(props?: T) => T;\n getInputProps: <T extends DropzoneInputProps>(props?: T) => T;\n};\n\nexport interface DropzoneRootProps extends React.HTMLAttributes<HTMLElement> {\n refKey?: string;\n [key: string]: any;\n}\n\nexport interface DropzoneInputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n refKey?: string;\n}\n\n/**\n * Convenience wrapper component for the `useDropzone` hook\n *\n * ```jsx\n * <Dropzone>\n * {({getRootProps, getInputProps}) => (\n * <div {...getRootProps()}>\n * <input {...getInputProps()} />\n * <p>Drag 'n' drop some files here, or click to select files</p>\n * </div>\n * )}\n * </Dropzone>\n * ```\n */\nconst Dropzone: React.ForwardRefExoticComponent<DropzoneProps & React.RefAttributes<DropzoneRef>> = forwardRef<\n DropzoneRef,\n DropzoneProps\n>(({children, ...params}, ref) => {\n const {open, ...props} = useDropzone(params);\n\n useImperativeHandle(ref, () => ({open}), [open]);\n\n return <>{children?.({...props, open})}</>;\n});\n\nDropzone.displayName = \"Dropzone\";\n\nexport default Dropzone;\n\ninterface DropzoneInternalState {\n isFocused: boolean;\n isFileDialogActive: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragGlobal: boolean;\n acceptedFiles: FileWithPath[];\n fileRejections: FileRejection[];\n}\n\nconst initialState: DropzoneInternalState = {\n isFocused: false,\n isFileDialogActive: false,\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false,\n isDragGlobal: false,\n acceptedFiles: [],\n fileRejections: []\n};\n\n/**\n * A React hook that creates a drag 'n' drop area.\n *\n * ```jsx\n * function MyDropzone(props) {\n * const {getRootProps, getInputProps} = useDropzone({\n * onDrop: acceptedFiles => {\n * // do something with the File objects, e.g. upload to some server\n * }\n * });\n * return (\n * <div {...getRootProps()}>\n * <input {...getInputProps()} />\n * <p>Drag and drop some files here, or click to select files</p>\n * </div>\n * )\n * }\n * ```\n */\nexport function useDropzone(props: DropzoneOptions = {}): DropzoneState {\n const {\n accept,\n disabled = false,\n getFilesFromEvent = fromEvent,\n maxSize = Number.POSITIVE_INFINITY,\n minSize = 0,\n multiple = true,\n maxFiles = 0,\n onDragEnter,\n onDragLeave,\n onDragOver,\n onDrop,\n onDropAccepted,\n onDropRejected,\n onFileDialogCancel,\n onFileDialogOpen,\n useFsAccessApi = false,\n autoFocus = false,\n preventDropOnDocument = true,\n noClick = false,\n noKeyboard = false,\n noDrag = false,\n noDragEventsBubbling = false,\n onError,\n validator\n } = props;\n\n const acceptAttr = useMemo(() => acceptPropAsAcceptAttr(accept), [accept]);\n const pickerTypes = useMemo(() => pickerOptionsFromAccept(accept), [accept]);\n\n const onFileDialogOpenCb = useMemo<(...args: any[]) => void>(\n () => (typeof onFileDialogOpen === \"function\" ? onFileDialogOpen : noop),\n [onFileDialogOpen]\n );\n const onFileDialogCancelCb = useMemo<(...args: any[]) => void>(\n () => (typeof onFileDialogCancel === \"function\" ? onFileDialogCancel : noop),\n [onFileDialogCancel]\n );\n\n const rootRef = useRef<HTMLElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [state, dispatch] = useReducer(reducer, initialState);\n const {isFocused, isFileDialogActive} = state;\n\n const fsAccessApiWorksRef = useRef(\n typeof window !== \"undefined\" && window.isSecureContext && useFsAccessApi && canUseFileSystemAccessAPI()\n );\n\n // Update file dialog active state when the window is focused on\n const onWindowFocus = () => {\n // Execute the timeout only if the file dialog is opened in the browser\n if (!fsAccessApiWorksRef.current && isFileDialogActive) {\n setTimeout(() => {\n if (inputRef.current) {\n const {files} = inputRef.current;\n\n if (!files?.length) {\n dispatch({type: \"closeDialog\"});\n onFileDialogCancelCb();\n }\n }\n }, 300);\n }\n };\n useEffect(() => {\n window.addEventListener(\"focus\", onWindowFocus, false);\n return () => {\n window.removeEventListener(\"focus\", onWindowFocus, false);\n };\n }, [inputRef, isFileDialogActive, onFileDialogCancelCb, fsAccessApiWorksRef]);\n\n const dragTargetsRef = useRef<EventTarget[]>([]);\n const globalDragTargetsRef = useRef<EventTarget[]>([]);\n const onDocumentDrop = (event: DragEvent) => {\n if (rootRef.current && event.target && rootRef.current.contains(event.target as Node)) {\n // If we intercepted an event for our instance, let it propagate down to the instance's onDrop handler\n return;\n }\n event.preventDefault();\n dragTargetsRef.current = [];\n };\n\n useEffect(() => {\n if (preventDropOnDocument) {\n document.addEventListener(\"dragover\", onDocumentDragOver, false);\n document.addEventListener(\"drop\", onDocumentDrop, false);\n }\n\n return () => {\n if (preventDropOnDocument) {\n document.removeEventListener(\"dragover\", onDocumentDragOver);\n document.removeEventListener(\"drop\", onDocumentDrop);\n }\n };\n }, [rootRef, preventDropOnDocument]);\n\n // Track global drag state for document-level drag events\n useEffect(() => {\n const onDocumentDragEnter = (event: DragEvent) => {\n if (event.target) {\n globalDragTargetsRef.current = [...globalDragTargetsRef.current, event.target];\n }\n\n if (isEvtWithFiles(event)) {\n dispatch({isDragGlobal: true, type: \"setDragGlobal\"});\n }\n };\n\n const onDocumentDragLeave = (event: DragEvent) => {\n // Only deactivate once we've left all children\n globalDragTargetsRef.current = globalDragTargetsRef.current.filter(el => el !== event.target && el !== null);\n\n if (globalDragTargetsRef.current.length > 0) {\n return;\n }\n\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDragEnd = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDropGlobal = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n document.addEventListener(\"dragenter\", onDocumentDragEnter, false);\n document.addEventListener(\"dragleave\", onDocumentDragLeave, false);\n document.addEventListener(\"dragend\", onDocumentDragEnd, false);\n document.addEventListener(\"drop\", onDocumentDropGlobal, false);\n\n return () => {\n document.removeEventListener(\"dragenter\", onDocumentDragEnter);\n document.removeEventListener(\"dragleave\", onDocumentDragLeave);\n document.removeEventListener(\"dragend\", onDocumentDragEnd);\n document.removeEventListener(\"drop\", onDocumentDropGlobal);\n };\n }, [rootRef]);\n\n // Auto focus the root when autoFocus is true\n useEffect(() => {\n if (!disabled && autoFocus && rootRef.current) {\n rootRef.current.focus();\n }\n return () => {};\n }, [rootRef, autoFocus, disabled]);\n\n const onErrCb = useCallback(\n (e: Error) => {\n if (onError) {\n onError(e);\n } else {\n // Let the user know something's gone wrong if they haven't provided the onError cb.\n console.error(e);\n }\n },\n [onError]\n );\n\n const onDragEnterCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n dragTargetsRef.current = [...dragTargetsRef.current, event.target];\n\n if (isEvtWithFiles(event)) {\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n return;\n }\n\n const fileCount = files.length;\n const isDragAccept =\n fileCount > 0 &&\n allFilesAccepted({\n files: files as File[],\n accept: acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n });\n const isDragReject = fileCount > 0 && !isDragAccept;\n\n dispatch({\n isDragAccept,\n isDragReject,\n isDragActive: true,\n type: \"setDraggedFiles\"\n });\n\n if (onDragEnter) {\n onDragEnter(event);\n }\n })\n .catch(e => onErrCb(e));\n }\n },\n [\n getFilesFromEvent,\n onDragEnter,\n onErrCb,\n noDragEventsBubbling,\n acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n ]\n );\n\n const onDragOverCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n const hasFiles = isEvtWithFiles(event);\n if (hasFiles && event.dataTransfer) {\n try {\n event.dataTransfer.dropEffect = \"copy\";\n } catch {\n /* no-op */\n }\n }\n\n if (hasFiles && onDragOver) {\n onDragOver(event);\n }\n\n return false;\n },\n [onDragOver, noDragEventsBubbling]\n );\n\n const onDragLeaveCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n // Only deactivate once the dropzone and all children have been left\n const targets = dragTargetsRef.current.filter(target => rootRef.current?.contains(target as Node));\n // Make sure to remove a target present multiple times only once\n // (Firefox may fire dragenter/dragleave multiple times on the same element)\n const targetIdx = targets.indexOf(event.target);\n if (targetIdx !== -1) {\n targets.splice(targetIdx, 1);\n }\n dragTargetsRef.current = targets;\n if (targets.length > 0) {\n return;\n }\n\n dispatch({\n type: \"setDraggedFiles\",\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false\n });\n\n if (isEvtWithFiles(event) && onDragLeave) {\n onDragLeave(event);\n }\n },\n [rootRef, onDragLeave, noDragEventsBubbling]\n );\n\n const setFiles = useCallback(\n (files: FileWithPath[], event: any) => {\n const acceptedFiles: FileWithPath[] = [];\n const fileRejections: FileRejection[] = [];\n\n files.forEach(file => {\n const [accepted, acceptError] = fileAccepted(file, acceptAttr);\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({file, errors: errors.filter((e): e is FileError => e != null)});\n }\n });\n\n if ((!multiple && acceptedFiles.length > 1) || (multiple && maxFiles >= 1 && acceptedFiles.length > maxFiles)) {\n // Reject everything and empty accepted files\n acceptedFiles.forEach(file => {\n fileRejections.push({file, errors: [TOO_MANY_FILES_REJECTION]});\n });\n acceptedFiles.splice(0);\n }\n\n dispatch({\n acceptedFiles,\n fileRejections,\n type: \"setFiles\"\n });\n\n if (onDrop) {\n onDrop(acceptedFiles, fileRejections, event);\n }\n\n if (fileRejections.length > 0 && onDropRejected) {\n onDropRejected(fileRejections, event);\n }\n\n if (acceptedFiles.length > 0 && onDropAccepted) {\n onDropAccepted(acceptedFiles, event);\n }\n },\n [dispatch, multiple, acceptAttr, minSize, maxSize, maxFiles, onDrop, onDropAccepted, onDropRejected, validator]\n );\n\n const onDropCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n dragTargetsRef.current = [];\n\n if (isEvtWithFiles(event)) {\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n return;\n }\n setFiles(files as FileWithPath[], event);\n })\n .catch(e => onErrCb(e));\n }\n dispatch({type: \"reset\"});\n },\n [getFilesFromEvent, setFiles, onErrCb, noDragEventsBubbling]\n );\n\n // Fn for opening the file dialog programmatically\n const openFileDialog = useCallback(() => {\n // No point to use FS access APIs if context is not secure\n // https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#feature_detection\n if (fsAccessApiWorksRef.current) {\n dispatch({type: \"openDialog\"});\n onFileDialogOpenCb();\n // https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker\n const opts = {\n multiple,\n types: pickerTypes\n };\n (window as any)\n .showOpenFilePicker(opts)\n .then((handles: any) => getFilesFromEvent(handles))\n .then((files: Array<File | DataTransferItem>) => {\n setFiles(files as FileWithPath[], null);\n dispatch({type: \"closeDialog\"});\n })\n .catch((e: any) => {\n // AbortError means the user canceled\n if (isAbort(e)) {\n onFileDialogCancelCb(e);\n dispatch({type: \"closeDialog\"});\n } else if (isSecurityError(e)) {\n fsAccessApiWorksRef.current = false;\n // CORS, so cannot use this API\n // Try using the input\n if (inputRef.current) {\n inputRef.current.value = \"\";\n inputRef.current.click();\n } else {\n onErrCb(\n new Error(\n \"Cannot open the file picker because the https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API is not supported and no <input> was provided.\"\n )\n );\n }\n } else {\n onErrCb(e);\n }\n });\n return;\n }\n\n if (inputRef.current) {\n dispatch({type: \"openDialog\"});\n onFileDialogOpenCb();\n inputRef.current.value = \"\";\n inputRef.current.click();\n }\n }, [dispatch, onFileDialogOpenCb, onFileDialogCancelCb, useFsAccessApi, setFiles, onErrCb, pickerTypes, multiple]);\n\n // Cb to open the file dialog when SPACE/ENTER occurs on the dropzone\n const onKeyDownCb = useCallback(\n (event: any) => {\n // Ignore keyboard events bubbling up the DOM tree\n if (!rootRef.current?.isEqualNode(event.target)) {\n return;\n }\n\n if (event.key === \" \" || event.key === \"Enter\" || event.keyCode === 32 || event.keyCode === 13) {\n event.preventDefault();\n openFileDialog();\n }\n },\n [rootRef, openFileDialog]\n );\n\n // Update focus state for the dropzone\n const onFocusCb = useCallback(() => {\n dispatch({type: \"focus\"});\n }, []);\n const onBlurCb = useCallback(() => {\n dispatch({type: \"blur\"});\n }, []);\n\n // Cb to open the file dialog when click occurs on the dropzone\n const onClickCb = useCallback(() => {\n if (noClick) {\n return;\n }\n\n // In IE11/Edge the file-browser dialog is blocking, therefore, use setTimeout()\n // to ensure React can handle state changes\n // See: https://github.com/react-dropzone/react-dropzone/issues/450\n if (isIeOrEdge()) {\n setTimeout(openFileDialog, 0);\n } else {\n openFileDialog();\n }\n }, [noClick, openFileDialog]);\n\n const composeHandler = (fn: any) => {\n return disabled ? null : fn;\n };\n\n const composeKeyboardHandler = (fn: any) => {\n return noKeyboard ? null : composeHandler(fn);\n };\n\n const composeDragHandler = (fn: any) => {\n return noDrag ? null : composeHandler(fn);\n };\n\n const stopPropagation = (event: any) => {\n if (noDragEventsBubbling) {\n event.stopPropagation();\n }\n };\n\n const getRootProps = useMemo(\n () =>\n ({\n refKey = \"ref\",\n role,\n onKeyDown,\n onFocus,\n onBlur,\n onClick,\n onDragEnter,\n onDragOver,\n onDragLeave,\n onDrop,\n ...rest\n }: DropzoneRootProps = {}) => ({\n onKeyDown: composeKeyboardHandler(composeEventHandlers(onKeyDown, onKeyDownCb)),\n onFocus: composeKeyboardHandler(composeEventHandlers(onFocus, onFocusCb)),\n onBlur: composeKeyboardHandler(composeEventHandlers(onBlur, onBlurCb)),\n onClick: composeHandler(composeEventHandlers(onClick, onClickCb)),\n onDragEnter: composeDragHandler(composeEventHandlers(onDragEnter, onDragEnterCb)),\n onDragOver: composeDragHandler(composeEventHandlers(onDragOver, onDragOverCb)),\n onDragLeave: composeDragHandler(composeEventHandlers(onDragLeave, onDragLeaveCb)),\n onDrop: composeDragHandler(composeEventHandlers(onDrop, onDropCb)),\n role: typeof role === \"string\" && role !== \"\" ? role : \"presentation\",\n [refKey]: rootRef,\n ...(!disabled && !noKeyboard ? {tabIndex: 0} : {}),\n ...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: acceptAttr,\n multiple,\n type: \"file\",\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\nexport function getTooLargeRejectionErr(maxSize: number): FileError {\n return {\n code: FILE_TOO_LARGE,\n message: `File is larger than ${maxSize} ${maxSize === 1 ? \"byte\" : \"bytes\"}`\n };\n}\n\nexport function getTooSmallRejectionErr(minSize: number): FileError {\n return {\n code: FILE_TOO_SMALL,\n message: `File is smaller than ${minSize} ${minSize === 1 ? \"byte\" : \"bytes\"}`\n };\n}\n\nexport const TOO_MANY_FILES_REJECTION: FileError = {\n code: TOO_MANY_FILES,\n message: \"Too many files\"\n};\n\n/**\n * Check if the given file is a DataTransferItem with an empty type.\n *\n * During drag events, browsers may return DataTransferItem objects instead of File objects.\n * Some browsers (e.g., Chrome) return an empty MIME type for certain file types (like .md files)\n * on DataTransferItem during drag events, even though the type is correctly set during drop.\n */\nexport function isDataTransferItemWithEmptyType(file: File | DataTransferItem): boolean {\n return file.type === \"\" && typeof (file as DataTransferItem).getAsFile === \"function\";\n}\n\n/**\n * Check if file is accepted.\n *\n * Firefox versions prior to 53 return a bogus MIME type for every file drag,\n * so dragovers with that MIME type will always be accepted.\n *\n * Chrome/other browsers may return an empty MIME type for files during drag events,\n * so we accept those as well (we'll validate properly on drop).\n */\nexport function fileAccepted(file: File, accept?: string): [boolean, FileError | null] {\n const isAcceptable =\n file.type === \"application/x-moz-file\" || accepts(file, accept ?? \"\") || isDataTransferItemWithEmptyType(file);\n return [isAcceptable, isAcceptable ? null : getInvalidTypeRejectionErr(accept)];\n}\n\nexport function fileMatchSize(\n file: {size?: number | null},\n minSize?: number,\n maxSize?: number\n): [boolean, FileError | null] {\n if (isDefined(file.size)) {\n if (isDefined(minSize) && isDefined(maxSize)) {\n if (file.size > maxSize) return [false, getTooLargeRejectionErr(maxSize)];\n if (file.size < minSize) return [false, getTooSmallRejectionErr(minSize)];\n } else if (isDefined(minSize) && file.size < minSize) {\n return [false, getTooSmallRejectionErr(minSize)];\n } else if (isDefined(maxSize) && file.size > maxSize) {\n return [false, getTooLargeRejectionErr(maxSize)];\n }\n }\n return [true, null];\n}\n\nfunction isDefined<T>(value: T): value is NonNullable<T> {\n return value !== undefined && value !== null;\n}\n\nexport function allFilesAccepted({\n files,\n accept,\n minSize,\n maxSize,\n multiple,\n maxFiles = 0,\n validator\n}: {\n files: File[];\n accept?: string;\n minSize?: number;\n maxSize?: number;\n multiple?: boolean;\n maxFiles?: number;\n validator?: (file: File) => FileError | readonly FileError[] | null;\n}): boolean {\n if ((!multiple && files.length > 1) || (multiple && maxFiles >= 1 && files.length > maxFiles)) {\n return false;\n }\n\n return files.every(file => {\n const [accepted] = fileAccepted(file, accept);\n const [sizeMatch] = fileMatchSize(file, minSize, maxSize);\n const customErrors = validator ? validator(file) : null;\n return accepted && sizeMatch && !customErrors;\n });\n}\n\n// React's synthetic events has event.isPropagationStopped,\n// but to remain compatibility with other libs (Preact) fall back\n// to check event.cancelBubble\nexport function isPropagationStopped(event: any): boolean {\n if (typeof event.isPropagationStopped === \"function\") {\n return event.isPropagationStopped();\n } else if (typeof event.cancelBubble !== \"undefined\") {\n return event.cancelBubble;\n }\n return false;\n}\n\nexport function isEvtWithFiles(event: any): boolean {\n if (!event.dataTransfer) {\n return !!event.target && !!event.target.files;\n }\n // https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/types\n // https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#file\n return Array.prototype.some.call(\n event.dataTransfer.types,\n (type: string) => type === \"Files\" || type === \"application/x-moz-file\"\n );\n}\n\nexport function isKindFile(item: any): boolean {\n return typeof item === \"object\" && item !== null && item.kind === \"file\";\n}\n\n// allow the entire document to be a drag target\nexport function onDocumentDragOver(event: Event): void {\n event.preventDefault();\n}\n\nfunction isIe(userAgent: string): boolean {\n return userAgent.indexOf(\"MSIE\") !== -1 || userAgent.indexOf(\"Trident/\") !== -1;\n}\n\nfunction isEdge(userAgent: string): boolean {\n return userAgent.indexOf(\"Edge/\") !== -1;\n}\n\nexport function isIeOrEdge(userAgent: string = window.navigator.userAgent): boolean {\n return isIe(userAgent) || isEdge(userAgent);\n}\n\n/**\n * This is intended to be used to compose event handlers.\n * They are executed in order until one of them calls `event.isPropagationStopped()`.\n * Note that the check is done on the first invoke too,\n * meaning that if propagation was stopped before invoking the fns,\n * no handlers will be executed.\n */\nexport function composeEventHandlers(\n ...fns: Array<((event: any, ...args: any[]) => void) | null | undefined>\n): (event: any, ...args: any[]) => boolean {\n return (event: any, ...args: any[]) =>\n fns.some(fn => {\n if (!isPropagationStopped(event) && fn) {\n fn(event, ...args);\n }\n return isPropagationStopped(event);\n });\n}\n\n/**\n * canUseFileSystemAccessAPI checks if the File System Access API is supported by the browser.\n */\nexport function canUseFileSystemAccessAPI(): boolean {\n return \"showOpenFilePicker\" in window;\n}\n\n/**\n * Convert the `{accept}` dropzone prop to the `{types}` option for showOpenFilePicker.\n */\nexport function pickerOptionsFromAccept(accept?: Accept): Array<{description: string; accept: Accept}> | undefined {\n if (isDefined(accept)) {\n const acceptForPicker = Object.entries(accept)\n .filter(([mimeType, ext]) => {\n let ok = true;\n\n if (!isMIMEType(mimeType)) {\n console.warn(\n `Skipped \"${mimeType}\" because it is not a valid MIME type. Check https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types for a list of valid MIME types.`\n );\n ok = false;\n }\n\n if (!Array.isArray(ext) || !ext.every(isExt)) {\n console.warn(`Skipped \"${mimeType}\" because an invalid file extension was provided.`);\n ok = false;\n }\n\n return ok;\n })\n .reduce<Accept>((agg, [mimeType, ext]) => {\n agg[mimeType] = ext;\n return agg;\n }, {});\n return [\n {\n // description is required due to https://crbug.com/1264708\n description: \"Files\",\n accept: acceptForPicker\n }\n ];\n }\n return undefined;\n}\n\n/**\n * Convert the `{accept}` dropzone prop to a comma-separated accept attribute string.\n *\n * When `omitWildcardMimeTypesWithExtensions` is set, a wildcard MIME type (e.g. `image/*`)\n * that is paired with explicit extensions is dropped in favour of those extensions. The\n * accept attribute is an OR list, so leaving `image/*` in would make both the native file\n * picker and the drop-time validator accept ANY file of that type, ignoring the extension\n * restriction. The drag-time `isDragAccept` check keeps the wildcard because file names\n * (and therefore extensions) aren't readable during a drag.\n *\n * See https://github.com/react-dropzone/react-dropzone/issues/1220\n */\nexport function acceptPropAsAcceptAttr(\n accept?: Accept,\n {omitWildcardMimeTypesWithExtensions = false}: {omitWildcardMimeTypesWithExtensions?: boolean} = {}\n): string | undefined {\n if (isDefined(accept)) {\n return (\n Object.entries(accept)\n .reduce<string[]>((a, [mimeType, ext]) => {\n if (omitWildcardMimeTypesWithExtensions && isMIMETypeWildcard(mimeType) && ext.some(isExt)) {\n a.push(...ext);\n } else {\n a.push(mimeType, ...ext);\n }\n return a;\n }, [])\n // Silently discard invalid entries as pickerOptionsFromAccept warns about these\n .filter(v => isMIMEType(v) || isExt(v))\n .join(\",\")\n );\n }\n\n return undefined;\n}\n\n/**\n * Check if v is an exception caused by aborting a request (e.g window.showOpenFilePicker()).\n */\nexport function isAbort(v: any): boolean {\n return v instanceof DOMException && (v.name === \"AbortError\" || v.code === v.ABORT_ERR);\n}\n\n/**\n * Check if v is a security error.\n */\nexport function isSecurityError(v: any): boolean {\n return v instanceof DOMException && (v.name === \"SecurityError\" || v.code === v.SECURITY_ERR);\n}\n\n/**\n * Check if v is a MIME type string.\n */\nexport function isMIMEType(v: string): boolean {\n return (\n v === \"audio/*\" ||\n v === \"video/*\" ||\n v === \"image/*\" ||\n v === \"text/*\" ||\n v === \"application/*\" ||\n /\\w+\\/[-+.\\w]+/g.test(v)\n );\n}\n\n/**\n * Check if v is a wildcard MIME type (e.g. `image/*`).\n */\nexport function isMIMETypeWildcard(v: string): boolean {\n return v.endsWith(\"/*\");\n}\n\n/**\n * Check if v is a file extension.\n */\nexport function isExt(v: string): boolean {\n return /^.*\\.[\\w]+$/.test(v);\n}\n","import {fromEvent} from \"file-selector\";\nimport type {FileWithPath} from \"file-selector\";\nimport type * as React from \"react\";\nimport {forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useReducer, useRef} from \"react\";\nimport {\n acceptPropAsAcceptAttr,\n allFilesAccepted,\n canUseFileSystemAccessAPI,\n composeEventHandlers,\n ErrorCode,\n fileAccepted,\n fileMatchSize,\n isAbort,\n isEvtWithFiles,\n isIeOrEdge,\n isPropagationStopped,\n isSecurityError,\n onDocumentDragOver,\n pickerOptionsFromAccept,\n TOO_MANY_FILES_REJECTION\n} from \"./utils\";\nimport type {Accept, FileError} from \"./utils\";\n\nexport type {Accept, FileError, FileWithPath};\nexport {ErrorCode};\n\nexport interface DropzoneProps extends DropzoneOptions {\n children?: (state: DropzoneState) => React.ReactElement;\n}\n\nexport interface FileRejection {\n file: FileWithPath;\n errors: readonly FileError[];\n}\n\ntype SharedProps = \"multiple\" | \"onDragEnter\" | \"onDragOver\" | \"onDragLeave\";\n\nexport type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> & {\n accept?: Accept;\n minSize?: number;\n maxSize?: number;\n maxFiles?: number;\n preventDropOnDocument?: boolean;\n noClick?: boolean;\n noKeyboard?: boolean;\n noDrag?: boolean;\n noDragEventsBubbling?: boolean;\n disabled?: boolean;\n onDrop?: <T extends File>(acceptedFiles: T[], fileRejections: FileRejection[], event: DropEvent) => void;\n onDropAccepted?: <T extends File>(files: T[], event: DropEvent) => void;\n onDropRejected?: (fileRejections: FileRejection[], event: DropEvent) => void;\n getFilesFromEvent?: (event: DropEvent | Array<FileSystemFileHandle>) => Promise<Array<File | DataTransferItem>>;\n onFileDialogCancel?: () => void;\n onFileDialogOpen?: () => void;\n onError?: (err: Error) => void;\n validator?: <T extends File>(file: T) => FileError | readonly FileError[] | null;\n useFsAccessApi?: boolean;\n autoFocus?: boolean;\n};\n\nexport type DropEvent = React.DragEvent<HTMLElement> | React.ChangeEvent<HTMLInputElement> | DragEvent | Event;\n\nexport interface DropzoneRef {\n open: () => void;\n}\n\nexport type DropzoneState = DropzoneRef & {\n isFocused: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragGlobal: boolean;\n isFileDialogActive: boolean;\n acceptedFiles: readonly FileWithPath[];\n fileRejections: readonly FileRejection[];\n rootRef: React.RefObject<HTMLElement>;\n inputRef: React.RefObject<HTMLInputElement>;\n getRootProps: <T extends DropzoneRootProps>(props?: T) => T;\n getInputProps: <T extends DropzoneInputProps>(props?: T) => T;\n};\n\nexport interface DropzoneRootProps extends React.HTMLAttributes<HTMLElement> {\n refKey?: string;\n [key: string]: any;\n}\n\nexport interface DropzoneInputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n refKey?: string;\n}\n\n/**\n * Convenience wrapper component for the `useDropzone` hook\n *\n * ```jsx\n * <Dropzone>\n * {({getRootProps, getInputProps}) => (\n * <div {...getRootProps()}>\n * <input {...getInputProps()} />\n * <p>Drag 'n' drop some files here, or click to select files</p>\n * </div>\n * )}\n * </Dropzone>\n * ```\n */\nconst Dropzone: React.ForwardRefExoticComponent<DropzoneProps & React.RefAttributes<DropzoneRef>> = forwardRef<\n DropzoneRef,\n DropzoneProps\n>(({children, ...params}, ref) => {\n const {open, ...props} = useDropzone(params);\n\n useImperativeHandle(ref, () => ({open}), [open]);\n\n return <>{children?.({...props, open})}</>;\n});\n\nDropzone.displayName = \"Dropzone\";\n\nexport default Dropzone;\n\ninterface DropzoneInternalState {\n isFocused: boolean;\n isFileDialogActive: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragGlobal: boolean;\n acceptedFiles: FileWithPath[];\n fileRejections: FileRejection[];\n}\n\nconst initialState: DropzoneInternalState = {\n isFocused: false,\n isFileDialogActive: false,\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false,\n isDragGlobal: false,\n acceptedFiles: [],\n fileRejections: []\n};\n\n/**\n * A React hook that creates a drag 'n' drop area.\n *\n * ```jsx\n * function MyDropzone(props) {\n * const {getRootProps, getInputProps} = useDropzone({\n * onDrop: acceptedFiles => {\n * // do something with the File objects, e.g. upload to some server\n * }\n * });\n * return (\n * <div {...getRootProps()}>\n * <input {...getInputProps()} />\n * <p>Drag and drop some files here, or click to select files</p>\n * </div>\n * )\n * }\n * ```\n */\nexport function useDropzone(props: DropzoneOptions = {}): DropzoneState {\n const {\n accept,\n disabled = false,\n getFilesFromEvent = fromEvent,\n maxSize = Number.POSITIVE_INFINITY,\n minSize = 0,\n multiple = true,\n maxFiles = 0,\n onDragEnter,\n onDragLeave,\n onDragOver,\n onDrop,\n onDropAccepted,\n onDropRejected,\n onFileDialogCancel,\n onFileDialogOpen,\n useFsAccessApi = false,\n autoFocus = false,\n preventDropOnDocument = true,\n noClick = false,\n noKeyboard = false,\n noDrag = false,\n noDragEventsBubbling = false,\n onError,\n validator\n } = props;\n\n // `acceptAttr` keeps wildcard MIME types (e.g. `image/*`) so the drag-time\n // `isDragAccept`/`isDragReject` check can react to a file's MIME type - file names\n // (hence extensions) aren't readable during a drag.\n const acceptAttr = useMemo(() => acceptPropAsAcceptAttr(accept), [accept]);\n // `inputAcceptAttr` drops a wildcard MIME type when it is paired with extensions, so the\n // native picker and drop-time validation enforce the extensions instead of accepting any\n // file of that type. See https://github.com/react-dropzone/react-dropzone/issues/1220\n const inputAcceptAttr = useMemo(\n () =>\n acceptPropAsAcceptAttr(accept, {\n omitWildcardMimeTypesWithExtensions: true\n }),\n [accept]\n );\n const pickerTypes = useMemo(() => pickerOptionsFromAccept(accept), [accept]);\n\n const onFileDialogOpenCb = useMemo<(...args: any[]) => void>(\n () => (typeof onFileDialogOpen === \"function\" ? onFileDialogOpen : noop),\n [onFileDialogOpen]\n );\n const onFileDialogCancelCb = useMemo<(...args: any[]) => void>(\n () => (typeof onFileDialogCancel === \"function\" ? onFileDialogCancel : noop),\n [onFileDialogCancel]\n );\n\n const rootRef = useRef<HTMLElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [state, dispatch] = useReducer(reducer, initialState);\n const {isFocused, isFileDialogActive} = state;\n\n const fsAccessApiWorksRef = useRef(\n typeof window !== \"undefined\" && window.isSecureContext && useFsAccessApi && canUseFileSystemAccessAPI()\n );\n\n // Update file dialog active state when the window is focused on\n const onWindowFocus = () => {\n // Execute the timeout only if the file dialog is opened in the browser\n if (!fsAccessApiWorksRef.current && isFileDialogActive) {\n setTimeout(() => {\n if (inputRef.current) {\n const {files} = inputRef.current;\n\n if (!files?.length) {\n dispatch({type: \"closeDialog\"});\n onFileDialogCancelCb();\n }\n }\n }, 300);\n }\n };\n useEffect(() => {\n window.addEventListener(\"focus\", onWindowFocus, false);\n return () => {\n window.removeEventListener(\"focus\", onWindowFocus, false);\n };\n }, [inputRef, isFileDialogActive, onFileDialogCancelCb, fsAccessApiWorksRef]);\n\n const dragTargetsRef = useRef<EventTarget[]>([]);\n const globalDragTargetsRef = useRef<EventTarget[]>([]);\n const onDocumentDrop = (event: DragEvent) => {\n if (rootRef.current && event.target && rootRef.current.contains(event.target as Node)) {\n // If we intercepted an event for our instance, let it propagate down to the instance's onDrop handler\n return;\n }\n event.preventDefault();\n dragTargetsRef.current = [];\n };\n\n useEffect(() => {\n if (preventDropOnDocument) {\n document.addEventListener(\"dragover\", onDocumentDragOver, false);\n document.addEventListener(\"drop\", onDocumentDrop, false);\n }\n\n return () => {\n if (preventDropOnDocument) {\n document.removeEventListener(\"dragover\", onDocumentDragOver);\n document.removeEventListener(\"drop\", onDocumentDrop);\n }\n };\n }, [rootRef, preventDropOnDocument]);\n\n // Track global drag state for document-level drag events\n useEffect(() => {\n const onDocumentDragEnter = (event: DragEvent) => {\n if (event.target) {\n globalDragTargetsRef.current = [...globalDragTargetsRef.current, event.target];\n }\n\n if (isEvtWithFiles(event)) {\n dispatch({isDragGlobal: true, type: \"setDragGlobal\"});\n }\n };\n\n const onDocumentDragLeave = (event: DragEvent) => {\n // Only deactivate once we've left all children\n globalDragTargetsRef.current = globalDragTargetsRef.current.filter(el => el !== event.target && el !== null);\n\n if (globalDragTargetsRef.current.length > 0) {\n return;\n }\n\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDragEnd = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDropGlobal = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n document.addEventListener(\"dragenter\", onDocumentDragEnter, false);\n document.addEventListener(\"dragleave\", onDocumentDragLeave, false);\n document.addEventListener(\"dragend\", onDocumentDragEnd, false);\n document.addEventListener(\"drop\", onDocumentDropGlobal, false);\n\n return () => {\n document.removeEventListener(\"dragenter\", onDocumentDragEnter);\n document.removeEventListener(\"dragleave\", onDocumentDragLeave);\n document.removeEventListener(\"dragend\", onDocumentDragEnd);\n document.removeEventListener(\"drop\", onDocumentDropGlobal);\n };\n }, [rootRef]);\n\n // Auto focus the root when autoFocus is true\n useEffect(() => {\n if (!disabled && autoFocus && rootRef.current) {\n rootRef.current.focus();\n }\n return () => {};\n }, [rootRef, autoFocus, disabled]);\n\n const onErrCb = useCallback(\n (e: Error) => {\n if (onError) {\n onError(e);\n } else {\n // Let the user know something's gone wrong if they haven't provided the onError cb.\n console.error(e);\n }\n },\n [onError]\n );\n\n const onDragEnterCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n dragTargetsRef.current = [...dragTargetsRef.current, event.target];\n\n if (isEvtWithFiles(event)) {\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n return;\n }\n\n const fileCount = files.length;\n const isDragAccept =\n fileCount > 0 &&\n allFilesAccepted({\n files: files as File[],\n accept: acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n });\n const isDragReject = fileCount > 0 && !isDragAccept;\n\n dispatch({\n isDragAccept,\n isDragReject,\n isDragActive: true,\n type: \"setDraggedFiles\"\n });\n\n if (onDragEnter) {\n onDragEnter(event);\n }\n })\n .catch(e => onErrCb(e));\n }\n },\n [\n getFilesFromEvent,\n onDragEnter,\n onErrCb,\n noDragEventsBubbling,\n acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator\n ]\n );\n\n const onDragOverCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n const hasFiles = isEvtWithFiles(event);\n if (hasFiles && event.dataTransfer) {\n try {\n event.dataTransfer.dropEffect = \"copy\";\n } catch {\n /* no-op */\n }\n }\n\n if (hasFiles && onDragOver) {\n onDragOver(event);\n }\n\n return false;\n },\n [onDragOver, noDragEventsBubbling]\n );\n\n const onDragLeaveCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n // Only deactivate once the dropzone and all children have been left\n const targets = dragTargetsRef.current.filter(target => rootRef.current?.contains(target as Node));\n // Make sure to remove a target present multiple times only once\n // (Firefox may fire dragenter/dragleave multiple times on the same element)\n const targetIdx = targets.indexOf(event.target);\n if (targetIdx !== -1) {\n targets.splice(targetIdx, 1);\n }\n dragTargetsRef.current = targets;\n if (targets.length > 0) {\n return;\n }\n\n dispatch({\n type: \"setDraggedFiles\",\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false\n });\n\n if (isEvtWithFiles(event) && onDragLeave) {\n onDragLeave(event);\n }\n },\n [rootRef, onDragLeave, noDragEventsBubbling]\n );\n\n const setFiles = useCallback(\n (files: FileWithPath[], event: any) => {\n const acceptedFiles: FileWithPath[] = [];\n const fileRejections: FileRejection[] = [];\n\n files.forEach(file => {\n const [accepted, acceptError] = fileAccepted(file, inputAcceptAttr);\n const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);\n const customErrors = validator ? validator(file) : null;\n\n if (accepted && sizeMatch && !customErrors) {\n acceptedFiles.push(file);\n } else {\n let errors: Array<FileError | null> = [acceptError, sizeError];\n\n if (customErrors) {\n errors = errors.concat(customErrors);\n }\n\n fileRejections.push({\n file,\n errors: errors.filter((e): e is FileError => e != null)\n });\n }\n });\n\n if ((!multiple && acceptedFiles.length > 1) || (multiple && maxFiles >= 1 && acceptedFiles.length > maxFiles)) {\n // Reject everything and empty accepted files\n acceptedFiles.forEach(file => {\n fileRejections.push({file, errors: [TOO_MANY_FILES_REJECTION]});\n });\n acceptedFiles.splice(0);\n }\n\n dispatch({\n acceptedFiles,\n fileRejections,\n type: \"setFiles\"\n });\n\n if (onDrop) {\n onDrop(acceptedFiles, fileRejections, event);\n }\n\n if (fileRejections.length > 0 && onDropRejected) {\n onDropRejected(fileRejections, event);\n }\n\n if (acceptedFiles.length > 0 && onDropAccepted) {\n onDropAccepted(acceptedFiles, event);\n }\n },\n [dispatch, multiple, inputAcceptAttr, minSize, maxSize, maxFiles, onDrop, onDropAccepted, onDropRejected, validator]\n );\n\n const onDropCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n dragTargetsRef.current = [];\n\n if (isEvtWithFiles(event)) {\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n return;\n }\n setFiles(files as FileWithPath[], event);\n })\n .catch(e => onErrCb(e));\n }\n dispatch({type: \"reset\"});\n },\n [getFilesFromEvent, setFiles, onErrCb, noDragEventsBubbling]\n );\n\n // Fn for opening the file dialog programmatically\n const openFileDialog = useCallback(() => {\n // No point to use FS access APIs if context is not secure\n // https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#feature_detection\n if (fsAccessApiWorksRef.current) {\n dispatch({type: \"openDialog\"});\n onFileDialogOpenCb();\n // https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker\n const opts = {\n multiple,\n types: pickerTypes\n };\n (window as any)\n .showOpenFilePicker(opts)\n .then((handles: any) => getFilesFromEvent(handles))\n .then((files: Array<File | DataTransferItem>) => {\n setFiles(files as FileWithPath[], null);\n dispatch({type: \"closeDialog\"});\n })\n .catch((e: any) => {\n // AbortError means the user canceled\n if (isAbort(e)) {\n onFileDialogCancelCb(e);\n dispatch({type: \"closeDialog\"});\n } else if (isSecurityError(e)) {\n fsAccessApiWorksRef.current = false;\n // CORS, so cannot use this API\n // Try using the input\n if (inputRef.current) {\n inputRef.current.value = \"\";\n inputRef.current.click();\n } else {\n onErrCb(\n new Error(\n \"Cannot open the file picker because the https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API is not supported and no <input> was provided.\"\n )\n );\n }\n } else {\n onErrCb(e);\n }\n });\n return;\n }\n\n if (inputRef.current) {\n dispatch({type: \"openDialog\"});\n onFileDialogOpenCb();\n inputRef.current.value = \"\";\n inputRef.current.click();\n }\n }, [dispatch, onFileDialogOpenCb, onFileDialogCancelCb, useFsAccessApi, setFiles, onErrCb, pickerTypes, multiple]);\n\n // Cb to open the file dialog when SPACE/ENTER occurs on the dropzone\n const onKeyDownCb = useCallback(\n (event: any) => {\n // Ignore keyboard events bubbling up the DOM tree\n if (!rootRef.current?.isEqualNode(event.target)) {\n return;\n }\n\n if (event.key === \" \" || event.key === \"Enter\" || event.keyCode === 32 || event.keyCode === 13) {\n event.preventDefault();\n openFileDialog();\n }\n },\n [rootRef, openFileDialog]\n );\n\n // Update focus state for the dropzone\n const onFocusCb = useCallback(() => {\n dispatch({type: \"focus\"});\n }, []);\n const onBlurCb = useCallback(() => {\n dispatch({type: \"blur\"});\n }, []);\n\n // Cb to open the file dialog when click occurs on the dropzone\n const onClickCb = useCallback(() => {\n if (noClick) {\n return;\n }\n\n // In IE11/Edge the file-browser dialog is blocking, therefore, use setTimeout()\n // to ensure React can handle state changes\n // See: https://github.com/react-dropzone/react-dropzone/issues/450\n if (isIeOrEdge()) {\n setTimeout(openFileDialog, 0);\n } else {\n openFileDialog();\n }\n }, [noClick, openFileDialog]);\n\n const composeHandler = (fn: any) => {\n return disabled ? null : fn;\n };\n\n const composeKeyboardHandler = (fn: any) => {\n return noKeyboard ? null : composeHandler(fn);\n };\n\n const composeDragHandler = (fn: any) => {\n return noDrag ? null : composeHandler(fn);\n };\n\n const stopPropagation = (event: any) => {\n if (noDragEventsBubbling) {\n event.stopPropagation();\n }\n };\n\n const getRootProps = useMemo(\n () =>\n ({\n refKey = \"ref\",\n role,\n onKeyDown,\n onFocus,\n onBlur,\n onClick,\n onDragEnter,\n onDragOver,\n onDragLeave,\n onDrop,\n ...rest\n }: DropzoneRootProps = {}) => ({\n onKeyDown: composeKeyboardHandler(composeEventHandlers(onKeyDown, onKeyDownCb)),\n onFocus: composeKeyboardHandler(composeEventHandlers(onFocus, onFocusCb)),\n onBlur: composeKeyboardHandler(composeEventHandlers(onBlur, onBlurCb)),\n onClick: composeHandler(composeEventHandlers(onClick, onClickCb)),\n onDragEnter: composeDragHandler(composeEventHandlers(onDragEnter, onDragEnterCb)),\n onDragOver: composeDragHandler(composeEventHandlers(onDragOver, onDragOverCb)),\n onDragLeave: composeDragHandler(composeEventHandlers(onDragLeave, onDragLeaveCb)),\n onDrop: composeDragHandler(composeEventHandlers(onDrop, onDropCb)),\n role: typeof role === \"string\" && role !== \"\" ? role : \"presentation\",\n [refKey]: rootRef,\n ...(!disabled && !noKeyboard ? {tabIndex: 0} : {}),\n ...(disabled ? {\"aria-disabled\": true} : {}),\n ...rest\n }),\n [\n rootRef,\n onKeyDownCb,\n onFocusCb,\n onBlurCb,\n onClickCb,\n onDragEnterCb,\n onDragOverCb,\n onDragLeaveCb,\n onDropCb,\n noKeyboard,\n noDrag,\n disabled\n ]\n );\n\n const onInputElementClick = useCallback((event: any) => {\n event.stopPropagation();\n }, []);\n\n const getInputProps = useMemo(\n () =>\n ({refKey = \"ref\", onChange, onClick, ...rest}: DropzoneInputProps = {}) => {\n const inputProps = {\n accept: inputAcceptAttr,\n multiple,\n type: \"file\",\n \"aria-label\": \"file upload\",\n style: {\n border: 0,\n clip: \"rect(0, 0, 0, 0)\",\n clipPath: \"inset(50%)\",\n height: \"1px\",\n margin: \"0 -1px -1px 0\",\n overflow: \"hidden\",\n padding: 0,\n position: \"absolute\",\n width: \"1px\",\n whiteSpace: \"nowrap\"\n },\n onChange: composeHandler(composeEventHandlers(onChange, onDropCb)),\n onClick: composeHandler(composeEventHandlers(onClick, onInputElementClick)),\n tabIndex: -1,\n [refKey]: inputRef\n };\n\n return {\n ...inputProps,\n ...rest\n };\n },\n [inputRef, accept, multiple, onDropCb, disabled]\n );\n\n return {\n ...state,\n isFocused: isFocused && !disabled,\n getRootProps,\n getInputProps,\n rootRef,\n inputRef,\n open: composeHandler(openFileDialog)\n } as unknown as DropzoneState;\n}\n\nfunction reducer(state: DropzoneInternalState, action: any): DropzoneInternalState {\n switch (action.type) {\n case \"focus\":\n return {\n ...state,\n isFocused: true\n };\n case \"blur\":\n return {\n ...state,\n isFocused: false\n };\n case \"openDialog\":\n return {\n ...initialState,\n isFileDialogActive: true\n };\n case \"closeDialog\":\n return {\n ...state,\n isFileDialogActive: false\n };\n case \"setDraggedFiles\":\n return {\n ...state,\n isDragActive: action.isDragActive,\n isDragAccept: action.isDragAccept,\n isDragReject: action.isDragReject\n };\n case \"setFiles\":\n return {\n ...state,\n acceptedFiles: action.acceptedFiles,\n fileRejections: action.fileRejections,\n isDragReject: false\n };\n case \"setDragGlobal\":\n return {\n ...state,\n isDragGlobal: action.isDragGlobal\n };\n case \"reset\":\n return {\n ...initialState\n };\n default:\n return state;\n }\n}\n\nfunction noop() {}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-dropzone",
3
- "version": "18.0.0",
3
+ "version": "18.0.2",
4
4
  "description": "Simple HTML5 drag-drop zone with React.js",
5
5
  "keywords": [
6
6
  "drag",
@@ -101,8 +101,14 @@
101
101
  "waku": "^1.0.0-beta.6"
102
102
  },
103
103
  "peerDependencies": {
104
+ "@types/react": "*",
104
105
  "react": ">= 18"
105
106
  },
107
+ "peerDependenciesMeta": {
108
+ "@types/react": {
109
+ "optional": true
110
+ }
111
+ },
106
112
  "engines": {
107
113
  "node": ">= 20"
108
114
  }
package/src/index.tsx CHANGED
@@ -49,7 +49,7 @@ export type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> &
49
49
  onDrop?: <T extends File>(acceptedFiles: T[], fileRejections: FileRejection[], event: DropEvent) => void;
50
50
  onDropAccepted?: <T extends File>(files: T[], event: DropEvent) => void;
51
51
  onDropRejected?: (fileRejections: FileRejection[], event: DropEvent) => void;
52
- getFilesFromEvent?: (event: DropEvent) => Promise<Array<File | DataTransferItem>>;
52
+ getFilesFromEvent?: (event: DropEvent | Array<FileSystemFileHandle>) => Promise<Array<File | DataTransferItem>>;
53
53
  onFileDialogCancel?: () => void;
54
54
  onFileDialogOpen?: () => void;
55
55
  onError?: (err: Error) => void;
@@ -58,12 +58,7 @@ export type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> &
58
58
  autoFocus?: boolean;
59
59
  };
60
60
 
61
- export type DropEvent =
62
- | React.DragEvent<HTMLElement>
63
- | React.ChangeEvent<HTMLInputElement>
64
- | DragEvent
65
- | Event
66
- | Array<FileSystemFileHandle>;
61
+ export type DropEvent = React.DragEvent<HTMLElement> | React.ChangeEvent<HTMLInputElement> | DragEvent | Event;
67
62
 
68
63
  export interface DropzoneRef {
69
64
  open: () => void;
@@ -191,7 +186,20 @@ export function useDropzone(props: DropzoneOptions = {}): DropzoneState {
191
186
  validator
192
187
  } = props;
193
188
 
189
+ // `acceptAttr` keeps wildcard MIME types (e.g. `image/*`) so the drag-time
190
+ // `isDragAccept`/`isDragReject` check can react to a file's MIME type - file names
191
+ // (hence extensions) aren't readable during a drag.
194
192
  const acceptAttr = useMemo(() => acceptPropAsAcceptAttr(accept), [accept]);
193
+ // `inputAcceptAttr` drops a wildcard MIME type when it is paired with extensions, so the
194
+ // native picker and drop-time validation enforce the extensions instead of accepting any
195
+ // file of that type. See https://github.com/react-dropzone/react-dropzone/issues/1220
196
+ const inputAcceptAttr = useMemo(
197
+ () =>
198
+ acceptPropAsAcceptAttr(accept, {
199
+ omitWildcardMimeTypesWithExtensions: true
200
+ }),
201
+ [accept]
202
+ );
195
203
  const pickerTypes = useMemo(() => pickerOptionsFromAccept(accept), [accept]);
196
204
 
197
205
  const onFileDialogOpenCb = useMemo<(...args: any[]) => void>(
@@ -448,7 +456,7 @@ export function useDropzone(props: DropzoneOptions = {}): DropzoneState {
448
456
  const fileRejections: FileRejection[] = [];
449
457
 
450
458
  files.forEach(file => {
451
- const [accepted, acceptError] = fileAccepted(file, acceptAttr);
459
+ const [accepted, acceptError] = fileAccepted(file, inputAcceptAttr);
452
460
  const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);
453
461
  const customErrors = validator ? validator(file) : null;
454
462
 
@@ -461,7 +469,10 @@ export function useDropzone(props: DropzoneOptions = {}): DropzoneState {
461
469
  errors = errors.concat(customErrors);
462
470
  }
463
471
 
464
- fileRejections.push({file, errors: errors.filter((e): e is FileError => e != null)});
472
+ fileRejections.push({
473
+ file,
474
+ errors: errors.filter((e): e is FileError => e != null)
475
+ });
465
476
  }
466
477
  });
467
478
 
@@ -491,7 +502,7 @@ export function useDropzone(props: DropzoneOptions = {}): DropzoneState {
491
502
  onDropAccepted(acceptedFiles, event);
492
503
  }
493
504
  },
494
- [dispatch, multiple, acceptAttr, minSize, maxSize, maxFiles, onDrop, onDropAccepted, onDropRejected, validator]
505
+ [dispatch, multiple, inputAcceptAttr, minSize, maxSize, maxFiles, onDrop, onDropAccepted, onDropRejected, validator]
495
506
  );
496
507
 
497
508
  const onDropCb = useCallback(
@@ -655,6 +666,7 @@ export function useDropzone(props: DropzoneOptions = {}): DropzoneState {
655
666
  role: typeof role === "string" && role !== "" ? role : "presentation",
656
667
  [refKey]: rootRef,
657
668
  ...(!disabled && !noKeyboard ? {tabIndex: 0} : {}),
669
+ ...(disabled ? {"aria-disabled": true} : {}),
658
670
  ...rest
659
671
  }),
660
672
  [
@@ -681,9 +693,10 @@ export function useDropzone(props: DropzoneOptions = {}): DropzoneState {
681
693
  () =>
682
694
  ({refKey = "ref", onChange, onClick, ...rest}: DropzoneInputProps = {}) => {
683
695
  const inputProps = {
684
- accept: acceptAttr,
696
+ accept: inputAcceptAttr,
685
697
  multiple,
686
698
  type: "file",
699
+ "aria-label": "file upload",
687
700
  style: {
688
701
  border: 0,
689
702
  clip: "rect(0, 0, 0, 0)",
@@ -250,14 +250,30 @@ export function pickerOptionsFromAccept(accept?: Accept): Array<{description: st
250
250
  }
251
251
 
252
252
  /**
253
- * Convert the `{accept}` dropzone prop to an array of MIME types/extensions.
253
+ * Convert the `{accept}` dropzone prop to a comma-separated accept attribute string.
254
+ *
255
+ * When `omitWildcardMimeTypesWithExtensions` is set, a wildcard MIME type (e.g. `image/*`)
256
+ * that is paired with explicit extensions is dropped in favour of those extensions. The
257
+ * accept attribute is an OR list, so leaving `image/*` in would make both the native file
258
+ * picker and the drop-time validator accept ANY file of that type, ignoring the extension
259
+ * restriction. The drag-time `isDragAccept` check keeps the wildcard because file names
260
+ * (and therefore extensions) aren't readable during a drag.
261
+ *
262
+ * See https://github.com/react-dropzone/react-dropzone/issues/1220
254
263
  */
255
- export function acceptPropAsAcceptAttr(accept?: Accept): string | undefined {
264
+ export function acceptPropAsAcceptAttr(
265
+ accept?: Accept,
266
+ {omitWildcardMimeTypesWithExtensions = false}: {omitWildcardMimeTypesWithExtensions?: boolean} = {}
267
+ ): string | undefined {
256
268
  if (isDefined(accept)) {
257
269
  return (
258
270
  Object.entries(accept)
259
271
  .reduce<string[]>((a, [mimeType, ext]) => {
260
- a.push(mimeType, ...ext);
272
+ if (omitWildcardMimeTypesWithExtensions && isMIMETypeWildcard(mimeType) && ext.some(isExt)) {
273
+ a.push(...ext);
274
+ } else {
275
+ a.push(mimeType, ...ext);
276
+ }
261
277
  return a;
262
278
  }, [])
263
279
  // Silently discard invalid entries as pickerOptionsFromAccept warns about these
@@ -297,6 +313,13 @@ export function isMIMEType(v: string): boolean {
297
313
  );
298
314
  }
299
315
 
316
+ /**
317
+ * Check if v is a wildcard MIME type (e.g. `image/*`).
318
+ */
319
+ export function isMIMETypeWildcard(v: string): boolean {
320
+ return v.endsWith("/*");
321
+ }
322
+
300
323
  /**
301
324
  * Check if v is a file extension.
302
325
  */