react-dropzone 11.7.1 → 12.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/src/index.js CHANGED
@@ -7,10 +7,10 @@ import React, {
7
7
  useImperativeHandle,
8
8
  useMemo,
9
9
  useReducer,
10
- useRef
11
- } from 'react'
12
- import PropTypes from 'prop-types'
13
- import {fromEvent} from 'file-selector'
10
+ useRef,
11
+ } from "react";
12
+ import PropTypes from "prop-types";
13
+ import { fromEvent } from "file-selector";
14
14
  import {
15
15
  allFilesAccepted,
16
16
  composeEventHandlers,
@@ -22,8 +22,8 @@ import {
22
22
  isIeOrEdge,
23
23
  isPropagationStopped,
24
24
  onDocumentDragOver,
25
- TOO_MANY_FILES_REJECTION
26
- } from './utils/index'
25
+ TOO_MANY_FILES_REJECTION,
26
+ } from "./utils/index";
27
27
 
28
28
  /**
29
29
  * Convenience wrapper component for the `useDropzone` hook
@@ -39,16 +39,16 @@ import {
39
39
  * </Dropzone>
40
40
  * ```
41
41
  */
42
- const Dropzone = forwardRef(({children, ...params}, ref) => {
43
- const {open, ...props} = useDropzone(params)
42
+ const Dropzone = forwardRef(({ children, ...params }, ref) => {
43
+ const { open, ...props } = useDropzone(params);
44
44
 
45
- useImperativeHandle(ref, () => ({open}), [open])
45
+ useImperativeHandle(ref, () => ({ open }), [open]);
46
46
 
47
47
  // TODO: Figure out why react-styleguidist cannot create docs if we don't return a jsx element
48
- return <Fragment>{children({...props, open})}</Fragment>
49
- })
48
+ return <Fragment>{children({ ...props, open })}</Fragment>;
49
+ });
50
50
 
51
- Dropzone.displayName = 'Dropzone'
51
+ Dropzone.displayName = "Dropzone";
52
52
 
53
53
  // Add default props for react-docgen
54
54
  const defaultProps = {
@@ -64,10 +64,10 @@ const defaultProps = {
64
64
  noDrag: false,
65
65
  noDragEventsBubbling: false,
66
66
  validator: null,
67
- useFsAccessApi: false,
68
- }
67
+ useFsAccessApi: true,
68
+ };
69
69
 
70
- Dropzone.defaultProps = defaultProps
70
+ Dropzone.defaultProps = defaultProps;
71
71
 
72
72
  Dropzone.propTypes = {
73
73
  /**
@@ -96,7 +96,10 @@ Dropzone.propTypes = {
96
96
  * Windows. In some cases there might not be a mime type set at all.
97
97
  * See: https://github.com/react-dropzone/react-dropzone/issues/276
98
98
  */
99
- accept: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
99
+ accept: PropTypes.oneOfType([
100
+ PropTypes.string,
101
+ PropTypes.arrayOf(PropTypes.string),
102
+ ]),
100
103
 
101
104
  /**
102
105
  * Allow drag 'n' drop (or selection from the file dialog) of multiple files
@@ -248,10 +251,10 @@ Dropzone.propTypes = {
248
251
  * @param {File} file
249
252
  * @returns {FileError|FileError[]}
250
253
  */
251
- validator: PropTypes.func
252
- }
254
+ validator: PropTypes.func,
255
+ };
253
256
 
254
- export default Dropzone
257
+ export default Dropzone;
255
258
 
