react-dropzone 12.0.6 → 14.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -19
- package/dist/es/index.js +106 -74
- package/dist/es/utils/index.js +88 -20
- package/dist/index.js +3 -3
- package/examples/accept/README.md +19 -16
- package/examples/pintura/README.md +3 -1
- package/examples/previews/README.md +3 -1
- package/examples/styling/README.md +2 -2
- package/package.json +8 -8
- package/src/index.js +116 -72
- package/src/index.spec.js +599 -616
- package/src/utils/index.js +82 -26
- package/src/utils/index.spec.js +124 -58
- package/typings/react-dropzone.d.ts +5 -2
- package/typings/tests/accept.tsx +3 -37
- package/typings/tests/all.tsx +3 -1
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
By providing `accept` prop you can make the dropzone accept specific file types and reject the others.
|
|
2
2
|
|
|
3
|
-
The value must be a
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
The value must be an object with a common [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types) as keys and an array of file extensions as values (similar to [showOpenFilePicker](https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker)'s types `accept` option).
|
|
4
|
+
```js static
|
|
5
|
+
useDropzone({
|
|
6
|
+
accept: {
|
|
7
|
+
'image/png': ['.png'],
|
|
8
|
+
'text/html': ['.html', '.htm'],
|
|
9
|
+
}
|
|
10
|
+
})
|
|
11
|
+
```
|
|
9
12
|
|
|
10
13
|
For more information see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input.
|
|
11
14
|
|
|
12
|
-
**IMPORTANT** As of [v12.0.0](https://github.com/react-dropzone/react-dropzone/releases/tag/v12.0.0), there has been some changes that affect how `accept` works.
|
|
13
|
-
See [file dialog cancel callback](../../README.md#file-dialog-cancel-callback) to read more about why this change was introduced. In summary:
|
|
14
|
-
1. In browsers that **do not support** the FS access API, the `accept` attr works exactly the same as in previous versions of react-dropozone, for both file picker and dag 'n' drop
|
|
15
|
-
2. In browsers that **support** the FS access API, when passing file extensions to `accept` (e.g `".jpg,.png"`), the file picker will not apply those filters, but drag 'n' drop will - though, the [browser limitations](#browser-limitations) described in this document still apply
|
|
16
|
-
3. If you want the same behaviour in all browsers, regardless of using the FS access API or not, you need to use MIME types - [browser limitations](#browser-limitations) still apply
|
|
17
|
-
4. The use of FS access API can be turned off via `useDropzone({useFsAccessApi: false})`
|
|
18
|
-
|
|
19
15
|
```jsx harmony
|
|
20
16
|
import React from 'react';
|
|
21
17
|
import {useDropzone} from 'react-dropzone';
|
|
@@ -27,7 +23,10 @@ function Accept(props) {
|
|
|
27
23
|
getRootProps,
|
|
28
24
|
getInputProps
|
|
29
25
|
} = useDropzone({
|
|
30
|
-
accept:
|
|
26
|
+
accept: {
|
|
27
|
+
'image/jpeg': [],
|
|
28
|
+
'image/png': []
|
|
29
|
+
}
|
|
31
30
|
});
|
|
32
31
|
|
|
33
32
|
const acceptedFileItems = acceptedFiles.map(file => (
|
|
@@ -85,7 +84,9 @@ function Accept(props) {
|
|
|
85
84
|
isDragAccept,
|
|
86
85
|
isDragReject
|
|
87
86
|
} = useDropzone({
|
|
88
|
-
accept:
|
|
87
|
+
accept: {
|
|
88
|
+
'image/jpeg': ['.jpeg', '.png']
|
|
89
|
+
}
|
|
89
90
|
});
|
|
90
91
|
|
|
91
92
|
return (
|
|
@@ -117,7 +118,9 @@ function Accept(props) {
|
|
|
117
118
|
isDragAccept,
|
|
118
119
|
isDragReject
|
|
119
120
|
} = useDropzone({
|
|
120
|
-
accept:
|
|
121
|
+
accept: {
|
|
122
|
+
'image/*': ['.jpeg', '.png']
|
|
123
|
+
}
|
|
121
124
|
});
|
|
122
125
|
|
|
123
126
|
return (
|
|
@@ -77,7 +77,9 @@ const editImage = (image, done) => {
|
|
|
77
77
|
function App() {
|
|
78
78
|
const [files, setFiles] = useState([]);
|
|
79
79
|
const { getRootProps, getInputProps } = useDropzone({
|
|
80
|
-
accept:
|
|
80
|
+
accept: {
|
|
81
|
+
'image/*': [],
|
|
82
|
+
},
|
|
81
83
|
onDrop: (acceptedFiles) => {
|
|
82
84
|
setFiles(
|
|
83
85
|
acceptedFiles.map((file) =>
|
|
@@ -41,7 +41,9 @@ const img = {
|
|
|
41
41
|
function Previews(props) {
|
|
42
42
|
const [files, setFiles] = useState([]);
|
|
43
43
|
const {getRootProps, getInputProps} = useDropzone({
|
|
44
|
-
accept:
|
|
44
|
+
accept: {
|
|
45
|
+
'image/*': []
|
|
46
|
+
},
|
|
45
47
|
onDrop: acceptedFiles => {
|
|
46
48
|
setFiles(acceptedFiles.map(file => Object.assign(file, {
|
|
47
49
|
preview: URL.createObjectURL(file)
|
|
@@ -41,7 +41,7 @@ function StyledDropzone(props) {
|
|
|
41
41
|
isFocused,
|
|
42
42
|
isDragAccept,
|
|
43
43
|
isDragReject
|
|
44
|
-
} = useDropzone({accept: 'image/*'});
|
|
44
|
+
} = useDropzone({accept: {'image/*': []}});
|
|
45
45
|
|
|
46
46
|
const style = useMemo(() => ({
|
|
47
47
|
...baseStyle,
|
|
@@ -110,7 +110,7 @@ function StyledDropzone(props) {
|
|
|
110
110
|
isFocused,
|
|
111
111
|
isDragAccept,
|
|
112
112
|
isDragReject
|
|
113
|
-
} = useDropzone({accept: 'image/*'});
|
|
113
|
+
} = useDropzone({accept: {'image/*': []}});
|
|
114
114
|
|
|
115
115
|
return (
|
|
116
116
|
<div className="container">
|
package/package.json
CHANGED
|
@@ -95,11 +95,11 @@
|
|
|
95
95
|
],
|
|
96
96
|
"license": "MIT",
|
|
97
97
|
"peerDependencies": {
|
|
98
|
-
"react": ">= 16.8"
|
|
98
|
+
"react": ">= 16.8 || 18.0.0"
|
|
99
99
|
},
|
|
100
100
|
"dependencies": {
|
|
101
101
|
"attr-accept": "^2.2.2",
|
|
102
|
-
"file-selector": "^0.
|
|
102
|
+
"file-selector": "^0.5.0",
|
|
103
103
|
"prop-types": "^15.8.1"
|
|
104
104
|
},
|
|
105
105
|
"devDependencies": {
|
|
@@ -129,8 +129,8 @@
|
|
|
129
129
|
"@size-limit/webpack-why": "^7.0.5",
|
|
130
130
|
"@testing-library/dom": "^8.11.3",
|
|
131
131
|
"@testing-library/jest-dom": "^5.16.1",
|
|
132
|
-
"@testing-library/react": "^
|
|
133
|
-
"@testing-library/react-hooks": "^
|
|
132
|
+
"@testing-library/react": "^13.1.1",
|
|
133
|
+
"@testing-library/react-hooks": "^8.0.0",
|
|
134
134
|
"@types/react": "^17.0.0",
|
|
135
135
|
"@types/react-dom": "^17.0.0",
|
|
136
136
|
"@typescript-eslint/eslint-plugin": "^5.10.1",
|
|
@@ -156,10 +156,10 @@
|
|
|
156
156
|
"markdownlint-cli": "^0.30.0",
|
|
157
157
|
"pinst": "^2.1.6",
|
|
158
158
|
"prettier": "^2.5.1",
|
|
159
|
-
"react": "^
|
|
160
|
-
"react-dom": "^
|
|
159
|
+
"react": "^18.1.0",
|
|
160
|
+
"react-dom": "^18.1.0",
|
|
161
161
|
"react-styleguidist": "^11.2.0",
|
|
162
|
-
"react-test-renderer": "^
|
|
162
|
+
"react-test-renderer": "^18.1.0",
|
|
163
163
|
"rimraf": "^3.0.2",
|
|
164
164
|
"rollup": "^2.66.1",
|
|
165
165
|
"rollup-plugin-terser": "^7.0.2",
|
|
@@ -171,7 +171,7 @@
|
|
|
171
171
|
"webpack-blocks": "^2.1.0"
|
|
172
172
|
},
|
|
173
173
|
"typings": "typings/react-dropzone.d.ts",
|
|
174
|
-
"version": "
|
|
174
|
+
"version": "14.0.0",
|
|
175
175
|
"engines": {
|
|
176
176
|
"node": ">= 10.13"
|
|
177
177
|
},
|
package/src/index.js
CHANGED
|
@@ -12,11 +12,11 @@ import React, {
|
|
|
12
12
|
import PropTypes from "prop-types";
|
|
13
13
|
import { fromEvent } from "file-selector";
|
|
14
14
|
import {
|
|
15
|
+
acceptPropAsAcceptAttr,
|
|
15
16
|
allFilesAccepted,
|
|
16
17
|
composeEventHandlers,
|
|
17
18
|
fileAccepted,
|
|
18
19
|
fileMatchSize,
|
|
19
|
-
filePickerOptionsTypes,
|
|
20
20
|
canUseFileSystemAccessAPI,
|
|
21
21
|
isAbort,
|
|
22
22
|
isEvtWithFiles,
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
isPropagationStopped,
|
|
25
25
|
isSecurityError,
|
|
26
26
|
onDocumentDragOver,
|
|
27
|
+
pickerOptionsFromAccept,
|
|
27
28
|
TOO_MANY_FILES_REJECTION,
|
|
28
29
|
} from "./utils/index";
|
|
29
30
|
|
|
@@ -84,7 +85,6 @@ Dropzone.propTypes = {
|
|
|
84
85
|
* @param {boolean} params.isDragActive Active drag is in progress
|
|
85
86
|
* @param {boolean} params.isDragAccept Dragged files are accepted
|
|
86
87
|
* @param {boolean} params.isDragReject Some dragged files are rejected
|
|
87
|
-
* @param {File[]} params.draggedFiles Files in active drag
|
|
88
88
|
* @param {File[]} params.acceptedFiles Accepted files
|
|
89
89
|
* @param {FileRejection[]} params.fileRejections Rejected files and why they were rejected
|
|
90
90
|
*/
|
|
@@ -92,16 +92,12 @@ Dropzone.propTypes = {
|
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
94
|
* Set accepted file types.
|
|
95
|
-
*
|
|
95
|
+
* Checkout https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker types option for more information.
|
|
96
96
|
* Keep in mind that mime type determination is not reliable across platforms. CSV files,
|
|
97
97
|
* for example, are reported as text/plain under macOS but as application/vnd.ms-excel under
|
|
98
|
-
* Windows. In some cases there might not be a mime type set at all.
|
|
99
|
-
* See: https://github.com/react-dropzone/react-dropzone/issues/276
|
|
98
|
+
* Windows. In some cases there might not be a mime type set at all (https://github.com/react-dropzone/react-dropzone/issues/276).
|
|
100
99
|
*/
|
|
101
|
-
accept: PropTypes.
|
|
102
|
-
PropTypes.string,
|
|
103
|
-
PropTypes.arrayOf(PropTypes.string),
|
|
104
|
-
]),
|
|
100
|
+
accept: PropTypes.objectOf(PropTypes.arrayOf(PropTypes.string)),
|
|
105
101
|
|
|
106
102
|
/**
|
|
107
103
|
* Allow drag 'n' drop (or selection from the file dialog) of multiple files
|
|
@@ -248,6 +244,13 @@ Dropzone.propTypes = {
|
|
|
248
244
|
*/
|
|
249
245
|
onDropRejected: PropTypes.func,
|
|
250
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Cb for when there's some error from any of the promises.
|
|
249
|
+
*
|
|
250
|
+
* @param {Error} error
|
|
251
|
+
*/
|
|
252
|
+
onError: PropTypes.func,
|
|
253
|
+
|
|
251
254
|
/**
|
|
252
255
|
* Custom validation function
|
|
253
256
|
* @param {File} file
|
|
@@ -306,29 +309,33 @@ export default Dropzone;
|
|
|
306
309
|
*/
|
|
307
310
|
|
|
308
311
|
/**
|
|
309
|
-
* An object with the current dropzone state
|
|
312
|
+
* An object with the current dropzone state.
|
|
310
313
|
*
|
|
311
314
|
* @typedef {object} DropzoneState
|
|
312
|
-
* @property {Function} getRootProps Returns the props you should apply to the root drop container you render
|
|
313
|
-
* @property {Function} getInputProps Returns the props you should apply to hidden file input you render
|
|
314
|
-
* @property {Function} open Open the native file selection dialog
|
|
315
315
|
* @property {boolean} isFocused Dropzone area is in focus
|
|
316
316
|
* @property {boolean} isFileDialogActive File dialog is opened
|
|
317
317
|
* @property {boolean} isDragActive Active drag is in progress
|
|
318
318
|
* @property {boolean} isDragAccept Dragged files are accepted
|
|
319
319
|
* @property {boolean} isDragReject Some dragged files are rejected
|
|
320
|
-
* @property {File[]} draggedFiles Files in active drag
|
|
321
320
|
* @property {File[]} acceptedFiles Accepted files
|
|
322
321
|
* @property {FileRejection[]} fileRejections Rejected files and why they were rejected
|
|
323
322
|
*/
|
|
324
323
|
|
|
324
|
+
/**
|
|
325
|
+
* An object with the dropzone methods.
|
|
326
|
+
*
|
|
327
|
+
* @typedef {object} DropzoneMethods
|
|
328
|
+
* @property {Function} getRootProps Returns the props you should apply to the root drop container you render
|
|
329
|
+
* @property {Function} getInputProps Returns the props you should apply to hidden file input you render
|
|
330
|
+
* @property {Function} open Open the native file selection dialog
|
|
331
|
+
*/
|
|
332
|
+
|
|
325
333
|
const initialState = {
|
|
326
334
|
isFocused: false,
|
|
327
335
|
isFileDialogActive: false,
|
|
328
336
|
isDragActive: false,
|
|
329
337
|
isDragAccept: false,
|
|
330
338
|
isDragReject: false,
|
|
331
|
-
draggedFiles: [],
|
|
332
339
|
acceptedFiles: [],
|
|
333
340
|
fileRejections: [],
|
|
334
341
|
};
|
|
@@ -355,12 +362,11 @@ const initialState = {
|
|
|
355
362
|
* @function useDropzone
|
|
356
363
|
*
|
|
357
364
|
* @param {object} props
|
|
358
|
-
* @param {
|
|
359
|
-
*
|
|
365
|
+
* @param {import("./utils").AcceptProp} [props.accept] Set accepted file types.
|
|
366
|
+
* Checkout https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker types option for more information.
|
|
360
367
|
* Keep in mind that mime type determination is not reliable across platforms. CSV files,
|
|
361
368
|
* for example, are reported as text/plain under macOS but as application/vnd.ms-excel under
|
|
362
|
-
* Windows. In some cases there might not be a mime type set at all.
|
|
363
|
-
* See: https://github.com/react-dropzone/react-dropzone/issues/276
|
|
369
|
+
* Windows. In some cases there might not be a mime type set at all (https://github.com/react-dropzone/react-dropzone/issues/276).
|
|
364
370
|
* @param {boolean} [props.multiple=true] Allow drag 'n' drop (or selection from the file dialog) of multiple files
|
|
365
371
|
* @param {boolean} [props.preventDropOnDocument=true] If false, allow dropped items to take over the current browser window
|
|
366
372
|
* @param {boolean} [props.noClick=false] If true, disables click to open the native file selection dialog
|
|
@@ -383,7 +389,7 @@ const initialState = {
|
|
|
383
389
|
* Note that this callback is invoked after the `getFilesFromEvent` callback is done.
|
|
384
390
|
*
|
|
385
391
|
* Files are accepted or rejected based on the `accept`, `multiple`, `minSize` and `maxSize` props.
|
|
386
|
-
* `accept` must be a valid [MIME type](http://www.iana.org/assignments/media-types/media-types.xhtml) according to [input element specification](https://www.w3.org/wiki/HTML/Elements/input/file)
|
|
392
|
+
* `accept` must be an object with keys as a valid [MIME type](http://www.iana.org/assignments/media-types/media-types.xhtml) according to [input element specification](https://www.w3.org/wiki/HTML/Elements/input/file) and the value an array of file extensions (optional).
|
|
387
393
|
* If `multiple` is set to false and additional files are dropped,
|
|
388
394
|
* all files besides the first will be rejected.
|
|
389
395
|
* Any file which does not have a size in the [`minSize`, `maxSize`] range, will be rejected as well.
|
|
@@ -405,10 +411,11 @@ const initialState = {
|
|
|
405
411
|
* ```
|
|
406
412
|
* @param {dropAcceptedCb} [props.onDropAccepted]
|
|
407
413
|
* @param {dropRejectedCb} [props.onDropRejected]
|
|
414
|
+
* @param {(error: Error) => void} [props.onError]
|
|
408
415
|
*
|
|
409
|
-
* @returns {DropzoneState}
|
|
416
|
+
* @returns {DropzoneState & DropzoneMethods}
|
|
410
417
|
*/
|
|
411
|
-
export function useDropzone(
|
|
418
|
+
export function useDropzone(props = {}) {
|
|
412
419
|
const {
|
|
413
420
|
accept,
|
|
414
421
|
disabled,
|
|
@@ -431,12 +438,16 @@ export function useDropzone(options = {}) {
|
|
|
431
438
|
noKeyboard,
|
|
432
439
|
noDrag,
|
|
433
440
|
noDragEventsBubbling,
|
|
441
|
+
onError,
|
|
434
442
|
validator,
|
|
435
443
|
} = {
|
|
436
444
|
...defaultProps,
|
|
437
|
-
...
|
|
445
|
+
...props,
|
|
438
446
|
};
|
|
439
447
|
|
|
448
|
+
const acceptAttr = useMemo(() => acceptPropAsAcceptAttr(accept), [accept]);
|
|
449
|
+
const pickerTypes = useMemo(() => pickerOptionsFromAccept(accept), [accept]);
|
|
450
|
+
|
|
440
451
|
const onFileDialogOpenCb = useMemo(
|
|
441
452
|
() => (typeof onFileDialogOpen === "function" ? onFileDialogOpen : noop),
|
|
442
453
|
[onFileDialogOpen]
|
|
@@ -451,7 +462,7 @@ export function useDropzone(options = {}) {
|
|
|
451
462
|
const inputRef = useRef(null);
|
|
452
463
|
|
|
453
464
|
const [state, dispatch] = useReducer(reducer, initialState);
|
|
454
|
-
const { isFocused, isFileDialogActive
|
|
465
|
+
const { isFocused, isFileDialogActive } = state;
|
|
455
466
|
|
|
456
467
|
const fsAccessApiWorksRef = useRef(
|
|
457
468
|
typeof window !== "undefined" &&
|
|
@@ -507,6 +518,18 @@ export function useDropzone(options = {}) {
|
|
|
507
518
|
};
|
|
508
519
|
}, [rootRef, preventDropOnDocument]);
|
|
509
520
|
|
|
521
|
+
const onErrCb = useCallback(
|
|
522
|
+
(e) => {
|
|
523
|
+
if (onError) {
|
|
524
|
+
onError(e);
|
|
525
|
+
} else {
|
|
526
|
+
// Let the user know something's gone wrong if they haven't provided the onError cb.
|
|
527
|
+
console.error(e);
|
|
528
|
+
}
|
|
529
|
+
},
|
|
530
|
+
[onError]
|
|
531
|
+
);
|
|
532
|
+
|
|
510
533
|
const onDragEnterCb = useCallback(
|
|
511
534
|
(event) => {
|
|
512
535
|
event.preventDefault();
|
|
@@ -517,24 +540,50 @@ export function useDropzone(options = {}) {
|
|
|
517
540
|
dragTargetsRef.current = [...dragTargetsRef.current, event.target];
|
|
518
541
|
|
|
519
542
|
if (isEvtWithFiles(event)) {
|
|
520
|
-
Promise.resolve(getFilesFromEvent(event))
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
dispatch({
|
|
526
|
-
draggedFiles,
|
|
527
|
-
isDragActive: true,
|
|
528
|
-
type: "setDraggedFiles",
|
|
529
|
-
});
|
|
543
|
+
Promise.resolve(getFilesFromEvent(event))
|
|
544
|
+
.then((files) => {
|
|
545
|
+
if (isPropagationStopped(event) && !noDragEventsBubbling) {
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
530
548
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
549
|
+
const fileCount = files.length;
|
|
550
|
+
const isDragAccept =
|
|
551
|
+
fileCount > 0 &&
|
|
552
|
+
allFilesAccepted({
|
|
553
|
+
files,
|
|
554
|
+
accept: acceptAttr,
|
|
555
|
+
minSize,
|
|
556
|
+
maxSize,
|
|
557
|
+
multiple,
|
|
558
|
+
maxFiles,
|
|
559
|
+
});
|
|
560
|
+
const isDragReject = fileCount > 0 && !isDragAccept;
|
|
561
|
+
|
|
562
|
+
dispatch({
|
|
563
|
+
isDragAccept,
|
|
564
|
+
isDragReject,
|
|
565
|
+
isDragActive: true,
|
|
566
|
+
type: "setDraggedFiles",
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
if (onDragEnter) {
|
|
570
|
+
onDragEnter(event);
|
|
571
|
+
}
|
|
572
|
+
})
|
|
573
|
+
.catch((e) => onErrCb(e));
|
|
535
574
|
}
|
|
536
575
|
},
|
|
537
|
-
[
|
|
576
|
+
[
|
|
577
|
+
getFilesFromEvent,
|
|
578
|
+
onDragEnter,
|
|
579
|
+
onErrCb,
|
|
580
|
+
noDragEventsBubbling,
|
|
581
|
+
acceptAttr,
|
|
582
|
+
minSize,
|
|
583
|
+
maxSize,
|
|
584
|
+
multiple,
|
|
585
|
+
maxFiles,
|
|
586
|
+
]
|
|
538
587
|
);
|
|
539
588
|
|
|
540
589
|
const onDragOverCb = useCallback(
|
|
@@ -581,9 +630,10 @@ export function useDropzone(options = {}) {
|
|
|
581
630
|
}
|
|
582
631
|
|
|
583
632
|
dispatch({
|
|
584
|
-
isDragActive: false,
|
|
585
633
|
type: "setDraggedFiles",
|
|
586
|
-
|
|
634
|
+
isDragActive: false,
|
|
635
|
+
isDragAccept: false,
|
|
636
|
+
isDragReject: false,
|
|
587
637
|
});
|
|
588
638
|
|
|
589
639
|
if (isEvtWithFiles(event) && onDragLeave) {
|
|
@@ -599,7 +649,7 @@ export function useDropzone(options = {}) {
|
|
|
599
649
|
const fileRejections = [];
|
|
600
650
|
|
|
601
651
|
files.forEach((file) => {
|
|
602
|
-
const [accepted, acceptError] = fileAccepted(file,
|
|
652
|
+
const [accepted, acceptError] = fileAccepted(file, acceptAttr);
|
|
603
653
|
const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);
|
|
604
654
|
const customErrors = validator ? validator(file) : null;
|
|
605
655
|
|
|
@@ -648,7 +698,7 @@ export function useDropzone(options = {}) {
|
|
|
648
698
|
[
|
|
649
699
|
dispatch,
|
|
650
700
|
multiple,
|
|
651
|
-
|
|
701
|
+
acceptAttr,
|
|
652
702
|
minSize,
|
|
653
703
|
maxSize,
|
|
654
704
|
maxFiles,
|
|
@@ -669,16 +719,18 @@ export function useDropzone(options = {}) {
|
|
|
669
719
|
dragTargetsRef.current = [];
|
|
670
720
|
|
|
671
721
|
if (isEvtWithFiles(event)) {
|
|
672
|
-
Promise.resolve(getFilesFromEvent(event))
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
722
|
+
Promise.resolve(getFilesFromEvent(event))
|
|
723
|
+
.then((files) => {
|
|
724
|
+
if (isPropagationStopped(event) && !noDragEventsBubbling) {
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
setFiles(files, event);
|
|
728
|
+
})
|
|
729
|
+
.catch((e) => onErrCb(e));
|
|
678
730
|
}
|
|
679
731
|
dispatch({ type: "reset" });
|
|
680
732
|
},
|
|
681
|
-
[getFilesFromEvent, setFiles, noDragEventsBubbling]
|
|
733
|
+
[getFilesFromEvent, setFiles, onErrCb, noDragEventsBubbling]
|
|
682
734
|
);
|
|
683
735
|
|
|
684
736
|
// Fn for opening the file dialog programmatically
|
|
@@ -691,7 +743,7 @@ export function useDropzone(options = {}) {
|
|
|
691
743
|
// https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker
|
|
692
744
|
const opts = {
|
|
693
745
|
multiple,
|
|
694
|
-
types:
|
|
746
|
+
types: pickerTypes,
|
|
695
747
|
};
|
|
696
748
|
window
|
|
697
749
|
.showOpenFilePicker(opts)
|
|
@@ -713,6 +765,8 @@ export function useDropzone(options = {}) {
|
|
|
713
765
|
inputRef.current.value = null;
|
|
714
766
|
inputRef.current.click();
|
|
715
767
|
}
|
|
768
|
+
} else {
|
|
769
|
+
onErrCb(e);
|
|
716
770
|
}
|
|
717
771
|
});
|
|
718
772
|
return;
|
|
@@ -730,7 +784,8 @@ export function useDropzone(options = {}) {
|
|
|
730
784
|
onFileDialogCancelCb,
|
|
731
785
|
useFsAccessApi,
|
|
732
786
|
setFiles,
|
|
733
|
-
|
|
787
|
+
onErrCb,
|
|
788
|
+
pickerTypes,
|
|
734
789
|
multiple,
|
|
735
790
|
]);
|
|
736
791
|
|
|
@@ -859,7 +914,7 @@ export function useDropzone(options = {}) {
|
|
|
859
914
|
() =>
|
|
860
915
|
({ refKey = "ref", onChange, onClick, ...rest } = {}) => {
|
|
861
916
|
const inputProps = {
|
|
862
|
-
accept,
|
|
917
|
+
accept: acceptAttr,
|
|
863
918
|
multiple,
|
|
864
919
|
type: "file",
|
|
865
920
|
style: { display: "none" },
|
|
@@ -879,23 +934,8 @@ export function useDropzone(options = {}) {
|
|
|
879
934
|
[inputRef, accept, multiple, onDropCb, disabled]
|
|
880
935
|
);
|
|
881
936
|
|
|
882
|
-
const fileCount = draggedFiles.length;
|
|
883
|
-
const isDragAccept =
|
|
884
|
-
fileCount > 0 &&
|
|
885
|
-
allFilesAccepted({
|
|
886
|
-
files: draggedFiles,
|
|
887
|
-
accept,
|
|
888
|
-
minSize,
|
|
889
|
-
maxSize,
|
|
890
|
-
multiple,
|
|
891
|
-
maxFiles,
|
|
892
|
-
});
|
|
893
|
-
const isDragReject = fileCount > 0 && !isDragAccept;
|
|
894
|
-
|
|
895
937
|
return {
|
|
896
938
|
...state,
|
|
897
|
-
isDragAccept,
|
|
898
|
-
isDragReject,
|
|
899
939
|
isFocused: isFocused && !disabled,
|
|
900
940
|
getRootProps,
|
|
901
941
|
getInputProps,
|
|
@@ -905,6 +945,11 @@ export function useDropzone(options = {}) {
|
|
|
905
945
|
};
|
|
906
946
|
}
|
|
907
947
|
|
|
948
|
+
/**
|
|
949
|
+
* @param {DropzoneState} state
|
|
950
|
+
* @param {{type: string} & DropzoneState} action
|
|
951
|
+
* @returns {DropzoneState}
|
|
952
|
+
*/
|
|
908
953
|
function reducer(state, action) {
|
|
909
954
|
/* istanbul ignore next */
|
|
910
955
|
switch (action.type) {
|
|
@@ -929,12 +974,11 @@ function reducer(state, action) {
|
|
|
929
974
|
isFileDialogActive: false,
|
|
930
975
|
};
|
|
931
976
|
case "setDraggedFiles":
|
|
932
|
-
/* eslint no-case-declarations: 0 */
|
|
933
|
-
const { isDragActive, draggedFiles } = action;
|
|
934
977
|
return {
|
|
935
978
|
...state,
|
|
936
|
-
|
|
937
|
-
|
|
979
|
+
isDragActive: action.isDragActive,
|
|
980
|
+
isDragAccept: action.isDragAccept,
|
|
981
|
+
isDragReject: action.isDragReject,
|
|
938
982
|
};
|
|
939
983
|
case "setFiles":
|
|
940
984
|
return {
|