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 +1 -0
- package/.eslintrc +21 -1
- package/README.md +14 -12
- package/dist/es/index.js +98 -118
- package/dist/es/utils/index.js +13 -4
- package/dist/index.js +2 -2
- package/package.json +58 -58
- package/src/.eslintrc +22 -4
- package/src/index.js +18 -34
- package/src/index.spec.js +31 -7
- package/src/utils/index.js +18 -4
- package/src/utils/index.spec.js +38 -0
- package/testSetup.js +1 -1
- package/.travis.yml +0 -12
package/.eslintignore
CHANGED
package/.eslintrc
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
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
|
[](https://www.npmjs.com/package/react-dropzone)
|
|
6
|
-
|
|
6
|
+

|
|
7
7
|
[](https://codecov.io/gh/react-dropzone/react-dropzone)
|
|
8
8
|
[](#backers)
|
|
9
9
|
[](#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
|
-
|
|
84
|
+
const onDrop = useCallback((acceptedFiles) => {
|
|
85
|
+
acceptedFiles.forEach((file) => {
|
|
86
|
+
const reader = new FileReader()
|
|
86
87
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
const binaryStr = reader.result
|
|
93
|
+
console.log(binaryStr)
|
|
94
|
+
}
|
|
95
|
+
reader.readAsArrayBuffer(file)
|
|
96
|
+
})
|
|
97
|
+
|
|
96
98
|
}, [])
|
|
97
|
-
const {getRootProps, getInputProps
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
}, [
|
|
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
|
|
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
|
-
|
|
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 (
|
|
541
|
-
|
|
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
|
-
}, [
|
|
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 =
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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,
|
package/dist/es/utils/index.js
CHANGED
|
@@ -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,
|
|
10
|
-
|
|
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
|
-
|
|
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
|