256
259
  /**
257
260
  * A function that is invoked for the `dragenter`,
@@ -325,8 +328,8 @@ const initialState = {
325
328
  isDragReject: false,
326
329
  draggedFiles: [],
327
330
  acceptedFiles: [],
328
- fileRejections: []
329
- }
331
+ fileRejections: [],
332
+ };
330
333
 
331
334
  /**
332
335
  * A React hook that creates a drag 'n' drop area.
@@ -426,24 +429,27 @@ export function useDropzone(options = {}) {
426
429
  noKeyboard,
427
430
  noDrag,
428
431
  noDragEventsBubbling,
429
- validator
432
+ validator,
430
433
  } = {
431
434
  ...defaultProps,
432
- ...options
433
- }
435
+ ...options,
436
+ };
434
437
 
435
438
  const onFileDialogOpenCb = useMemo(
436
- () => typeof onFileDialogOpen === 'function' ? onFileDialogOpen : noop,
437
- [onFileDialogOpen])
439
+ () => (typeof onFileDialogOpen === "function" ? onFileDialogOpen : noop),
440
+ [onFileDialogOpen]
441
+ );
438
442
  const onFileDialogCancelCb = useMemo(
439
- () => typeof onFileDialogCancel === 'function' ? onFileDialogCancel : noop,
440
- [onFileDialogCancel])
443
+ () =>
444
+ typeof onFileDialogCancel === "function" ? onFileDialogCancel : noop,
445
+ [onFileDialogCancel]
446
+ );
441
447
 
442
- const rootRef = useRef(null)
443
- const inputRef = useRef(null)
448
+ const rootRef = useRef(null);
449
+ const inputRef = useRef(null);
444
450
 
445
- const [state, dispatch] = useReducer(reducer, initialState)
446
- const {isFocused, isFileDialogActive, draggedFiles} = state
451
+ const [state, dispatch] = useReducer(reducer, initialState);
452
+ const { isFocused, isFileDialogActive, draggedFiles } = state;
447
453
 
448
454
  // Update file dialog active state when the window is focused on
449
455
  const onWindowFocus = () => {
@@ -451,246 +457,249 @@ export function useDropzone(options = {}) {
451
457
  if (isFileDialogActive) {
452
458
  setTimeout(() => {
453
459
  if (inputRef.current) {
454
- const {files} = inputRef.current
460
+ const { files } = inputRef.current;
455
461
 
456
462
  if (!files.length) {
457
- dispatch({type: 'closeDialog'})
458
- onFileDialogCancelCb()
463
+ dispatch({ type: "closeDialog" });
464
+ onFileDialogCancelCb();
459
465
  }
460
466
  }
461
- }, 300)
467
+ }, 300);
462
468
  }
463
- }
469
+ };
464
470
  useEffect(() => {
465
471
  if (useFsAccessApi && canUseFileSystemAccessAPI()) {
466
- return () => {}
472
+ return () => {};
467
473
  }
468
474
 
469
- window.addEventListener('focus', onWindowFocus, false)
475
+ window.addEventListener("focus", onWindowFocus, false);
470
476
  return () => {
471
- window.removeEventListener('focus', onWindowFocus, false)
472
- }
473
- }, [inputRef, isFileDialogActive, onFileDialogCancelCb, useFsAccessApi])
477
+ window.removeEventListener("focus", onWindowFocus, false);
478
+ };
479
+ }, [inputRef, isFileDialogActive, onFileDialogCancelCb, useFsAccessApi]);
474
480
 
475
- const dragTargetsRef = useRef([])
476
- const onDocumentDrop = event => {
481
+ const dragTargetsRef = useRef([]);
482
+ const onDocumentDrop = (event) => {
477
483
  if (rootRef.current && rootRef.current.contains(event.target)) {
478
484
  // If we intercepted an event for our instance, let it propagate down to the instance's onDrop handler
479
- return
485
+ return;
480
486
  }
481
- event.preventDefault()
482
- dragTargetsRef.current = []
483
- }
487
+ event.preventDefault();
488
+ dragTargetsRef.current = [];
489
+ };
484
490
 
485
491
  useEffect(() => {
486
492
  if (preventDropOnDocument) {
487
- document.addEventListener('dragover', onDocumentDragOver, false)
488
- document.addEventListener('drop', onDocumentDrop, false)
493
+ document.addEventListener("dragover", onDocumentDragOver, false);
494
+ document.addEventListener("drop", onDocumentDrop, false);
489
495
  }
490
496
 
491
497
  return () => {
492
498
  if (preventDropOnDocument) {
493
- document.removeEventListener('dragover', onDocumentDragOver)
494
- document.removeEventListener('drop', onDocumentDrop)
499
+ document.removeEventListener("dragover", onDocumentDragOver);
500
+ document.removeEventListener("drop", onDocumentDrop);
495
501
  }
496
- }
497
- }, [rootRef, preventDropOnDocument])
502
+ };
503
+ }, [rootRef, preventDropOnDocument]);
498
504
 
499
505
  const onDragEnterCb = useCallback(
500
- event => {
501
- event.preventDefault()
506
+ (event) => {
507
+ event.preventDefault();
502
508
  // Persist here because we need the event later after getFilesFromEvent() is done
503
- event.persist()
504
- stopPropagation(event)
509
+ event.persist();
510
+ stopPropagation(event);
505
511
 
506
- dragTargetsRef.current = [...dragTargetsRef.current, event.target]
512
+ dragTargetsRef.current = [...dragTargetsRef.current, event.target];
507
513
 
508
514
  if (isEvtWithFiles(event)) {
509
- Promise.resolve(getFilesFromEvent(event)).then(draggedFiles => {
515
+ Promise.resolve(getFilesFromEvent(event)).then((draggedFiles) => {
510
516
  if (isPropagationStopped(event) && !noDragEventsBubbling) {
511
- return
517
+ return;
512
518
  }
513
519
 
514
520
  dispatch({
515
521
  draggedFiles,
516
522
  isDragActive: true,
517
- type: 'setDraggedFiles'
518
- })
523
+ type: "setDraggedFiles",
524
+ });
519
525
 
520
526
  if (onDragEnter) {
521
- onDragEnter(event)
527
+ onDragEnter(event);
522
528
  }
523
- })
529
+ });
524
530
  }
525
531
  },
526
532
  [getFilesFromEvent, onDragEnter, noDragEventsBubbling]
527
- )
533
+ );
528
534
 
529
535
  const onDragOverCb = useCallback(
530
- event => {
531
- event.preventDefault()
532
- event.persist()
533
- stopPropagation(event)
536
+ (event) => {
537
+ event.preventDefault();
538
+ event.persist();
539
+ stopPropagation(event);
534
540
 
535
541
  const hasFiles = isEvtWithFiles(event);
536
542
  if (hasFiles && event.dataTransfer) {
537
543
  try {
538
- event.dataTransfer.dropEffect = 'copy'
544
+ event.dataTransfer.dropEffect = "copy";
539
545
  } catch {} /* eslint-disable-line no-empty */
