react-dropzone
Version:
Simple HTML5 drag-drop zone with React.js
1 lines • 80.5 kB
Source Map (JSON)
{"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 *\n * An extension value may be a single extension string or an array of them - both are\n * accepted, mirroring the shape of `window.showOpenFilePicker`'s `accept`.\n */\nexport interface Accept {\n [key: string]: string | readonly string[];\n}\n\n/**\n * A labeled group of accepted types, mirroring one entry of `window.showOpenFilePicker`'s\n * `types` option. Passing the `accept` prop as an array of these lets the File System Access\n * picker present multiple named filter rows instead of a single one (see\n * {@link pickerOptionsFromAccept}). The optional `description` labels the row; when omitted it\n * is derived from the group's extensions.\n *\n * Grouping only surfaces when the FS Access picker is actually used (`useFsAccessApi` +\n * a secure context + browser support). The native `<input>` fallback has no concept of groups\n * or descriptions, so every group is flattened into one accept attribute there.\n */\nexport interface AcceptGroup {\n description?: string;\n accept: Accept;\n}\n\n/**\n * A file rejection error.\n */\nexport interface FileError {\n message: string;\n code: ErrorCode | string;\n}\n\n/**\n * What a custom `validator` returns: a single error, a list of errors, or `null` when the file\n * passes. A validator may return the result directly (synchronous) or wrapped in a `Promise`\n * (asynchronous, e.g. reading image dimensions or calling an external service).\n */\nexport type ValidatorResult = FileError | readonly FileError[] | null;\n\n// Error codes\nexport const FILE_INVALID_TYPE = \"file-invalid-type\";\nexport const FILE_TOO_LARGE = \"file-too-large\";\nexport const FILE_TOO_SMALL = \"file-too-small\";\nexport const TOO_MANY_FILES = \"too-many-files\";\n\nexport enum ErrorCode {\n FileInvalidType = \"file-invalid-type\",\n FileTooLarge = \"file-too-large\",\n FileTooSmall = \"file-too-small\",\n TooManyFiles = \"too-many-files\"\n}\n\nexport function getInvalidTypeRejectionErr(accept: string = \"\"): FileError {\n const acceptArr = accept.split(\",\");\n const msg = acceptArr.length > 1 ? `one of ${acceptArr.join(\", \")}` : acceptArr[0];\n\n return {\n code: FILE_INVALID_TYPE,\n message: `File type must be ${msg}`\n };\n}\n\nconst FILE_SIZE_UNITS = [\"KB\", \"MB\", \"GB\", \"TB\", \"PB\"];\n\n/**\n * Format a byte count into a human-readable string, e.g. `1111` -> `1.08 KB`.\n * Values below 1 KB are kept in bytes to preserve the singular/plural wording.\n */\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} ${bytes === 1 ? \"byte\" : \"bytes\"}`;\n }\n\n let size = bytes / 1024;\n let unitIndex = 0;\n while (size >= 1024 && unitIndex < FILE_SIZE_UNITS.length - 1) {\n size /= 1024;\n unitIndex++;\n }\n\n // Round to 2 decimals, then drop trailing zeros (1.00 -> 1, 1.50 -> 1.5).\n return `${Number(size.toFixed(2))} ${FILE_SIZE_UNITS[unitIndex]}`;\n}\n\nexport function getTooLargeRejectionErr(maxSize: number): FileError {\n return {\n code: FILE_TOO_LARGE,\n message: `File is larger than ${formatBytes(maxSize)}`\n };\n}\n\nexport function getTooSmallRejectionErr(minSize: number): FileError {\n return {\n code: FILE_TOO_SMALL,\n message: `File is smaller than ${formatBytes(minSize)}`\n };\n}\n\nexport const TOO_MANY_FILES_REJECTION: FileError = {\n code: TOO_MANY_FILES,\n message: \"Too many files\"\n};\n\n/**\n * Check if the given file is a DataTransferItem with an empty type.\n *\n * During drag events, browsers may return DataTransferItem objects instead of File objects.\n * Some browsers (e.g., Chrome) return an empty MIME type for certain file types (like .md files)\n * on DataTransferItem during drag events, even though the type is correctly set during drop.\n */\nexport function isDataTransferItemWithEmptyType(file: File | DataTransferItem): boolean {\n return file.type === \"\" && typeof (file as DataTransferItem).getAsFile === \"function\";\n}\n\n/**\n * Check if file is accepted.\n *\n * Firefox versions prior to 53 return a bogus MIME type for every file drag,\n * so dragovers with that MIME type will always be accepted.\n *\n * Chrome/other browsers may return an empty MIME type for files during drag events,\n * so we accept those as well (we'll validate properly on drop).\n */\nexport function fileAccepted(file: File, accept?: string): [boolean, FileError | null] {\n const isAcceptable =\n file.type === \"application/x-moz-file\" || accepts(file, accept ?? \"\") || isDataTransferItemWithEmptyType(file);\n return [isAcceptable, isAcceptable ? null : getInvalidTypeRejectionErr(accept)];\n}\n\nexport function fileMatchSize(\n file: {size?: number | null},\n minSize?: number,\n maxSize?: number\n): [boolean, FileError | null] {\n if (isDefined(file.size)) {\n if (isDefined(minSize) && isDefined(maxSize)) {\n if (file.size > maxSize) return [false, getTooLargeRejectionErr(maxSize)];\n if (file.size < minSize) return [false, getTooSmallRejectionErr(minSize)];\n } else if (isDefined(minSize) && file.size < minSize) {\n return [false, getTooSmallRejectionErr(minSize)];\n } else if (isDefined(maxSize) && file.size > maxSize) {\n return [false, getTooLargeRejectionErr(maxSize)];\n }\n }\n return [true, null];\n}\n\nfunction isDefined<T>(value: T): value is NonNullable<T> {\n return value !== undefined && value !== null;\n}\n\n/**\n * Check if a value is thenable (Promise-like), used to tell a synchronous validator result from an\n * asynchronous one.\n */\nexport function isThenable(value: unknown): value is PromiseLike<unknown> {\n return value != null && typeof (value as {then?: unknown}).then === \"function\";\n}\n\nexport function allFilesAccepted({\n files,\n accept,\n minSize,\n maxSize,\n multiple,\n maxFiles = 0,\n validator\n}: {\n files: File[];\n accept?: string;\n minSize?: number;\n maxSize?: number;\n multiple?: boolean;\n maxFiles?: number;\n validator?: (file: File) => FileError | readonly FileError[] | null;\n}): boolean {\n if ((!multiple && files.length > 1) || (multiple && maxFiles >= 1 && files.length > maxFiles)) {\n return false;\n }\n\n return files.every(file => {\n const [accepted] = fileAccepted(file, accept);\n const [sizeMatch] = fileMatchSize(file, minSize, maxSize);\n const customErrors = validator ? validator(file) : null;\n return accepted && sizeMatch && !customErrors;\n });\n}\n\n/**\n * The outcome of the drag-time acceptance check.\n *\n * - `accept` - every file passes the checks we can evaluate during a drag.\n * - `reject` - at least one file confidently fails a check we can fully evaluate during a\n * drag (the file count, or a non-empty MIME type that doesn't match `accept`).\n * - `unknown` - nothing confidently fails, but the outcome can't be confirmed until drop,\n * because a custom `validator` is configured and can't be evaluated yet.\n */\nexport type DragVerdict = \"accept\" | \"reject\" | \"unknown\";\n\n/**\n * A file rejected by the checks that can run during a drag.\n */\nexport interface DragFileRejection<T extends File | DataTransferItem = File | DataTransferItem> {\n file: T;\n errors: readonly FileError[];\n}\n\nexport interface DragEvaluation<T extends File | DataTransferItem = File | DataTransferItem> {\n verdict: DragVerdict;\n rejections: DragFileRejection<T>[];\n}\n\n/**\n * Classify a set of dragged files for the `isDragAccept`/`isDragReject`/`isDragUnknown` states.\n *\n * During `dragenter`/`dragover` the browser only exposes `DataTransferItem`s, which carry a MIME\n * `type` but no file name, extension or size (see https://html.spec.whatwg.org/multipage/dnd.html#dndevents).\n * So the drag-time check is deliberately optimistic about anything it can't see:\n *\n * - The custom `validator` is **never** run here. It is typed `(file: File) => ...` and users\n * routinely read `file.name`/`file.size`, which are `undefined` on a `DataTransferItem` - running\n * it would throw and abort the whole drag handler (leaving `isDragActive` stuck at `false`).\n * See https://github.com/react-dropzone/react-dropzone/issues/1408\n * - When a `validator` is configured we therefore can't promise the files are acceptable, so the\n * verdict is `unknown` rather than a misleading `reject` (or a premature `accept`).\n * See https://github.com/react-dropzone/react-dropzone/issues/1244\n *\n * The full check (including the `validator`) still runs on drop in {@link fileAccepted}/`setFiles`.\n */\nexport function evaluateDragFiles<T extends File | DataTransferItem>({\n files,\n accept,\n minSize,\n maxSize,\n multiple,\n maxFiles = 0,\n validator,\n getErrorMessage\n}: {\n files: T[];\n accept?: string;\n minSize?: number;\n maxSize?: number;\n multiple?: boolean;\n maxFiles?: number;\n // The validator is never invoked here (see the note above), so its async variant is accepted\n // purely so the same `validator` prop is assignable during a drag.\n validator?: (file: File) => ValidatorResult | Promise<ValidatorResult>;\n getErrorMessage?: (error: FileError, file: File) => string;\n}): DragEvaluation<T> {\n const acceptedFiles: T[] = [];\n const rejections: DragFileRejection<T>[] = [];\n\n const localizeError = (error: FileError, file: T): FileError =>\n getErrorMessage && typeof File !== \"undefined\" && file instanceof File\n ? {...error, message: getErrorMessage(error, file)}\n : error;\n\n files.forEach(file => {\n const [accepted, acceptError] = fileAccepted(file as File, accept);\n const [sizeMatch, sizeError] = fileMatchSize(file as File, minSize, maxSize);\n\n if (accepted && sizeMatch) {\n acceptedFiles.push(file);\n } else {\n rejections.push({\n file,\n errors: [acceptError, sizeError]\n .filter((error): error is FileError => error != null)\n .map(error => localizeError(error, file))\n });\n }\n });\n\n // Match the drop path: files that already failed a per-file check do not consume the limit,\n // and only otherwise-valid surplus files receive a too-many-files rejection.\n const acceptedFilesLimit = multiple ? (maxFiles >= 1 ? maxFiles : Number.POSITIVE_INFINITY) : 1;\n if (acceptedFiles.length > acceptedFilesLimit) {\n acceptedFiles.slice(acceptedFilesLimit).forEach(file => {\n rejections.push({file, errors: [localizeError(TOO_MANY_FILES_REJECTION, file)]});\n });\n }\n\n if (rejections.length > 0) {\n return {verdict: \"reject\", rejections};\n }\n\n // Built-in checks pass. A custom validator can only ever add rejections on drop, never rescue\n // one - so with a validator present the drag outcome is unknown until we have real Files.\n return {verdict: validator ? \"unknown\" : \"accept\", rejections};\n}\n\nexport function getDragVerdict(options: Parameters<typeof evaluateDragFiles>[0]): DragVerdict {\n return evaluateDragFiles(options).verdict;\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 // A paste (ClipboardEvent) carries its DataTransfer under {clipboardData} rather than\n // {dataTransfer}, so a pasted screenshot is detected the same way as a drop.\n const dataTransfer = event.dataTransfer ?? event.clipboardData;\n if (!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 // Some Chromium drags omit \"Files\" from types (e.g. reporting only [\"text/plain\"])\n // while still exposing a kind: \"file\" entry in items - the same signal file-selector\n // uses to extract the files. Accept either so detection stays consistent. See #1409.\n return (\n Array.prototype.some.call(\n dataTransfer.types,\n (type: string) => type === \"Files\" || type === \"application/x-moz-file\"\n ) || Array.prototype.some.call(dataTransfer.items ?? [], isKindFile)\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 * Coerce an `accept` extension value to an array. `window.showOpenFilePicker` allows a single\n * extension string as well as an array, so we accept both and normalize to an array. Anything\n * else (a malformed value) collapses to an empty list.\n */\nfunction toExtensions(ext: string | readonly string[] | undefined): readonly string[] {\n if (Array.isArray(ext)) {\n return ext;\n }\n if (typeof ext === \"string\") {\n return [ext];\n }\n return [];\n}\n\n/**\n * Normalize either `accept` form to the internal array of `{description, accept}` groups.\n *\n * - The object form (`{mime: ext}`) becomes a single group; its `description` (which the object\n * form can't express) is derived from the extensions like any other group.\n * - The array form is passed through; entries missing an `accept` map are dropped.\n *\n * In both cases a missing `description` is filled in later from the group's extensions (see\n * {@link describeAccept}), so the picker always gets the non-empty description it requires\n * (https://crbug.com/1264708). Returns `undefined` when no `accept` is provided.\n */\nfunction normalizeAcceptGroups(accept?: Accept | readonly AcceptGroup[]): AcceptGroup[] | undefined {\n if (!isDefined(accept)) {\n return undefined;\n }\n if (Array.isArray(accept)) {\n return (accept as readonly AcceptGroup[]).filter(group => isDefined(group) && isDefined(group.accept));\n }\n return [{accept: accept as Accept}];\n}\n\n/**\n * Build a human-readable label for a picker group from its (validated) accept map, used when the\n * caller doesn't supply a `description`. Prefer the file extensions, fall back to the MIME types,\n * then to a generic label - `showOpenFilePicker` requires a non-empty description (crbug 1264708).\n */\nfunction describeAccept(accept: Accept): string {\n const extensions: string[] = [];\n const mimeTypes = Object.keys(accept);\n for (const ext of Object.values(accept)) {\n for (const e of toExtensions(ext)) {\n if (!extensions.includes(e)) {\n extensions.push(e);\n }\n }\n }\n if (extensions.length > 0) {\n return extensions.join(\", \");\n }\n if (mimeTypes.length > 0) {\n return mimeTypes.join(\", \");\n }\n return \"Files\";\n}\n\n/**\n * Merge every `accept` group into a single MIME-type -> extensions map. Duplicate MIME keys union\n * their extensions. This flattened map drives the native `<input accept>` attribute and the\n * drag/drop validators, which have no concept of groups or descriptions.\n */\nexport function flattenAccept(accept?: Accept | readonly AcceptGroup[]): Accept | undefined {\n const groups = normalizeAcceptGroups(accept);\n if (!isDefined(groups)) {\n return undefined;\n }\n const merged: Record<string, string[]> = {};\n for (const group of groups) {\n for (const [mimeType, ext] of Object.entries(group.accept)) {\n const existing = merged[mimeType] ?? (merged[mimeType] = []);\n for (const e of toExtensions(ext)) {\n if (!existing.includes(e)) {\n existing.push(e);\n }\n }\n }\n }\n return merged;\n}\n\n/**\n * Convert the `{accept}` dropzone prop to the `{types}` option for showOpenFilePicker.\n *\n * Each group becomes one filter row in the picker. Invalid MIME types / extensions are dropped\n * with a warning; a group left with no valid entries is omitted entirely (showOpenFilePicker\n * rejects an empty `accept`). Returns `undefined` when nothing valid remains.\n */\nexport function pickerOptionsFromAccept(\n accept?: Accept | readonly AcceptGroup[]\n): Array<{description: string; accept: Accept}> | undefined {\n const groups = normalizeAcceptGroups(accept);\n if (!isDefined(groups)) {\n return undefined;\n }\n\n const options = groups\n .map(group => {\n const acceptForPicker = Object.entries(group.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 const isExtInput = Array.isArray(ext) || typeof ext === \"string\";\n if (!isExtInput || !toExtensions(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] = toExtensions(ext);\n return agg;\n }, {});\n\n return {\n description:\n isDefined(group.description) && group.description !== \"\"\n ? group.description\n : describeAccept(acceptForPicker),\n accept: acceptForPicker\n };\n })\n // Drop groups with no valid entries - showOpenFilePicker rejects an empty accept map.\n .filter(option => Object.keys(option.accept).length > 0);\n\n return options.length > 0 ? options : 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, extVal]) => {\n const ext = toExtensions(extVal);\n if (omitWildcardMimeTypesWithExtensions && isMIMETypeWildcard(mimeType) && ext.some(isExt)) {\n a.push(...ext);\n } else {\n a.push(mimeType, ...ext);\n }\n return a;\n }, [])\n // Silently discard invalid entries as pickerOptionsFromAccept warns about these\n .filter(v => isMIMEType(v) || isExt(v))\n .join(\",\")\n );\n }\n\n return undefined;\n}\n\n/**\n * Check if v is an exception caused by aborting a request (e.g window.showOpenFilePicker()).\n */\nexport function isAbort(v: any): boolean {\n return v instanceof DOMException && (v.name === \"AbortError\" || v.code === v.ABORT_ERR);\n}\n\n/**\n * Check if v is a security error.\n */\nexport function isSecurityError(v: any): boolean {\n return v instanceof DOMException && (v.name === \"SecurityError\" || v.code === v.SECURITY_ERR);\n}\n\n/**\n * Check if v is a \"not allowed\" error.\n *\n * Some browsers/configurations block `window.showOpenFilePicker()` outright and reject with a\n * `NotAllowedError` instead of showing the picker (e.g. Microsoft Edge for Business, or other\n * restrictive enterprise/security policies). We treat this like a security error and fall back\n * to the native `<input>`. See https://github.com/react-dropzone/react-dropzone/issues/1429\n */\nexport function isNotAllowedError(v: any): boolean {\n return v instanceof DOMException && v.name === \"NotAllowedError\";\n}\n\n/**\n * Check if v is a MIME type string.\n */\nexport function isMIMEType(v: string): boolean {\n return (\n v === \"audio/*\" ||\n v === \"video/*\" ||\n v === \"image/*\" ||\n v === \"text/*\" ||\n v === \"application/*\" ||\n /\\w+\\/[-+.\\w]+/g.test(v)\n );\n}\n\n/**\n * Check if v is a wildcard MIME type (e.g. `image/*`).\n */\nexport function isMIMETypeWildcard(v: string): boolean {\n return v.endsWith(\"/*\");\n}\n\n/**\n * Check if v is a file extension.\n */\nexport function isExt(v: string): boolean {\n return /^.*\\.[\\w]+$/.test(v);\n}\n","import {fromEvent} from \"file-selector\";\nimport type {FileWithPath} from \"file-selector\";\nimport type * as React from \"react\";\nimport {forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useReducer, useRef} from \"react\";\nimport {\n acceptPropAsAcceptAttr,\n canUseFileSystemAccessAPI,\n composeEventHandlers,\n ErrorCode,\n evaluateDragFiles,\n fileAccepted,\n fileMatchSize,\n flattenAccept,\n isAbort,\n isEvtWithFiles,\n isIeOrEdge,\n isNotAllowedError,\n isThenable,\n isPropagationStopped,\n isSecurityError,\n onDocumentDragOver,\n pickerOptionsFromAccept,\n TOO_MANY_FILES_REJECTION\n} from \"./utils\";\nimport type {\n Accept,\n AcceptGroup,\n DragFileRejection as UtilsDragFileRejection,\n FileError,\n ValidatorResult\n} from \"./utils\";\n\nexport type {Accept, AcceptGroup, FileError, FileWithPath, ValidatorResult};\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\nexport type DragFileRejection = UtilsDragFileRejection<FileWithPath | DataTransferItem>;\n\ntype SharedProps = \"multiple\" | \"onDragEnter\" | \"onDragOver\" | \"onDragLeave\";\n\nexport type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, SharedProps> & {\n accept?: Accept | AcceptGroup[];\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 /**\n * If true, disables paste-to-upload. By default, when the dropzone (or a focused child) receives a\n * paste that carries files - e.g. a screenshot pasted with Ctrl/Cmd+V - those files go through the\n * same `accept`/size/`validator` checks and `onDrop` callbacks as a drop. Pastes with no files\n * (plain text, etc.) are ignored and left untouched. See\n * https://github.com/react-dropzone/react-dropzone/issues/1210\n */\n noPaste?: 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 /**\n * Custom validation, run once per file on drop/selection. Return `null` to accept the file, or a\n * {@link FileError} (or array of them) to reject it. May be `async` (return a `Promise`) to support\n * checks that can't run synchronously - e.g. reading image dimensions, inspecting file contents,\n * or calling an external service. While an async validator is pending, {@link DropzoneState.isProcessing}\n * is `true`, and `onDrop`/`onDropAccepted`/`onDropRejected` fire only once it settles. If the\n * validator throws or rejects, `onError` is called and the drop is discarded.\n *\n * Note: the validator never runs during a drag (a `DataTransferItem` has no name/size), so a\n * validator-configured dropzone is `isDragUnknown` until drop.\n */\n validator?: <T extends File>(file: T) => ValidatorResult | Promise<ValidatorResult>;\n /**\n * Override the message of any rejection error (built-in or custom). Called once per error;\n * receives the error and the file it belongs to and returns the message to use. Return\n * `error.message` for codes you don't want to change. Useful for localizing error messages.\n */\n getErrorMessage?: (error: FileError, file: File) => string;\n useFsAccessApi?: boolean;\n autoFocus?: boolean;\n};\n\nexport type DropEvent =\n | React.DragEvent<HTMLElement>\n | React.ChangeEvent<HTMLInputElement>\n | React.ClipboardEvent<HTMLElement>\n | DragEvent\n | ClipboardEvent\n | Event;\n\nexport interface DropzoneRef {\n open: () => void;\n}\n\nexport type DropzoneState = DropzoneRef & {\n isFocused: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragUnknown: boolean;\n isDragGlobal: boolean;\n isFileDialogActive: boolean;\n /**\n * `true` while a drop/selection is being processed asynchronously - i.e. while `getFilesFromEvent`\n * reads the files and/or an async {@link DropzoneOptions.validator} runs. Spans the whole pipeline,\n * from when files start being read until validation settles. When both are synchronous (the default\n * `getFilesFromEvent` with no/async-free validator) the work resolves within a microtask, so it's\n * only observable for genuinely async work. Use it to show a spinner or disable UI while processing.\n */\n isProcessing: boolean;\n acceptedFiles: readonly FileWithPath[];\n fileRejections: readonly FileRejection[];\n /**\n * Rejections that can be determined before drop. Standard drag events expose\n * `DataTransferItem`s with a MIME type but no name or size, so extension, size, and custom\n * validator failures are only available in {@link fileRejections} after drop. In practice this\n * state can report MIME-type and surplus-file errors during a standard browser drag.\n */\n dragFileRejections: readonly DragFileRejection[];\n rootRef: React.RefObject<HTMLElement>;\n inputRef: React.RefObject<HTMLInputElement>;\n getRootProps: <T extends DropzoneRootProps>(props?: T) => T;\n getInputProps: <T extends DropzoneInputProps>(props?: T) => T;\n};\n\nexport interface DropzoneRootProps extends React.HTMLAttributes<HTMLElement> {\n refKey?: string;\n [key: string]: any;\n}\n\nexport interface DropzoneInputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n refKey?: string;\n}\n\n/**\n * Convenience wrapper component for the `useDropzone` hook\n *\n * ```jsx\n * <Dropzone>\n * {({getRootProps, getInputProps}) => (\n * <div {...getRootProps()}>\n * <input {...getInputProps()} />\n * <p>Drag 'n' drop some files here, or click to select files</p>\n * </div>\n * )}\n * </Dropzone>\n * ```\n */\nconst Dropzone: React.ForwardRefExoticComponent<DropzoneProps & React.RefAttributes<DropzoneRef>> = forwardRef<\n DropzoneRef,\n DropzoneProps\n>(({children, ...params}, ref) => {\n const {open, ...props} = useDropzone(params);\n\n useImperativeHandle(ref, () => ({open}), [open]);\n\n return <>{children?.({...props, open})}</>;\n});\n\nDropzone.displayName = \"Dropzone\";\n\nexport default Dropzone;\n\ninterface DropzoneInternalState {\n isFocused: boolean;\n isFileDialogActive: boolean;\n isDragActive: boolean;\n isDragAccept: boolean;\n isDragReject: boolean;\n isDragUnknown: boolean;\n isDragGlobal: boolean;\n isProcessing: boolean;\n acceptedFiles: FileWithPath[];\n fileRejections: FileRejection[];\n dragFileRejections: DragFileRejection[];\n}\n\n/**\n * The per-file outcome of the built-in checks plus the (resolved) custom validator, assembled in\n * setFiles before the accepted/rejected split.\n */\ninterface PerFileResult {\n file: FileWithPath;\n accepted: boolean;\n acceptError: FileError | null;\n sizeMatch: boolean;\n sizeError: FileError | null;\n customErrors: ValidatorResult;\n}\n\nconst initialState: DropzoneInternalState = {\n isFocused: false,\n isFileDialogActive: false,\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false,\n isDragUnknown: false,\n isDragGlobal: false,\n isProcessing: false,\n acceptedFiles: [],\n fileRejections: [],\n dragFileRejections: []\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 noPaste = false,\n onError,\n validator,\n getErrorMessage\n } = props;\n\n // `accept` may be a MIME->extensions map or an array of labeled groups (for the FS Access\n // picker). Flatten it to a single map for the native `<input>` and the drag/drop validators,\n // which have no concept of groups; the picker keeps the groups via `pickerTypes` below.\n const flatAccept = useMemo(() => flattenAccept(accept), [accept]);\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(flatAccept), [flatAccept]);\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(flatAccept, {\n omitWildcardMimeTypesWithExtensions: true\n }),\n [flatAccept]\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 // Mirror {isFileDialogActive} into a ref so the memoized drag handlers can read the current value\n // without being recreated (and churning getRootProps/getInputProps) every time the dialog toggles.\n const isFileDialogActiveRef = useRef(isFileDialogActive);\n isFileDialogActiveRef.current = isFileDialogActive;\n\n // Tracks the in-flight processing run - reading files (getFilesFromEvent) plus running an async\n // validator. A newer drop/selection aborts the previous run so slow async work can't resolve late\n // and clobber the state with stale results.\n const processingAbortRef = useRef<AbortController | null>(null);\n\n // Begin a processing run: supersede any run still in flight and flip {isProcessing} on. Returns\n // the run's AbortSignal, which downstream async steps check to bail if a newer run took over.\n const beginProcessing = useCallback(() => {\n processingAbortRef.current?.abort();\n const controller = new AbortController();\n processingAbortRef.current = controller;\n dispatch({type: \"setProcessing\", isProcessing: true});\n return controller.signal;\n }, []);\n\n // End a processing run by clearing {isProcessing} - but only if this run is still the active one.\n // A superseded run (signal aborted) leaves the flag to the run that replaced it.\n const endProcessing = useCallback((signal: AbortSignal) => {\n if (!signal.aborted) {\n dispatch({type: \"setProcessing\", isProcessing: false});\n }\n }, []);\n\n const fsAccessApiWorksRef = useRef(\n typeof window !== \"undefined\" && window.isSecureContext && useFsAccessApi && canUseFileSystemAccessAPI()\n );\n\n // Update file dialog active state when the window is focused on\n const onWindowFocus = () => {\n // Execute the timeout only if the file dialog is opened in the browser\n if (!fsAccessApiWorksRef.current && isFileDialogActive) {\n setTimeout(() => {\n if (inputRef.current) {\n const {files} = inputRef.current;\n\n if (!files?.length) {\n dispatch({type: \"closeDialog\"});\n onFileDialogCancelCb();\n }\n }\n }, 300);\n }\n };\n useEffect(() => {\n window.addEventListener(\"focus\", onWindowFocus, false);\n return () => {\n window.removeEventListener(\"focus\", onWindowFocus, false);\n };\n }, [inputRef, isFileDialogActive, onFileDialogCancelCb, fsAccessApiWorksRef]);\n\n const dragTargetsRef = useRef<EventTarget[]>([]);\n const globalDragTargetsRef = useRef<EventTarget[]>([]);\n const onDocumentDrop = (event: DragEvent) => {\n // This is a document-level, bubble-phase listener, so it runs *after* the event has already\n // bubbled through the dropzone root. If the drop landed inside the root and the instance's own\n // onDrop handler already prevented the default, there's nothing left to do.\n //\n // We must NOT bail out on `contains()` alone: when the dropzone is `disabled` or has `noDrag`,\n // the root has no onDrop handler, so nothing prevents the browser's default action and the file\n // is opened in the tab. Falling through to `preventDefault()` here keeps that from happening.\n // See https://github.com/react-dropzone/react-dropzone/issues/1362\n if (rootRef.current && event.target && rootRef.current.contains(event.target as Node) && event.defaultPrevented) {\n return;\n }\n event.preventDefault();\n dragTargetsRef.current = [];\n };\n\n useEffect(() => {\n if (preventDropOnDocument) {\n document.addEventListener(\"dragover\", onDocumentDragOver, false);\n document.addEventListener(\"drop\", onDocumentDrop, false);\n }\n\n return () => {\n if (preventDropOnDocument) {\n document.removeEventListener(\"dragover\", onDocumentDragOver);\n document.removeEventListener(\"drop\", onDocumentDrop);\n }\n };\n }, [rootRef, preventDropOnDocument]);\n\n // Track global drag state for document-level drag events\n useEffect(() => {\n const onDocumentDragEnter = (event: DragEvent) => {\n if (event.target) {\n globalDragTargetsRef.current = [...globalDragTargetsRef.current, event.target];\n }\n\n if (isEvtWithFiles(event)) {\n dispatch({isDragGlobal: true, type: \"setDragGlobal\"});\n }\n };\n\n const onDocumentDragLeave = (event: DragEvent) => {\n // Only deactivate once we've left all children\n globalDragTargetsRef.current = globalDragTargetsRef.current.filter(el => el !== event.target && el !== null);\n\n if (globalDragTargetsRef.current.length > 0) {\n return;\n }\n\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDragEnd = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n const onDocumentDropGlobal = () => {\n globalDragTargetsRef.current = [];\n dispatch({isDragGlobal: false, type: \"setDragGlobal\"});\n };\n\n document.addEventListener(\"dragenter\", onDocumentDragEnter, false);\n document.addEventListener(\"dragleave\", onDocumentDragLeave, false);\n document.addEventListener(\"dragend\", onDocumentDragEnd, false);\n document.addEventListener(\"drop\", onDocumentDropGlobal, false);\n\n return () => {\n document.removeEventListener(\"dragenter\", onDocumentDragEnter);\n document.removeEventListener(\"dragleave\", onDocumentDragLeave);\n document.removeEventListener(\"dragend\", onDocumentDragEnd);\n document.removeEventListener(\"drop\", onDocumentDropGlobal);\n };\n }, [rootRef]);\n\n // Auto focus the root when autoFocus is true\n useEffect(() => {\n if (!disabled && autoFocus && rootRef.current) {\n rootRef.current.focus();\n }\n return () => {};\n }, [rootRef, autoFocus, disabled]);\n\n const onErrCb = useCallback(\n (e: Error) => {\n if (onError) {\n onError(e);\n } else {\n // Let the user know something's gone wrong if they haven't provided the onError cb.\n console.error(e);\n }\n },\n [onError]\n );\n\n const onDragEnterCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n // Ignore drags onto the dropzone while the file picker dialog is open: the page underneath a\n // live picker shouldn't react to (or accept) dropped files. See #1455. preventDefault() above\n // still runs so the browser doesn't try to open/navigate to a dropped file.\n if (isFileDialogActiveRef.current) {\n return;\n }\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 // During a drag we only have DataTransferItems (MIME type, no name/size), so the\n // custom validator can't run yet - a validator-configured dropzone is \"unknown\" until\n // drop rather than a misleading accept/reject. The verdict and rejection details come\n // from one evaluation so the two states cannot disagree.\n const evaluation =\n files.length > 0\n ? evaluateDragFiles({\n files: files as Array<FileWithPath | DataTransferItem>,\n accept: acceptAttr,\n minSize,\n maxSize,\n multiple,\n maxFiles,\n validator,\n getErrorMessage\n })\n : null;\n\n dispatch({\n isDragAccept: evaluation?.verdict === \"accept\",\n isDragReject: evaluation?.verdict === \"reject\",\n isDragUnknown: evaluation?.verdict === \"unknown\",\n isDragActive: true,\n dragFileRejections: evaluation?.rejections ?? [],\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 getErrorMessage\n ]\n );\n\n const onDragOverCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n // Ignore drags over the dropzone while the file picker dialog is open. See #1455.\n if (isFileDialogActiveRef.current) {\n return false;\n }\n\n const hasFiles = isEvtWithFiles(event);\n if (hasFiles && event.dataTransfer) {\n try {\n event.dataTransfer.dropEffect = \"copy\";\n } catch {\n /* no-op */\n }\n }\n\n if (hasFiles && onDragOver) {\n onDragOver(event);\n }\n\n return false;\n },\n [onDragOver, noDragEventsBubbling]\n );\n\n const onDragLeaveCb = useCallback(\n (event: any) => {\n event.preventDefault();\n event.persist?.();\n stopPropagation(event);\n\n // Only deactivate once the dropzone and all children have been left\n const targets = dragTargetsRef.current.filter(target => rootRef.current?.contains(target as Node));\n // Make sure to remove a target present multiple times only once\n // (Firefox may fire dragenter/dragleave multiple times on the same element)\n const targetIdx = targets.indexOf(event.target);\n if (targetIdx !== -1) {\n targets.splice(targetIdx, 1);\n }\n dragTargetsRef.current = targets;\n if (targets.length > 0) {\n return;\n }\n\n dispatch({\n type: \"setDraggedFiles\",\n isDragActive: false,\n isDragAccept: false,\n isDragReject: false,\n isDragUnknown: false,\n dragFileRejections: []\n });\n\n if (isEvtWithFiles(event) && onDragLeave) {\n onDragLeave(event);\n }\n },\n [rootRef, onDragLeave, noDragEventsBubbling]\n );\n\n const setFiles = useCallback(\n async (files: FileWithPath[], event: any, signal: AbortSignal) => {\n const localizeError = (error: FileError, file: File): FileError =>\n getErrorMessage ? {...error, message: getErrorMessage(error, file)} : error;\n\n // Commit the per-file verdicts: split accepted/rejected, cap the surplus, update state and\n // fire the onDrop callbacks. Runs synchronously so nested-dropzone ordering is preserved on\n // the fast path (an onDrop handler calling stopPropagation must do so before a parent's onDrop\n // check - see the noDragEventsBubbling tests).\n const commit = (results: Array<PerFileResult>) => {\n const acceptedFiles: FileWithPath[] = [];\n const fileRejections: FileRejection[] = [];\n\n results.forEach(({file, accepted, acceptError, sizeMatch, sizeError, customErrors}) => {\n if (accepted && sizeMatch && !customErrors) {\n acceptedFiles.push(file);\n } else {\n let errors: Array<FileError | null> = [acceptError, sizeError];\n\n if (customErrors) {\n errors = errors.concat(customErrors);\n }\n\n fileRejections.push({\n file,\n errors: errors.filter((e): e is FileError => e != null).map(error => localizeError(error, file))\n });\n }\n });\n\n // Cap the accepted files at the configured limit and reject only the surplus (the files past\n // the limit) with a too-many-files error, instead of rejecting the whole batch. The limit is 1\n // when {multiple} is false, and {maxFiles} when {multiple} is true (0 means no limit). Files\n // that already failed the per-file checks above are in {fileRejections} and don't count here.\n // See https://github.com/react-dropzone/react-dropzone/issues/1355\n // and https://github.com/react-dropzone/react-dropzone/issues/1358\n const acceptedFilesLimit = multiple ? (maxFiles >= 1 ? maxFiles : Number.POSITIVE_INFINITY) : 1;\n if (acceptedFiles.length > acceptedFilesLimit) {\n const surplusFiles = acceptedFiles.splice(acceptedFilesLimit);\n surplusFiles.forEach(file => {\n fileRejections.push({file, errors: [localizeError(TOO_MANY_FILES_REJECTION, file)]});\n });\n }\n\n // Clears isProcessing back to false (see the reducer) in the same update that sets the files.\n dispatch({\n acceptedFiles,\n fileRejections,\n type: \"setFiles\"\n });\n\n if (onDrop) {\n onDrop(acceptedFiles, fileRejections, event);\n }\n\n if (fileRejections.length > 0 && onDropRejected) {\n onDropRejected(fileRejections, event);\n }\n\n if (acceptedFiles.length > 0 && onDropAccepted) {\n onDropAccepted(acceptedFiles, event);\n }\n };\n\n // Run the built-in checks synchronously and invoke the validator (which may return a value or\n // a Promise). customErrors is left as-is here so we can tell sync from async below.\n const pending = files.map(file => {\n const [accepted, acceptError] = fileAccepted(file, inputAcceptAttr);\n const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);\n const customErrors = validator ? validator(file) : null;\n return {file, accepted, acceptError, sizeMatch, sizeError, customErrors};\n });\n\n // Callers check signal.aborted right before invoking setFiles (synchronously, no await in\n // between), so this run is guaranteed live here - the supersession guards below only matter\n // after we await the validator.\n\n // Fast path: no validator, or a synchronous one. Commit synchronously - no extra microtask\n // hop, so nested-dropzone ordering is preserved (an onDrop handler calling stopPropagation\n // must run before a parent's onDrop check - see the noDragEventsBubbling tests). commit's\n // dispatch also clears isProcessing.\n if (!pending.some(({customErrors}) => isThenable(customErrors))) {\n commit(pending as Array<PerFileResult>);\n return;\n }\n\n // Async path: at least one validator returned a Promise. isProcessing is already on (set when\n // the run began, before getFilesFromEvent); keep guarding against supersession while we await.\n let results: Array<PerFileResult>;\n try {\n results = await Promise.all(\n pending.map(async ({customErrors, ...rest}) => ({...rest, customErrors: await customErrors}))\n );\n } catch (e) {\n // A validator threw/rejected. If a newer run already superseded this one, let it own the\n // state; otherwise clear the processing flag and report the error via onError.\n if (!signal.aborted) {\n endProcessing(signal);\n onErrCb(e as Error);\n }\n return;\n }\n\n // A newer drop landed while we were validating - discard these stale results.\n if (signal.aborted) {\n return;\n }\n\n commit(results);\n },\n [\n dispatch,\n multiple,\n inputAcceptAttr,\n minSize,\n maxSize,\n maxFiles,\n onDrop,\n onDropAccepted,\n onDropRejected,\n validator,\n getErrorMessage,\n onErrCb,\n endProcessing\n ]\n );\n\n const onDropCb = useCallback(\n (event: any) => {\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n dragTargetsRef.current = [];\n\n // Ignore a drop landing on the dropzone while the file picker dialog is open (see #1455).\n // Guard on {event.dataTransfer} so only real drag-drops are suppressed: the input's change\n // event (a file picked from the dialog) also runs through here while the dialog is still\n // flagged active, and that path must keep working. Returning before the reset below leaves\n // the dialog flag intact.\n if (isFileDialogActiveRef.current && event.dataTransfer) {\n return;\n }\n\n // Clear drag state before we begin processing so beginProcessing's isProcessing isn't reset.\n dispatch({type: \"reset\"});\n\n if (isEvtWithFiles(event)) {\n // Processing spans reading the files (getFilesFromEvent) and running the validator.\n const signal = beginProcessing();\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n // A newer drop superseded this one while reading files - it owns isProcessing now.\n if (signal.aborted) {\n return;\n }\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n endProcessing(signal);\n return;\n }\n // setFiles handles validator errors internally (routing them to onError); the outer\n // catch here only fires for a getFilesFromEvent failure.\n return setFiles(files as FileWithPath[], event, signal);\n })\n .catch(e => {\n if (!signal.aborted) {\n endProcessing(signal);\n onErrCb(e);\n }\n });\n }\n },\n [getFilesFromEvent, setFiles, onErrCb, noDragEventsBubbling, beginProcessing, endProcessing]\n );\n\n // Cb to add files pasted into the dropzone (e.g. a screenshot pasted with Ctrl/Cmd+V). Fires when\n // the root - or a focused descendant, so a child <textarea> works too - receives a paste. Reuses\n // the same read/validate/onDrop pipeline as a drop.\n const onPasteCb = useCallback(\n (event: any) => {\n // Only act on a paste that carries files. Bail before preventDefault() for text/other pastes\n // so pasting into a child input keeps working normally.\n if (!isEvtWithFiles(event)) {\n return;\n }\n event.preventDefault();\n // Persist here because we need the event later after getFilesFromEvent() is done\n event.persist?.();\n stopPropagation(event);\n\n // Processing spans reading the files (getFilesFromEvent) and running the validator.\n const signal = beginProcessing();\n Promise.resolve(getFilesFromEvent(event))\n .then(files => {\n // A newer drop/paste superseded this one while reading files - it owns isProcessing now.\n if (signal.aborted) {\n return;\n }\n if (isPropagationStopped(event) && !noDragEventsBubbling) {\n endProcessing(signal);\n return;\n }\n return setFiles(files as FileWithPath[], event, signal);\n })\n .catch(e => {\n if (!signal.aborted) {\n endProcessing(signal);\n onErrCb(e);\n }\n });\n },\n [getFilesFromEvent, setFiles, onErrCb, noDragEventsBubbling, beginProcessing, endProcessing]\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 // Set once the user has picked file(s); processing then spans reading them (getFilesFromEvent)\n // and running the validator. Picker rejections (cancel, security) happen before this, so it\n // stays undefined there and no processing state is touched.\n let signal: AbortSignal | undefined;\n (window as any)\n .showOpenFilePicker(opts)\n .then((handles: any) => {\n signal = beginProcessing();\n return getFilesFromEvent(handles);\n })\n .then((files: Array<File | DataTransferItem>) => {\n // Close the dialog as soon as we have the selection; validation runs afterwards and is\n // reflected by isProcessing rather than by keeping the dialog \"active\".\n dispatch({type: \"closeDialog\"});\n // A drop elsewhere superseded this selection while reading files - it owns isProcessing.\n if (signal!.aborted) {\n return;\n }\n return setFiles(files as FileWithPath[], null, signal!);\n })\n .catch((e: any) => {\n // Clear any processing this run started (e.g. a getFilesFromEvent failure).\n if (signal) {\n endProcessing(signal);\n }\n // AbortError means the user canceled\n if (isAbort(e)) {\n onFileDialogCancelCb(e);\n dispatch({type: \"closeDialog\"});\n } else if (isSecurityError(e) || isNotAllowedError(e)) {\n // The FS access API is unusable here: either the context forbids it (SecurityError,\n // e.g. CORS) or the browser/platform blocked the picker (NotAllowedError, e.g. Edge\n // for Business - see https://github.com/react-dropzone/react-dropzone/issues/1429).\n // Stop using it and fall back to the native <input>.\n fsAccessApiWorksRef.current = false;\n if (inputRef.current) {\n inputRef.current.value = \"\";\n inputRef.current.click();\n } else {\n onErrCb(\n new Error(\n \"Cannot open the file picker because the https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API is not supported and no <input> was provided.\"\n )\n );\n }\n } else {\n onErrCb(e);\n }\n });\n return;\n }\n\n if (inputRef.current) {\n dispatch({type: \"openDialog\"});\n onFileDialogOpenCb();\n inputRef.current.value = \"\";\n inputRef.current.click();\n }\n }, [\n dispatch,\n onFileDialogOpenCb,\n onFileDialogCancelCb,\n useFsAccessApi,\n setFiles,\n onErrCb,\n pickerTypes,\n multiple,\n beginProcessing,\n endProcessing\n ]);\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 composePasteHandler = (fn: any) => {\n return noPaste ? 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 onPaste,\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 onPaste: composePasteHandler(composeEventHandlers(onPaste, onPasteCb)),\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 onPasteCb,\n noKeyboard,\n noDrag,\n noPaste,\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 // Hide the input without taking it out of flow. A visually-hidden input with\n // {position: absolute} makes the browser scroll the page to it whenever it gets\n // focus (e.g. inside a collapsed accordion), see #1413. Keeping it in flow as a\n // zero-size, transparent block avoids that while staying focusable so a {required}\n // input still triggers form validation, see #1268. Don't use {display: none} or\n // {visibility: hidden}: those make the input unfocusable and reintroduce #1268.\n style: {\n border: 0,\n display: \"block\",\n height: 0,\n margin: 0,\n opacity: 0,\n overflow: \"hidden\",\n padding: 0,\n width: 0\n },\n onChange: composeHandler(composeEventHandlers(onChange, onDropCb)),\n onClick: composeHandler(composeEventHandlers(onClick, onInputElementClick)),\n tabIndex: -1,\n [refKey]: inputRef\n };\n\n return {\n ...inputProps,\n ...rest\n };\n },\n [inputRef, accept, multiple, onDropCb, disabled]\n );\n\n return {\n ...state,\n isFocused: isFocused && !disabled,\n getRootProps,\n getInputProps,\n rootRef,\n inputRef,\n open: composeHandler(openFileDialog)\n } as unknown as DropzoneState;\n}\n\nfunction reducer(state: DropzoneInternalState, action: any): DropzoneInternalState {\n switch (action.type) {\n case \"focus\":\n return {\n ...state,\n isFocused: true\n };\n case \"blur\":\n return {\n ...state,\n isFocused: false\n };\n case \"openDialog\":\n return {\n ...initialState,\n isFileDialogActive: true\n };\n case \"closeDialog\":\n return {\n ...state,\n isFileDialogActive: false\n };\n case \"setDraggedFiles\":\n return {\n ...state,\n isDragActive: action.isDragActive,\n isDragAccept: action.isDragAccept,\n isDragReject: action.isDragReject,\n isDragUnknown: action.isDragUnknown,\n dragFileRejections: action.dragFileRejections\n };\n case \"setProcessing\":\n return {\n ...state,\n isProcessing: action.isProcessing\n };\n case \"setFiles\":\n return {\n ...state,\n acceptedFiles: action.acceptedFiles,\n fileRejections: action.fileRejections,\n dragFileRejections: [],\n isProcessing: false,\n isDragReject: false,\n isDragUnknown: false\n };\n case \"setDragGlobal\":\n return {\n ...state,\n isDragGlobal: action.isDragGlobal\n };\n case \"reset\":\n return {\n ...initialState\n };\n default:\n return state;\n }\n}\n\nfunction noop() {}\n"],"mappings":"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"}