react-dropzone 10.1.8 → 10.2.1

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/.eslintignore CHANGED
@@ -1,4 +1,5 @@
1
1
  dist/
2
2
  coverage/
3
3
  typings/*
4
+ styleguide/*
4
5
  !.babelrc.js
package/.eslintrc CHANGED
@@ -1,5 +1,25 @@
1
1
  {
2
- "extends": ["okonet/node"],
2
+ "parser": "babel-eslint",
3
+ "parserOptions": {
4
+ "ecmaVersion": 2017,
5
+ "sourceType": "module"
6
+ },
7
+ "env": {
8
+ "es6": true,
9
+ "node": true,
10
+ "jest": true
11
+ },
12
+ "plugins": [
13
+ "import",
14
+ "node",
15
+ "prettier"
16
+ ],
17
+ "extends": [
18
+ // TODO: Fix this so we can use
19
+ // "okonet/node"
20
+ "eslint:recommended",
21
+ "prettier"
22
+ ],
3
23
  "rules": {
4
24
  "strict": 0,
5
25
  "node/no-unpublished-require": 0,
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  # react-dropzone
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/react-dropzone.svg?style=flat-square)](https://www.npmjs.com/package/react-dropzone)
6
- [![Build Status](https://img.shields.io/travis/react-dropzone/react-dropzone/master.svg?style=flat-square)](https://travis-ci.org/react-dropzone/react-dropzone)
6
+ ![Build Status](https://github.com/react-dropzone/react-dropzone/workflows/Test/badge.svg)
7
7
  [![codecov](https://img.shields.io/codecov/c/gh/react-dropzone/react-dropzone/master.svg?style=flat-square)](https://codecov.io/gh/react-dropzone/react-dropzone)
8
8
  [![Open Collective](https://img.shields.io/opencollective/backers/react-dropzone.svg?style=flat-square)](#backers)
9
9
  [![Open Collective](https://img.shields.io/opencollective/sponsors/react-dropzone.svg?style=flat-square)](#sponsors)
@@ -81,20 +81,22 @@ import React, {useCallback} from 'react'
81
81
  import {useDropzone} from 'react-dropzone'
82
82
 
83
83
  function MyDropzone() {
84
- const onDrop = useCallback(acceptedFiles => {
85
- const reader = new FileReader()
84
+ const onDrop = useCallback((acceptedFiles) => {
85
+ acceptedFiles.forEach((file) => {
86
+ const reader = new FileReader()
86
87
 
87
- reader.onabort = () => console.log('file reading was aborted')
88
- reader.onerror = () => console.log('file reading has failed')
89
- reader.onload = () => {
88
+ reader.onabort = () => console.log('file reading was aborted')
89
+ reader.onerror = () => console.log('file reading has failed')
90
+ reader.onload = () => {
90
91
  // Do whatever you want with the file contents
91
- const binaryStr = reader.result
92
- console.log(binaryStr)
93
- }
94
-
95
- acceptedFiles.forEach(file => reader.readAsBinaryString(file))
92
+ const binaryStr = reader.result
93
+ console.log(binaryStr)
94
+ }
95
+ reader.readAsArrayBuffer(file)
96
+ })
97
+
96
98
  }, [])
97
- const {getRootProps, getInputProps, isDragActive} = useDropzone({onDrop})
99
+ const {getRootProps, getInputProps} = useDropzone({onDrop})
98
100
 
99
101
  return (
100
102
  <div {...getRootProps()}>
package/dist/es/index.js CHANGED
@@ -10,22 +10,22 @@ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArra
10
10
 
11
11
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
12
12
 
13
- function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
13
+ function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
14
14
 
15
15
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
16
16
 
17
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
17
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
18
18
 
19
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
19
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
20
20
 
21
- function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
21
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
22
22
 
23
23
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
24
24
 
25
25
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
26
26
 
27
27
  /* eslint prefer-template: 0 */