540
546
  }
541
547
 
542
548
  if (hasFiles && onDragOver) {
543
- onDragOver(event)
549
+ onDragOver(event);
544
550
  }
545
551
 
546
- return false
552
+ return false;
547
553
  },
548
554
  [onDragOver, noDragEventsBubbling]
549
- )
555
+ );
550
556
 
551
557
  const onDragLeaveCb = useCallback(
552
- event => {
553
- event.preventDefault()
554
- event.persist()
555
- stopPropagation(event)
558
+ (event) => {
559
+ event.preventDefault();
560
+ event.persist();
561
+ stopPropagation(event);
556
562
 
557
563
  // Only deactivate once the dropzone and all children have been left
558
564
  const targets = dragTargetsRef.current.filter(
559
- target => rootRef.current && rootRef.current.contains(target)
560
- )
565
+ (target) => rootRef.current && rootRef.current.contains(target)
566
+ );
561
567
  // Make sure to remove a target present multiple times only once
562
568
  // (Firefox may fire dragenter/dragleave multiple times on the same element)
563
- const targetIdx = targets.indexOf(event.target)
569
+ const targetIdx = targets.indexOf(event.target);
564
570
  if (targetIdx !== -1) {
565
- targets.splice(targetIdx, 1)
571
+ targets.splice(targetIdx, 1);
566
572
  }
567
- dragTargetsRef.current = targets
573
+ dragTargetsRef.current = targets;
568
574
  if (targets.length > 0) {
569
- return
575
+ return;
570
576
  }
571
577
 
572
578
  dispatch({
573
579
  isDragActive: false,
574
- type: 'setDraggedFiles',
575
- draggedFiles: []
576
- })
580
+ type: "setDraggedFiles",
581
+ draggedFiles: [],
582
+ });
577
583
 
