react-dropzone 13.0.0 → 14.1.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 -17
- package/dist/es/index.js +61 -35
- package/dist/index.js +3 -3
- package/package.json +7 -7
- package/src/__snapshots__/index.spec.js.snap +1 -1
- package/src/index.js +72 -34
- package/src/index.spec.js +455 -605
- package/typings/react-dropzone.d.ts +1 -1
package/README.md
CHANGED
|
@@ -230,7 +230,7 @@ dropzoneRef.open()
|
|
|
230
230
|
```js static
|
|
231
231
|
import React from 'react'
|
|
232
232
|
import Dropzone from 'react-dropzone'
|
|
233
|
-
import {act, fireEvent, render
|
|
233
|
+
import {act, fireEvent, render} from '@testing-library/react'
|
|
234
234
|
|
|
235
235
|
test('invoke onDragEnter when dragenter event occurs', async () => {
|
|
236
236
|
const file = new File([
|
|
@@ -248,25 +248,17 @@ test('invoke onDragEnter when dragenter event occurs', async () => {
|
|
|
248
248
|
)}
|
|
249
249
|
</Dropzone>
|
|
250
250
|
)
|
|
251
|
-
const { container
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
251
|
+
const { container } = render(ui)
|
|
252
|
+
|
|
253
|
+
await act(
|
|
254
|
+
() => fireEvent.dragEnter(
|
|
255
|
+
container.querySelector('div'),
|
|
256
|
+
data,
|
|
257
|
+
)
|
|
258
|
+
);
|
|
257
259
|
expect(onDragEnter).toHaveBeenCalled()
|
|
258
260
|
})
|
|
259
261
|
|
|
260
|
-
async function flushPromises(rerender, ui) {
|
|
261
|
-
await act(() => waitFor(() => rerender(ui)))
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
function dispatchEvt(node, type, data) {
|
|
265
|
-
const event = new Event(type, { bubbles: true })
|
|
266
|
-
Object.assign(event, data)
|
|
267
|
-
fireEvent(node, event)
|
|
268
|
-
}
|
|
269
|
-
|
|
270
262
|
function mockData(files) {
|
|
271
263
|
return {
|
|
272
264
|
dataTransfer: {
|
package/dist/es/index.js
CHANGED
|
@@ -86,7 +86,8 @@ var defaultProps = {
|
|
|
86
86
|
noDrag: false,
|
|
87
87
|
noDragEventsBubbling: false,
|
|
88
88
|
validator: null,
|
|
89
|
-
useFsAccessApi: true
|
|
89
|
+
useFsAccessApi: true,
|
|
90
|
+
autoFocus: false
|
|
90
91
|
};
|
|
91
92
|
Dropzone.defaultProps = defaultProps;
|
|
92
93
|
Dropzone.propTypes = {
|
|
@@ -102,7 +103,6 @@ Dropzone.propTypes = {
|
|
|
102
103
|
* @param {boolean} params.isDragActive Active drag is in progress
|
|
103
104
|
* @param {boolean} params.isDragAccept Dragged files are accepted
|
|
104
105
|
* @param {boolean} params.isDragReject Some dragged files are rejected
|
|
105
|
-
* @param {File[]} params.draggedFiles Files in active drag
|
|
106
106
|
* @param {File[]} params.acceptedFiles Accepted files
|
|
107
107
|
* @param {FileRejection[]} params.fileRejections Rejected files and why they were rejected
|
|
108
108
|
*/
|
|
@@ -192,6 +192,11 @@ Dropzone.propTypes = {
|
|
|
192
192
|
*/
|
|
193
193
|
useFsAccessApi: PropTypes.bool,
|
|
194
194
|
|
|
195
|
+
/**
|
|
196
|
+
* Set to true to focus the root element on render
|
|
197
|
+
*/
|
|
198
|
+
autoFocus: PropTypes.bool,
|
|
199
|
+
|
|
195
200
|
/**
|
|
196
201
|
* Cb for when the `dragenter` event occurs.
|
|
197
202
|
*
|
|
@@ -326,29 +331,33 @@ export default Dropzone;
|
|
|
326
331
|
*/
|
|
327
332
|
|
|
328
333
|
/**
|
|
329
|
-
* An object with the current dropzone state
|
|
334
|
+
* An object with the current dropzone state.
|
|
330
335
|
*
|
|
331
336
|
* @typedef {object} DropzoneState
|
|
332
|
-
* @property {Function} getRootProps Returns the props you should apply to the root drop container you render
|
|
333
|
-
* @property {Function} getInputProps Returns the props you should apply to hidden file input you render
|
|
334
|
-
* @property {Function} open Open the native file selection dialog
|
|
335
337
|
* @property {boolean} isFocused Dropzone area is in focus
|
|
336
338
|
* @property {boolean} isFileDialogActive File dialog is opened
|
|
337
339
|
* @property {boolean} isDragActive Active drag is in progress
|
|
338
340
|
* @property {boolean} isDragAccept Dragged files are accepted
|
|
339
341
|
* @property {boolean} isDragReject Some dragged files are rejected
|
|
340
|
-
* @property {File[]} draggedFiles Files in active drag
|
|
341
342
|
* @property {File[]} acceptedFiles Accepted files
|
|
342
343
|
* @property {FileRejection[]} fileRejections Rejected files and why they were rejected
|
|
343
344
|
*/
|
|
344
345
|
|
|
346
|
+
/**
|
|
347
|
+
* An object with the dropzone methods.
|
|
348
|
+
*
|
|
349
|
+
* @typedef {object} DropzoneMethods
|
|
350
|
+
* @property {Function} getRootProps Returns the props you should apply to the root drop container you render
|
|
351
|
+
* @property {Function} getInputProps Returns the props you should apply to hidden file input you render
|
|
352
|
+
* @property {Function} open Open the native file selection dialog
|
|
353
|
+
*/
|
|
354
|
+
|
|
345
355
|
var initialState = {
|
|
346
356
|
isFocused: false,
|
|
347
357
|
isFileDialogActive: false,
|
|
348
358
|
isDragActive: false,
|
|
349
359
|
isDragAccept: false,
|
|
350
360
|
isDragReject: false,
|
|
351
|
-
draggedFiles: [],
|
|
352
361
|
acceptedFiles: [],
|
|
353
362
|
fileRejections: []
|
|
354
363
|
};
|
|
@@ -393,6 +402,7 @@ var initialState = {
|
|
|
393
402
|
* @param {Function} [props.onFileDialogCancel] Cb for when closing the file dialog with no selection
|
|
394
403
|
* @param {boolean} [props.useFsAccessApi] Set to true to use the https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API
|
|
395
404
|
* to open the file picker instead of using an `<input type="file">` click event.
|
|
405
|
+
* @param {boolean} autoFocus Set to true to auto focus the root element.
|
|
396
406
|
* @param {Function} [props.onFileDialogOpen] Cb for when opening the file dialog
|
|
397
407
|
* @param {dragCb} [props.onDragEnter] Cb for when the `dragenter` event occurs.
|
|
398
408
|
* @param {dragCb} [props.onDragLeave] Cb for when the `dragleave` event occurs
|
|
@@ -425,7 +435,7 @@ var initialState = {
|
|
|
425
435
|
* @param {dropRejectedCb} [props.onDropRejected]
|
|
426
436
|
* @param {(error: Error) => void} [props.onError]
|
|
427
437
|
*
|
|
428
|
-
* @returns {DropzoneState}
|
|
438
|
+
* @returns {DropzoneState & DropzoneMethods}
|
|
429
439
|
*/
|
|
430
440
|
|
|
431
441
|
export function useDropzone() {
|
|
@@ -448,6 +458,7 @@ export function useDropzone() {
|
|
|
448
458
|
onFileDialogCancel = _defaultProps$props.onFileDialogCancel,
|
|
449
459
|
onFileDialogOpen = _defaultProps$props.onFileDialogOpen,
|
|
450
460
|
useFsAccessApi = _defaultProps$props.useFsAccessApi,
|
|
461
|
+
autoFocus = _defaultProps$props.autoFocus,
|
|
451
462
|
preventDropOnDocument = _defaultProps$props.preventDropOnDocument,
|
|
452
463
|
noClick = _defaultProps$props.noClick,
|
|
453
464
|
noKeyboard = _defaultProps$props.noKeyboard,
|
|
@@ -468,6 +479,11 @@ export function useDropzone() {
|
|
|
468
479
|
var onFileDialogCancelCb = useMemo(function () {
|
|
469
480
|
return typeof onFileDialogCancel === "function" ? onFileDialogCancel : noop;
|
|
470
481
|
}, [onFileDialogCancel]);
|
|
482
|
+
/**
|
|
483
|
+
* @constant
|
|
484
|
+
* @type {React.MutableRefObject<HTMLElement>}
|
|
485
|
+
*/
|
|
486
|
+
|
|
471
487
|
var rootRef = useRef(null);
|
|
472
488
|
var inputRef = useRef(null);
|
|
473
489
|
|
|
@@ -477,8 +493,7 @@ export function useDropzone() {
|
|
|
477
493
|
dispatch = _useReducer2[1];
|
|
478
494
|
|
|
479
495
|
var isFocused = state.isFocused,
|
|
480
|
-
isFileDialogActive = state.isFileDialogActive
|
|
481
|
-
draggedFiles = state.draggedFiles;
|
|
496
|
+
isFileDialogActive = state.isFileDialogActive;
|
|
482
497
|
var fsAccessApiWorksRef = useRef(typeof window !== "undefined" && window.isSecureContext && useFsAccessApi && canUseFileSystemAccessAPI()); // Update file dialog active state when the window is focused on
|
|
483
498
|
|
|
484
499
|
var onWindowFocus = function onWindowFocus() {
|
|
@@ -529,7 +544,15 @@ export function useDropzone() {
|
|
|
529
544
|
document.removeEventListener("drop", onDocumentDrop);
|
|
530
545
|
}
|
|
531
546
|
};
|
|
532
|
-
}, [rootRef, preventDropOnDocument]);
|
|
547
|
+
}, [rootRef, preventDropOnDocument]); // Auto focus the root when autoFocus is true
|
|
548
|
+
|
|
549
|
+
useEffect(function () {
|
|
550
|
+
if (!disabled && autoFocus && rootRef.current) {
|
|
551
|
+
rootRef.current.focus();
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
return function () {};
|
|
555
|
+
}, [rootRef, autoFocus, disabled]);
|
|
533
556
|
var onErrCb = useCallback(function (e) {
|
|
534
557
|
if (onError) {
|
|
535
558
|
onError(e);
|
|
@@ -546,13 +569,24 @@ export function useDropzone() {
|
|
|
546
569
|
dragTargetsRef.current = [].concat(_toConsumableArray(dragTargetsRef.current), [event.target]);
|
|
547
570
|
|
|
548
571
|
if (isEvtWithFiles(event)) {
|
|
549
|
-
Promise.resolve(getFilesFromEvent(event)).then(function (
|
|
572
|
+
Promise.resolve(getFilesFromEvent(event)).then(function (files) {
|
|
550
573
|
if (isPropagationStopped(event) && !noDragEventsBubbling) {
|
|
551
574
|
return;
|
|
552
575
|
}
|
|
553
576
|
|
|
577
|
+
var fileCount = files.length;
|
|
578
|
+
var isDragAccept = fileCount > 0 && allFilesAccepted({
|
|
579
|
+
files: files,
|
|
580
|
+
accept: acceptAttr,
|
|
581
|
+
minSize: minSize,
|
|
582
|
+
maxSize: maxSize,
|
|
583
|
+
multiple: multiple,
|
|
584
|
+
maxFiles: maxFiles
|
|
585
|
+
});
|
|
586
|
+
var isDragReject = fileCount > 0 && !isDragAccept;
|
|
554
587
|
dispatch({
|
|
555
|
-
|
|
588
|
+
isDragAccept: isDragAccept,
|
|
589
|
+
isDragReject: isDragReject,
|
|
556
590
|
isDragActive: true,
|
|
557
591
|
type: "setDraggedFiles"
|
|
558
592
|
});
|
|
@@ -564,7 +598,7 @@ export function useDropzone() {
|
|
|
564
598
|
return onErrCb(e);
|
|
565
599
|
});
|
|
566
600
|
}
|
|
567
|
-
}, [getFilesFromEvent, onDragEnter, onErrCb, noDragEventsBubbling]);
|
|
601
|
+
}, [getFilesFromEvent, onDragEnter, onErrCb, noDragEventsBubbling, acceptAttr, minSize, maxSize, multiple, maxFiles]);
|
|
568
602
|
var onDragOverCb = useCallback(function (event) {
|
|
569
603
|
event.preventDefault();
|
|
570
604
|
event.persist();
|
|
@@ -608,9 +642,10 @@ export function useDropzone() {
|
|
|
608
642
|
}
|
|
609
643
|
|
|
610
644
|
dispatch({
|
|
611
|
-
isDragActive: false,
|
|
612
645
|
type: "setDraggedFiles",
|
|
613
|
-
|
|
646
|
+
isDragActive: false,
|
|
647
|
+
isDragAccept: false,
|
|
648
|
+
isDragReject: false
|
|
614
649
|
});
|
|
615
650
|
|
|
616
651
|
if (isEvtWithFiles(event) && onDragLeave) {
|
|
@@ -837,7 +872,7 @@ export function useDropzone() {
|
|
|
837
872
|
onDragOver: composeDragHandler(composeEventHandlers(onDragOver, onDragOverCb)),
|
|
838
873
|
onDragLeave: composeDragHandler(composeEventHandlers(onDragLeave, onDragLeaveCb)),
|
|
839
874
|
onDrop: composeDragHandler(composeEventHandlers(onDrop, onDropCb)),
|
|
840
|
-
role: typeof role === "string" && role !== "" ? role : "
|
|
875
|
+
role: typeof role === "string" && role !== "" ? role : "presentation"
|
|
841
876
|
}, refKey, rootRef), !disabled && !noKeyboard ? {
|
|
842
877
|
tabIndex: 0
|
|
843
878
|
} : {}), rest);
|
|
@@ -870,19 +905,7 @@ export function useDropzone() {
|
|
|
870
905
|
return _objectSpread(_objectSpread({}, inputProps), rest);
|
|
871
906
|
};
|
|
872
907
|
}, [inputRef, accept, multiple, onDropCb, disabled]);
|
|
873
|
-
var fileCount = draggedFiles.length;
|
|
874
|
-
var isDragAccept = fileCount > 0 && allFilesAccepted({
|
|
875
|
-
files: draggedFiles,
|
|
876
|
-
accept: acceptAttr,
|
|
877
|
-
minSize: minSize,
|
|
878
|
-
maxSize: maxSize,
|
|
879
|
-
multiple: multiple,
|
|
880
|
-
maxFiles: maxFiles
|
|
881
|
-
});
|
|
882
|
-
var isDragReject = fileCount > 0 && !isDragAccept;
|
|
883
908
|
return _objectSpread(_objectSpread({}, state), {}, {
|
|
884
|
-
isDragAccept: isDragAccept,
|
|
885
|
-
isDragReject: isDragReject,
|
|
886
909
|
isFocused: isFocused && !disabled,
|
|
887
910
|
getRootProps: getRootProps,
|
|
888
911
|
getInputProps: getInputProps,
|
|
@@ -891,6 +914,11 @@ export function useDropzone() {
|
|
|
891
914
|
open: composeHandler(openFileDialog)
|
|
892
915
|
});
|
|
893
916
|
}
|
|
917
|
+
/**
|
|
918
|
+
* @param {DropzoneState} state
|
|
919
|
+
* @param {{type: string} & DropzoneState} action
|
|
920
|
+
* @returns {DropzoneState}
|
|
921
|
+
*/
|
|
894
922
|
|
|
895
923
|
function reducer(state, action) {
|
|
896
924
|
/* istanbul ignore next */
|
|
@@ -916,12 +944,10 @@ function reducer(state, action) {
|
|
|
916
944
|
});
|
|
917
945
|
|
|
918
946
|
case "setDraggedFiles":
|
|
919
|
-
/* eslint no-case-declarations: 0 */
|
|
920
|
-
var isDragActive = action.isDragActive,
|
|
921
|
-
draggedFiles = action.draggedFiles;
|
|
922
947
|
return _objectSpread(_objectSpread({}, state), {}, {
|
|
923
|
-
|
|
924
|
-
|
|
948
|
+
isDragActive: action.isDragActive,
|
|
949
|
+
isDragAccept: action.isDragAccept,
|
|
950
|
+
isDragReject: action.isDragReject
|
|
925
951
|
});
|
|
926
952
|
|
|
927
953
|
case "setFiles":
|