28
- import React, { forwardRef, Fragment, useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react';
28
+ import React, { forwardRef, Fragment, useCallback, useEffect, useImperativeHandle, useMemo, useReducer, useRef } from 'react';
29
29
  import PropTypes from 'prop-types';
30
30
  import { fromEvent } from 'file-selector';
31
31
  import { allFilesAccepted, composeEventHandlers, fileAccepted, fileMatchSize, isEvtWithFiles, isIeOrEdge, isPropagationStopped, onDocumentDragOver } from './utils/index';
@@ -52,25 +52,11 @@ var Dropzone = forwardRef(function (_ref, ref) {
52
52
  open = _useDropzone.open,
53
53
  props = _objectWithoutProperties(_useDropzone, ["open"]);
54
54
 
55
- useEffect(function () {
56
- if (typeof ref === 'function') {
57
- ref({
58
- open: open
59
- });
60
- } else if (_typeof(ref) === 'object' && ref !== null) {
61
- ref.current = {
62
- open: open
63
- };
64
- }
65
-
66
- return function () {
67
- if (typeof ref === 'function') {
68
- ref(null);
69
- } else if (_typeof(ref) === 'object' && ref !== null) {
70
- ref.current = null;
71
- }
55
+ useImperativeHandle(ref, function () {
56
+ return {
57
+ open: open
72
58
  };
73
- }, [ref]); // TODO: Figure out why react-styleguidist cannot create docs if we don't return a jsx element
59
+ }, [open]); // TODO: Figure out why react-styleguidist cannot create docs if we don't return a jsx element
74
60
 
75
61
  return React.createElement(Fragment, null, children(_objectSpread({}, props, {
76
62
  open: open
@@ -309,80 +295,80 @@ var initialState = {
309
295
  draggedFiles: [],
310
296
  acceptedFiles: [],
311
297
  rejectedFiles: []
312
- /**
313
- * A React hook that creates a drag 'n' drop area.
314
- *
315
- * ```jsx
316
- * function MyDropzone(props) {
317
- * const {getRootProps, getInputProps} = useDropzone({
318
- * onDrop: acceptedFiles => {
319
- * // do something with the File objects, e.g. upload to some server
320
- * }
321
- * });
322
- * return (
323
- * <div {...getRootProps()}>
324
- * <input {...getInputProps()} />
325
- * <p>Drag and drop some files here, or click to select files</p>
326
- * </div>
327
- * )
328
- * }
329
- * ```
330
- *
331
- * @function useDropzone
332
- *
333
- * @param {object} props
334
- * @param {string|string[]} [props.accept] Set accepted file types.
335
- * See https://github.com/okonet/attr-accept for more information.
336
- * Keep in mind that mime type determination is not reliable across platforms. CSV files,
337
- * for example, are reported as text/plain under macOS but as application/vnd.ms-excel under
338
- * Windows. In some cases there might not be a mime type set at all.
339
- * See: https://github.com/react-dropzone/react-dropzone/issues/276
340
- * @param {boolean} [props.multiple=true] Allow drag 'n' drop (or selection from the file dialog) of multiple files
341
- * @param {boolean} [props.preventDropOnDocument=true] If false, allow dropped items to take over the current browser window
342
- * @param {boolean} [props.noClick=false] If true, disables click to open the native file selection dialog
343
- * @param {boolean} [props.noKeyboard=false] If true, disables SPACE/ENTER to open the native file selection dialog.
344
- * Note that it also stops tracking the focus state.
345
- * @param {boolean} [props.noDrag=false] If true, disables drag 'n' drop
346
- * @param {boolean} [props.noDragEventsBubbling=false] If true, stops drag event propagation to parents
347
- * @param {number} [props.minSize=0] Minimum file size (in bytes)
348
- * @param {number} [props.maxSize=Infinity] Maximum file size (in bytes)
349
- * @param {boolean} [props.disabled=false] Enable/disable the dropzone
350
- * @param {getFilesFromEvent} [props.getFilesFromEvent] Use this to provide a custom file aggregator
351
- * @param {Function} [props.onFileDialogCancel] Cb for when closing the file dialog with no selection
352
- * @param {dragCb} [props.onDragEnter] Cb for when the `dragenter` event occurs.
353
- * @param {dragCb} [props.onDragLeave] Cb for when the `dragleave` event occurs
354
- * @param {dragCb} [props.onDragOver] Cb for when the `dragover` event occurs
355
- * @param {dropCb} [props.onDrop] Cb for when the `drop` event occurs.
356
- * Note that this callback is invoked after the `getFilesFromEvent` callback is done.
357
- *
358
- * Files are accepted or rejected based on the `accept`, `multiple`, `minSize` and `maxSize` props.
359
- * `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) or a valid file extension.
360
- * If `multiple` is set to false and additional files are droppped,
361
- * all files besides the first will be rejected.
362
- * Any file which does not have a size in the [`minSize`, `maxSize`] range, will be rejected as well.
363
- *
364
- * Note that the `onDrop` callback will always be invoked regardless if the dropped files were accepted or rejected.
365
- * If you'd like to react to a specific scenario, use the `onDropAccepted`/`onDropRejected` props.
366
- *
367
- * `onDrop` will provide you with an array of [File](https://developer.mozilla.org/en-US/docs/Web/API/File) objects which you can then process and send to a server.
368
- * For example, with [SuperAgent](https://github.com/visionmedia/superagent) as a http/ajax library:
369
- *
370
- * ```js
371
- * function onDrop(acceptedFiles) {
372
- * const req = request.post('/upload')
373
- * acceptedFiles.forEach(file => {
374
- * req.attach(file.name, file)
375
- * })
376
- * req.end(callback)
377
- * }
378
- * ```
379
- * @param {dropAcceptedCb} [props.onDropAccepted]
380
- * @param {dropRejectedCb} [props.onDropRejected]
381
- *
382
- * @returns {DropzoneState}
383
- */
384
-
385
298
  };
299
+ /**
300
+ * A React hook that creates a drag 'n' drop area.
301
+ *
302
+ * ```jsx
303
+ * function MyDropzone(props) {
304
+ * const {getRootProps, getInputProps} = useDropzone({
305
+ * onDrop: acceptedFiles => {
306
+ * // do something with the File objects, e.g. upload to some server
307
+ * }
308
+ * });
309
+ * return (
310
+ * <div {...getRootProps()}>
311
+ * <input {...getInputProps()} />
312
+ * <p>Drag and drop some files here, or click to select files</p>
313
+ * </div>
314
+ * )
315
+ * }
316
+ * ```
317
+ *
318
+ * @function useDropzone
319
+ *
320
+ * @param {object} props
321
+ * @param {string|string[]} [props.accept] Set accepted file types.
322
+ * See https://github.com/okonet/attr-accept for more information.
323
+ * Keep in mind that mime type determination is not reliable across platforms. CSV files,
324
+ * for example, are reported as text/plain under macOS but as application/vnd.ms-excel under
325
+ * Windows. In some cases there might not be a mime type set at all.
326
+ * See: https://github.com/react-dropzone/react-dropzone/issues/276
327
+ * @param {boolean} [props.multiple=true] Allow drag 'n' drop (or selection from the file dialog) of multiple files
328
+ * @param {boolean} [props.preventDropOnDocument=true] If false, allow dropped items to take over the current browser window
329
+ * @param {boolean} [props.noClick=false] If true, disables click to open the native file selection dialog
330
+ * @param {boolean} [props.noKeyboard=false] If true, disables SPACE/ENTER to open the native file selection dialog.
331
+ * Note that it also stops tracking the focus state.
332
+ * @param {boolean} [props.noDrag=false] If true, disables drag 'n' drop
333
+ * @param {boolean} [props.noDragEventsBubbling=false] If true, stops drag event propagation to parents
334
+ * @param {number} [props.minSize=0] Minimum file size (in bytes)
335
+ * @param {number} [props.maxSize=Infinity] Maximum file size (in bytes)
336
+ * @param {boolean} [props.disabled=false] Enable/disable the dropzone
337
+ * @param {getFilesFromEvent} [props.getFilesFromEvent] Use this to provide a custom file aggregator
338
+ * @param {Function} [props.onFileDialogCancel] Cb for when closing the file dialog with no selection
339
+ * @param {dragCb} [props.onDragEnter] Cb for when the `dragenter` event occurs.
340
+ * @param {dragCb} [props.onDragLeave] Cb for when the `dragleave` event occurs
341
+ * @param {dragCb} [props.onDragOver] Cb for when the `dragover` event occurs
342
+ * @param {dropCb} [props.onDrop] Cb for when the `drop` event occurs.
343
+ * Note that this callback is invoked after the `getFilesFromEvent` callback is done.
344
+ *
345
+ * Files are accepted or rejected based on the `accept`, `multiple`, `minSize` and `maxSize` props.
346
+ * `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) or a valid file extension.
347
+ * If `multiple` is set to false and additional files are droppped,
348
+ * all files besides the first will be rejected.
349
+ * Any file which does not have a size in the [`minSize`, `maxSize`] range, will be rejected as well.
350
+ *
351
+ * Note that the `onDrop` callback will always be invoked regardless if the dropped files were accepted or rejected.
352
+ * If you'd like to react to a specific scenario, use the `onDropAccepted`/`onDropRejected` props.
353
+ *
354
+ * `onDrop` will provide you with an array of [File](https://developer.mozilla.org/en-US/docs/Web/API/File) objects which you can then process and send to a server.
355
+ * For example, with [SuperAgent](https://github.com/visionmedia/superagent) as a http/ajax library:
356
+ *
357
+ * ```js
358
+ * function onDrop(acceptedFiles) {
359
+ * const req = request.post('/upload')
360
+ * acceptedFiles.forEach(file => {
361
+ * req.attach(file.name, file)
362
+ * })
363
+ * req.end(callback)
364
+ * }
365
+ * ```
366
+ * @param {dropAcceptedCb} [props.onDropAccepted]
367
+ * @param {dropRejectedCb} [props.onDropRejected]
368
+ *
369
+ * @returns {DropzoneState}
370
+ */
371
+
386
372
  export function useDropzone() {
387
373
  var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
388
374
  accept = _ref2.accept,
@@ -426,7 +412,7 @@ export function useDropzone() {
426
412
  isFileDialogActive = state.isFileDialogActive,
427
413
  draggedFiles = state.draggedFiles; // Fn for opening the file dialog programmatically
428
414
 
429
- var openFileDialog = function openFileDialog() {
415
+ var openFileDialog = useCallback(function () {
430
416
  if (inputRef.current) {
431
417
  dispatch({
432
418
  type: 'openDialog'
@@ -434,8 +420,7 @@ export function useDropzone() {
434
420
  inputRef.current.value = null;
435
421
  inputRef.current.click();
436
422
  }
437
- }; // Update file dialog active state when the window is focused on
438
-
423
+ }, [dispatch]); // Update file dialog active state when the window is focused on
439
424
 
440
425
  var onWindowFocus = function onWindowFocus() {
441
426
  // Execute the timeout only if the file dialog is opened in the browser
@@ -502,11 +487,7 @@ export function useDropzone() {
502
487
  openFileDialog();
503
488
  }
504
489
  }, [inputRef, noClick]);
505
-
506
- var _useState = useState([]),
507
- _useState2 = _slicedToArray(_useState, 2),
508
- dragTargets = _useState2[0],
509
- setDragTargets = _useState2[1];
490
+ var dragTargetsRef = useRef([]);
510
491
 
511
492
  var onDocumentDrop = function onDocumentDrop(event) {
512
493
  if (rootRef.current && rootRef.current.contains(event.target)) {
@@ -515,7 +496,7 @@ export function useDropzone() {
515
496
  }
516
497
 
517
498
  event.preventDefault();
518
- setDragTargets([]);
499
+ dragTargetsRef.current = [];
519
500
  };
520
501
 
521
502
  useEffect(function () {
@@ -537,8 +518,8 @@ export function useDropzone() {
537
518
  event.persist();
538
519
  stopPropagation(event); // Count the dropzone and any children that are entered.
539
520
 
540
- if (dragTargets.indexOf(event.target) === -1) {
541
- setDragTargets([].concat(_toConsumableArray(dragTargets), [event.target]));
521
+ if (dragTargetsRef.current.indexOf(event.target) === -1) {
522
+ dragTargetsRef.current = [].concat(_toConsumableArray(dragTargetsRef.current), [event.target]);
542
523
  }
543
524
 
544
525
  if (isEvtWithFiles(event)) {
@@ -558,7 +539,7 @@ export function useDropzone() {
558
539
  }
559
540
  });
560
541
  }
561
- }, [dragTargets, getFilesFromEvent, onDragEnter, noDragEventsBubbling]);
542
+ }, [getFilesFromEvent, onDragEnter, noDragEventsBubbling]);
562
543
  var onDragOverCb = useCallback(function (event) {
563
544
  event.preventDefault();
564
545
  event.persist();
@@ -583,11 +564,10 @@ export function useDropzone() {
583
564
  event.persist();
584
565
  stopPropagation(event); // Only deactivate once the dropzone and all children have been left
585
566
 
586
- var targets = _toConsumableArray(dragTargets.filter(function (target) {
567
+ var targets = dragTargetsRef.current.filter(function (target) {
587
568
  return target !== event.target && rootRef.current && rootRef.current.contains(target);
588
- }));
589
-
590
- setDragTargets(targets);
569
+ });
570
+ dragTargetsRef.current = targets;
591
571
 
592
572
  if (targets.length > 0) {
593
573
  return;
@@ -602,13 +582,13 @@ export function useDropzone() {
602
582
  if (isEvtWithFiles(event) && onDragLeave) {
603
583
  onDragLeave(event);
604
584
  }
605
- }, [rootRef, dragTargets, onDragLeave, noDragEventsBubbling]);
585
+ }, [rootRef, onDragLeave, noDragEventsBubbling]);
606
586
  var onDropCb = useCallback(function (event) {
607
587
  event.preventDefault(); // Persist here because we need the event later after getFilesFromEvent() is done
608
588
 
609
589
  event.persist();
610
590
  stopPropagation(event);
611
- setDragTargets([]);
591
+ dragTargetsRef.current = [];
612
592
  dispatch({
613
593
  type: 'reset'
614
594
  });
@@ -622,7 +602,7 @@ export function useDropzone() {
622
602
  var acceptedFiles = [];
623
603
  var rejectedFiles = [];
624
604
  files.forEach(function (file) {
625
- if (fileAccepted(file, accept) && fileMatchSize(file, maxSize, minSize)) {
605
+ if (fileAccepted(file, accept) && fileMatchSize(file, minSize, maxSize)) {
626
606
  acceptedFiles.push(file);
627
607
  } else {
628
608
  rejectedFiles.push(file);
@@ -698,7 +678,7 @@ export function useDropzone() {
698
678
  onDrop: composeDragHandler(composeEventHandlers(onDrop, onDropCb))
699
679
  }, refKey, rootRef), !disabled && !noKeyboard ? {
700
680
  tabIndex: 0
701
- } : {}, rest);
681
+ } : {}, {}, rest);
702
682
  };
703
683
  }, [rootRef, onKeyDownCb, onFocusCb, onBlurCb, onClickCb, onDragEnterCb, onDragOverCb, onDragLeaveCb, onDropCb, noKeyboard, noDrag, disabled]);
704
684
  var onInputElementClick = useCallback(function (event) {
@@ -726,12 +706,12 @@ export function useDropzone() {
726
706
  tabIndex: -1
727
707
  }, refKey, inputRef);
728
708
 
729
- return _objectSpread({}, inputProps, rest);
709
+ return _objectSpread({}, inputProps, {}, rest);
730
710
  };
731
711
  }, [inputRef, accept, multiple, onDropCb, disabled]);
732
712
  var fileCount = draggedFiles.length;
733
713
  var isMultipleAllowed = multiple || fileCount <= 1;
734
- var isDragAccept = fileCount > 0 && allFilesAccepted(draggedFiles, accept);
714
+ var isDragAccept = fileCount > 0 && allFilesAccepted(draggedFiles, accept, minSize, maxSize);
735
715
  var isDragReject = fileCount > 0 && (!isDragAccept || !isMultipleAllowed);
736
716
  return _objectSpread({}, state, {
737
717
  isDragAccept: isDragAccept,
@@ -6,12 +6,21 @@ import accepts from 'attr-accept'; // Firefox versions prior to 53 return a bogu
6
6
  export function fileAccepted(file, accept) {
7
7
  return file.type === 'application/x-moz-file' || accepts(file, accept);
8
8
  }
9
- export function fileMatchSize(file, maxSize, minSize) {
10
- return file.size <= maxSize && file.size >= minSize;
9
+ export function fileMatchSize(file, minSize, maxSize) {
10
+ if (isDefined(file.size)) {
11
+ if (isDefined(minSize) && isDefined(maxSize)) return file.size >= minSize && file.size <= maxSize;else if (isDefined(minSize)) return file.size >= minSize;else if (isDefined(maxSize)) return file.size <= maxSize;
12
+ }
13
+
14
+ return true;
11
15
  }
12
- export function allFilesAccepted(files, accept) {
16
+
17
+ function isDefined(value) {
18
+ return value !== undefined && value !== null;
19
+ }
20
+
21
+ export function allFilesAccepted(files, accept, minSize, maxSize) {
13
22
  return files.every(function (file) {
14
- return fileAccepted(file, accept);
23
+ return fileAccepted(file, accept) && fileMatchSize(file, minSize, maxSize);
15
24
  });
16
25
  } // React's synthetic events has event.isPropagationStopped,
17
26
  // but to remain compatibility with other libs (Preact) fall back