578
584
  if (isEvtWithFiles(event) && onDragLeave) {
579
- onDragLeave(event)
585
+ onDragLeave(event);
580
586
  }
581
587
  },
582
588
  [rootRef, onDragLeave, noDragEventsBubbling]
583
- )
589
+ );
584
590
 
585
- const setFiles = useCallback((files, event) => {
586
- const acceptedFiles = []
587
- const fileRejections = []
591
+ const setFiles = useCallback(
592
+ (files, event) => {
593
+ const acceptedFiles = [];
594
+ const fileRejections = [];
588
595
 
589
- files.forEach(file => {
590
- const [accepted, acceptError] = fileAccepted(file, accept)
591
- const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize)
592
- const customErrors = validator ? validator(file) : null;
596
+ files.forEach((file) => {
597
+ const [accepted, acceptError] = fileAccepted(file, accept);
598
+ const [sizeMatch, sizeError] = fileMatchSize(file, minSize, maxSize);
599
+ const customErrors = validator ? validator(file) : null;
593
600
 
594
- if (accepted && sizeMatch && !customErrors) {
595
- acceptedFiles.push(file)
596
- } else {
597
- let errors = [acceptError, sizeError];
601
+ if (accepted && sizeMatch && !customErrors) {
602
+ acceptedFiles.push(file);
603
+ } else {
604
+ let errors = [acceptError, sizeError];
598
605
 
599
- if (customErrors) {
600
- errors = errors.concat(customErrors);
601
- }
606
+ if (customErrors) {
607
+ errors = errors.concat(customErrors);
608
+ }
602
609
 
603
- fileRejections.push({file, errors: errors.filter(e => e)})
610
+ fileRejections.push({ file, errors: errors.filter((e) => e) });
611
+ }
612
+ });
613
+
614
+ if (
615
+ (!multiple && acceptedFiles.length > 1) ||
616
+ (multiple && maxFiles >= 1 && acceptedFiles.length > maxFiles)
617
+ ) {
618
+ // Reject everything and empty accepted files
619
+ acceptedFiles.forEach((file) => {
620
+ fileRejections.push({ file, errors: [TOO_MANY_FILES_REJECTION] });
621
+ });
622
+ acceptedFiles.splice(0);
604
623
  }
605
- })
606
-
607
- if ((!multiple && acceptedFiles.length > 1) || (multiple && maxFiles >= 1 && acceptedFiles.length > maxFiles)) {
608
- // Reject everything and empty accepted files
609
- acceptedFiles.forEach(file => {
610
- fileRejections.push({file, errors: [TOO_MANY_FILES_REJECTION]})
611
- })
612
- acceptedFiles.splice(0)
613
- }
614
624
 
615
- dispatch({
616
- acceptedFiles,
617
- fileRejections,
618
- type: 'setFiles'
619
- })
625
+ dispatch({
626
+ acceptedFiles,
627
+ fileRejections,
628
+ type: "setFiles",
629
+ });
620
630
 
621
- if (onDrop) {
622
- onDrop(acceptedFiles, fileRejections, event)
623
- }
631
+ if (onDrop) {
632
+ onDrop(acceptedFiles, fileRejections, event);
633
+ }
624
634
 
625
- if (fileRejections.length > 0 && onDropRejected) {
626
- onDropRejected(fileRejections, event)
627
- }
635
+ if (fileRejections.length > 0 && onDropRejected) {
636
+ onDropRejected(fileRejections, event);
637
+ }
628
638
 
629
- if (acceptedFiles.length > 0 && onDropAccepted) {
630
- onDropAccepted(acceptedFiles, event)
631
- }
632
- }, [
633
- dispatch,
634
- multiple,
635
- accept,
636
- minSize,
637
- maxSize,
638
- maxFiles,
639
- onDrop,
640
- onDropAccepted,
641
- onDropRejected,
642
- validator
643
- ]);
639
+ if (acceptedFiles.length > 0 && onDropAccepted) {
640
+ onDropAccepted(acceptedFiles, event);
641
+ }
642
+ },
643
+ [
644
+ dispatch,
645
+ multiple,
646
+ accept,
647
+ minSize,
648
+ maxSize,
649
+ maxFiles,
650
+ onDrop,
651
+ onDropAccepted,
652
+ onDropRejected,
653
+ validator,
654
+ ]
655
+ );
644
656
 
645
657
  const onDropCb = useCallback(
646
- event => {
647
- event.preventDefault()
658
+ (event) => {
659
+ event.preventDefault();
648
660
  // Persist here because we need the event later after getFilesFromEvent() is done
649
- event.persist()
650
- stopPropagation(event)
661
+ event.persist();
662
+ stopPropagation(event);
651
663
 
652
- dragTargetsRef.current = []
664
+ dragTargetsRef.current = [];
653
665
 
654
666
  if (isEvtWithFiles(event)) {
655
- Promise.resolve(getFilesFromEvent(event)).then(files => {
667
+ Promise.resolve(getFilesFromEvent(event)).then((files) => {
656
668
  if (isPropagationStopped(event) && !noDragEventsBubbling) {
657
- return
669
+ return;
658
670
  }
659
- setFiles(files, event)
660
- })
671
+ setFiles(files, event);
672
+ });
661
673
  }
662
- dispatch({type: 'reset'})
674
+ dispatch({ type: "reset" });
663
675
  },
664
- [
665
- getFilesFromEvent,
666
- setFiles,
667
- noDragEventsBubbling
668
- ]
669
- )
676
+ [getFilesFromEvent, setFiles, noDragEventsBubbling]
677
+ );
670
678
 
671
679
  // Fn for opening the file dialog programmatically
672
680
  const openFileDialog = useCallback(() => {
673
681
  if (useFsAccessApi && canUseFileSystemAccessAPI()) {
674
- dispatch({type: 'openDialog'})
675
- onFileDialogOpenCb()
682
+ dispatch({ type: "openDialog" });
683
+ onFileDialogOpenCb();
676
684
  // https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker
677
685
  const opts = {
678
686
  multiple,
679
- types: filePickerOptionsTypes(accept)
687
+ types: filePickerOptionsTypes(accept),
680
688
  };
681
- window.showOpenFilePicker(opts)
682
- .then(handles => getFilesFromEvent(handles))
683
- .then(files => setFiles(files, null))
684
- .catch(e => onFileDialogCancelCb(e))
685
- .finally(() => dispatch({type: 'closeDialog'}));
686
- return
689
+ window
690
+ .showOpenFilePicker(opts)
691
+ .then((handles) => getFilesFromEvent(handles))
692
+ .then((files) => setFiles(files, null))
693
+ .catch((e) => onFileDialogCancelCb(e))
694
+ .finally(() => dispatch({ type: "closeDialog" }));
695
+ return;
687
696
  }
688
697
 
689
698
  if (inputRef.current) {
690
- dispatch({type: 'openDialog'})
691
- onFileDialogOpenCb()
692
- inputRef.current.value = null
693
- inputRef.current.click()
699
+ dispatch({ type: "openDialog" });
700
+ onFileDialogOpenCb();
701
+ inputRef.current.value = null;
702
+ inputRef.current.click();
694
703
  }
695
704
  }, [
696
705
  dispatch,
@@ -699,94 +708,105 @@ export function useDropzone(options = {}) {
699
708
  useFsAccessApi,
700
709
  setFiles,
701
710
  accept,
702
- multiple
703
- ])
711
+ multiple,
712
+ ]);
704
713
 
705
714
  // Cb to open the file dialog when SPACE/ENTER occurs on the dropzone
706
715
  const onKeyDownCb = useCallback(
707
- event => {
716
+ (event) => {
708
717
  // Ignore keyboard events bubbling up the DOM tree
709
718
  if (!rootRef.current || !rootRef.current.isEqualNode(event.target)) {
710
- return
719
+ return;
711
720
  }
712
721
 
713
722
  if (event.keyCode === 32 || event.keyCode === 13) {
714
- event.preventDefault()
715
- openFileDialog()
723
+ event.preventDefault();
724
+ openFileDialog();
716
725
  }
717
726
  },
718
727
  [rootRef, inputRef, openFileDialog]
719
- )
728
+ );
720
729
 
721
730
  // Update focus state for the dropzone
722
731
  const onFocusCb = useCallback(() => {
723
- dispatch({type: 'focus'})
724
- }, [])
732
+ dispatch({ type: "focus" });
733
+ }, []);
725
734
  const onBlurCb = useCallback(() => {
726
- dispatch({type: 'blur'})
727
- }, [])
735
+ dispatch({ type: "blur" });
736
+ }, []);
728
737
 
729
738
  // Cb to open the file dialog when click occurs on the dropzone
730
739
  const onClickCb = useCallback(() => {
731
740
  if (noClick) {
732
- return
741
+ return;
733
742
  }
734
743
 
735
744
  // In IE11/Edge the file-browser dialog is blocking, therefore, use setTimeout()
736
745
  // to ensure React can handle state changes
737
746
  // See: https://github.com/react-dropzone/react-dropzone/issues/450
738
747
  if (isIeOrEdge()) {
739
- setTimeout(openFileDialog, 0)
748
+ setTimeout(openFileDialog, 0);
740
749
  } else {
741
- openFileDialog()
750
+ openFileDialog();
742
751
  }
743
- }, [inputRef, noClick, openFileDialog])
752
+ }, [inputRef, noClick, openFileDialog]);
744
753
 
745
- const composeHandler = fn => {
746
- return disabled ? null : fn
747
- }
754
+ const composeHandler = (fn) => {
755
+ return disabled ? null : fn;
756
+ };
748
757
 
749
- const composeKeyboardHandler = fn => {
750
- return noKeyboard ? null : composeHandler(fn)
751
- }
758
+ const composeKeyboardHandler = (fn) => {
759
+ return noKeyboard ? null : composeHandler(fn);
760
+ };
752
761
 
753
- const composeDragHandler = fn => {
754
- return noDrag ? null : composeHandler(fn)
755
- }
762
+ const composeDragHandler = (fn) => {
763
+ return noDrag ? null : composeHandler(fn);
764
+ };
756
765
 
757
- const stopPropagation = event => {
766
+ const stopPropagation = (event) => {
758
767
  if (noDragEventsBubbling) {
759
- event.stopPropagation()
768
+ event.stopPropagation();
760
769
  }
761
- }
770
+ };
762
771
 
763
772
  const getRootProps = useMemo(
764
- () => ({
765
- refKey = 'ref',
766
- role,
767
- onKeyDown,
768
- onFocus,
769
- onBlur,
770
- onClick,
771
- onDragEnter,
772
- onDragOver,
773
- onDragLeave,
774
- onDrop,
775
- ...rest
776
- } = {}) => ({
777
- onKeyDown: composeKeyboardHandler(composeEventHandlers(onKeyDown, onKeyDownCb)),
778
- onFocus: composeKeyboardHandler(composeEventHandlers(onFocus, onFocusCb)),
779
- onBlur: composeKeyboardHandler(composeEventHandlers(onBlur, onBlurCb)),
780
- onClick: composeHandler(composeEventHandlers(onClick, onClickCb)),
781
- onDragEnter: composeDragHandler(composeEventHandlers(onDragEnter, onDragEnterCb)),
782
- onDragOver: composeDragHandler(composeEventHandlers(onDragOver, onDragOverCb)),
783
- onDragLeave: composeDragHandler(composeEventHandlers(onDragLeave, onDragLeaveCb)),
784
- onDrop: composeDragHandler(composeEventHandlers(onDrop, onDropCb)),
785
- role: typeof role === 'string' && role !== '' ? role : 'button',
786
- [refKey]: rootRef,
787
- ...(!disabled && !noKeyboard ? {tabIndex: 0} : {}),
788
- ...rest
789
- }),
773
+ () =>
774
+ ({
775
+ refKey = "ref",
776
+ role,
777
+ onKeyDown,
778
+ onFocus,
779
+ onBlur,
780
+ onClick,
781
+ onDragEnter,
782
+ onDragOver,
783
+ onDragLeave,
784
+ onDrop,
785
+ ...rest
786
+ } = {}) => ({
787
+ onKeyDown: composeKeyboardHandler(
788
+ composeEventHandlers(onKeyDown, onKeyDownCb)
789
+ ),
790
+ onFocus: composeKeyboardHandler(
791
+ composeEventHandlers(onFocus, onFocusCb)
792
+ ),
793
+ onBlur: composeKeyboardHandler(composeEventHandlers(onBlur, onBlurCb)),
794
+ onClick: composeHandler(composeEventHandlers(onClick, onClickCb)),
795
+ onDragEnter: composeDragHandler(
796
+ composeEventHandlers(onDragEnter, onDragEnterCb)
797
+ ),
798
+ onDragOver: composeDragHandler(
799
+ composeEventHandlers(onDragOver, onDragOverCb)
800
+ ),
801
+ onDragLeave: composeDragHandler(
802
+ composeEventHandlers(onDragLeave, onDragLeaveCb)
803
+ ),
804
+ onDrop: composeDragHandler(composeEventHandlers(onDrop, onDropCb)),
805
+ role: typeof role === "string" && role !== "" ? role : "button",
806
+ [refKey]: rootRef,
807
+ ...(!disabled && !noKeyboard ? { tabIndex: 0 } : {}),
808
+ ...rest,
809
+ }),
790
810
  [
791
811
  rootRef,
792
812
  onKeyDownCb,
@@ -799,39 +819,51 @@ export function useDropzone(options = {}) {
799
819
  onDropCb,
800
820
  noKeyboard,
801
821
  noDrag,
802
- disabled
822
+ disabled,
803
823
  ]
804
- )
824
+ );
805
825
 
806
- const onInputElementClick = useCallback(event => {
807
- event.stopPropagation()
808
- }, [])
826
+ const onInputElementClick = useCallback((event) => {
827
+ event.stopPropagation();
828
+ }, []);
809
829
 
810
830
  const getInputProps = useMemo(
811
- () => ({refKey = 'ref', onChange, onClick, ...rest} = {}) => {
812
- const inputProps = {
813
- accept,
814
- multiple,
815
- type: 'file',
816
- style: {display: 'none'},
817
- onChange: composeHandler(composeEventHandlers(onChange, onDropCb)),
818
- onClick: composeHandler(composeEventHandlers(onClick, onInputElementClick)),
819
- autoComplete: 'off',
820
- tabIndex: -1,
821
- [refKey]: inputRef
822
- }
823
-
824
- return {
825
- ...inputProps,
826
- ...rest
827
- }
828
- },
831
+ () =>
832
+ ({ refKey = "ref", onChange, onClick, ...rest } = {}) => {
833
+ const inputProps = {
834
+ accept,
835
+ multiple,
836
+ type: "file",
837
+ style: { display: "none" },
838
+ onChange: composeHandler(composeEventHandlers(onChange, onDropCb)),
839
+ onClick: composeHandler(
840
+ composeEventHandlers(onClick, onInputElementClick)
841
+ ),
842
+ autoComplete: "off",
843
+ tabIndex: -1,
844
+ [refKey]: inputRef,
845
+ };
846
+
847
+ return {
848
+ ...inputProps,
849
+ ...rest,
850
+ };
851
+ },
829
852
  [inputRef, accept, multiple, onDropCb, disabled]
830
- )
831
-
832
- const fileCount = draggedFiles.length
833
- const isDragAccept = fileCount > 0 && allFilesAccepted({files: draggedFiles, accept, minSize, maxSize, multiple, maxFiles})
834
- const isDragReject = fileCount > 0 && !isDragAccept
853
+ );
854
+
855
+ const fileCount = draggedFiles.length;
856
+ const isDragAccept =
857
+ fileCount > 0 &&
858
+ allFilesAccepted({
859
+ files: draggedFiles,
860
+ accept,
861
+ minSize,
862
+ maxSize,
863
+ multiple,
864
+ maxFiles,
865
+ });
866
+ const isDragReject = fileCount > 0 && !isDragAccept;
835
867
 
836
868
  return {
837
869
  ...state,
@@ -842,56 +874,56 @@ export function useDropzone(options = {}) {
842
874
  getInputProps,
843
875
  rootRef,
844
876
  inputRef,
845
- open: composeHandler(openFileDialog)
846
- }
877
+ open: composeHandler(openFileDialog),
878
+ };
847
879
  }
848
880
 
849
881
  function reducer(state, action) {
850
882
  /* istanbul ignore next */
851
883
  switch (action.type) {
852
- case 'focus':
884
+ case "focus":
853
885
  return {
854
886
  ...state,
855
- isFocused: true
856
- }
857
- case 'blur':
887
+ isFocused: true,
888
+ };
889
+ case "blur":
858
890
  return {
859
891
  ...state,
860
- isFocused: false
861
- }
862
- case 'openDialog':
892
+ isFocused: false,
893
+ };
894
+ case "openDialog":
863
895
  return {
864
896
  ...initialState,
865
- isFileDialogActive: true
866
- }
867
- case 'closeDialog':
897
+ isFileDialogActive: true,
898
+ };
899
+ case "closeDialog":
868
900
  return {
869
901
  ...state,
870
- isFileDialogActive: false
871
- }
872
- case 'setDraggedFiles':
902
+ isFileDialogActive: false,
903
+ };
904
+ case "setDraggedFiles":
873
905
  /* eslint no-case-declarations: 0 */
874
- const {isDragActive, draggedFiles} = action
906
+ const { isDragActive, draggedFiles } = action;
875
907
  return {
876
908
  ...state,
877
909
  draggedFiles,
878
- isDragActive
879
- }
880
- case 'setFiles':
910
+ isDragActive,
911
+ };
912
+ case "setFiles":
881
913
  return {
882
914
  ...state,
883
915
  acceptedFiles: action.acceptedFiles,
884
- fileRejections: action.fileRejections
885
- }
886
- case 'reset':
916
+ fileRejections: action.fileRejections,
917
+ };
918
+ case "reset":
887
919
  return {
888
- ...initialState
889
- }
920
+ ...initialState,
921
+ };
890
922
  default:
891
- return state
923
+ return state;
892
924
  }
893
925
  }
894
926
 
895
927
  function noop() {}
896
928
 
897
- export {ErrorCode} from './utils'
929
+ export { ErrorCode } from "./utils";