react-dropzone 14.3.8 → 14.4.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/.nvmrc +1 -1
- package/.releaserc.json +28 -0
- package/CHANGELOG.md +12 -0
- package/dist/es/index.js +66 -1
- package/dist/es/utils/index.js +25 -1
- package/dist/index.js +2 -2
- package/dist/react-dropzone-14.4.0.tgz +0 -0
- package/examples/drag-overlay/README.md +132 -0
- package/package.json +7 -1
- package/src/index.js +58 -0
- package/src/index.spec.js +141 -4
- package/src/utils/index.js +27 -1
- package/src/utils/index.spec.js +25 -0
- package/styleguide.config.js +4 -0
- package/typings/react-dropzone.d.ts +1 -0
package/.nvmrc
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
22
|
package/.releaserc.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"branches": ["master"],
|
|
3
|
+
"plugins": [
|
|
4
|
+
"@semantic-release/commit-analyzer",
|
|
5
|
+
"@semantic-release/release-notes-generator",
|
|
6
|
+
"@semantic-release/changelog",
|
|
7
|
+
[
|
|
8
|
+
"@semantic-release/npm",
|
|
9
|
+
{
|
|
10
|
+
"npmPublish": true,
|
|
11
|
+
"pkgRoot": ".",
|
|
12
|
+
"tarballDir": "dist",
|
|
13
|
+
"provenance": true
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
[
|
|
17
|
+
"@semantic-release/github",
|
|
18
|
+
{
|
|
19
|
+
"assets": [
|
|
20
|
+
{
|
|
21
|
+
"path": "dist/*.tgz",
|
|
22
|
+
"label": "Distribution"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
]
|
|
28
|
+
}
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# [14.4.0](https://github.com/react-dropzone/react-dropzone/compare/v14.3.8...v14.4.0) (2026-01-29)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* accept files with empty type during drag events ([eaa8ba5](https://github.com/react-dropzone/react-dropzone/commit/eaa8ba54963480afbba50415b1dd792514fefac1))
|
|
7
|
+
* correct dragLeave filter logic and add dragend test ([273aff4](https://github.com/react-dropzone/react-dropzone/commit/273aff4a151aba05ddd473cbc49dc3db59132f2f))
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* add isDragGlobal state for document-level drag detection ([f0874b0](https://github.com/react-dropzone/react-dropzone/commit/f0874b0ad8e94dbf662b16bc82d0aa2b082ec8ee))
|
package/dist/es/index.js
CHANGED
|
@@ -103,6 +103,7 @@ Dropzone.propTypes = {
|
|
|
103
103
|
* @param {boolean} params.isDragActive Active drag is in progress
|
|
104
104
|
* @param {boolean} params.isDragAccept Dragged files are accepted
|
|
105
105
|
* @param {boolean} params.isDragReject Some dragged files are rejected
|
|
106
|
+
* @param {boolean} params.isDragGlobal Files are being dragged anywhere on the document
|
|
106
107
|
* @param {File[]} params.acceptedFiles Accepted files
|
|
107
108
|
* @param {FileRejection[]} params.fileRejections Rejected files and why they were rejected
|
|
108
109
|
*/
|
|
@@ -339,6 +340,7 @@ export default Dropzone;
|
|
|
339
340
|
* @property {boolean} isDragActive Active drag is in progress
|
|
340
341
|
* @property {boolean} isDragAccept Dragged files are accepted
|
|
341
342
|
* @property {boolean} isDragReject Some dragged files are rejected
|
|
343
|
+
* @property {boolean} isDragGlobal Files are being dragged anywhere on the document
|
|
342
344
|
* @property {File[]} acceptedFiles Accepted files
|
|
343
345
|
* @property {FileRejection[]} fileRejections Rejected files and why they were rejected
|
|
344
346
|
*/
|
|
@@ -358,6 +360,7 @@ var initialState = {
|
|
|
358
360
|
isDragActive: false,
|
|
359
361
|
isDragAccept: false,
|
|
360
362
|
isDragReject: false,
|
|
363
|
+
isDragGlobal: false,
|
|
361
364
|
acceptedFiles: [],
|
|
362
365
|
fileRejections: []
|
|
363
366
|
};
|
|
@@ -521,6 +524,7 @@ export function useDropzone() {
|
|
|
521
524
|
};
|
|
522
525
|
}, [inputRef, isFileDialogActive, onFileDialogCancelCb, fsAccessApiWorksRef]);
|
|
523
526
|
var dragTargetsRef = useRef([]);
|
|
527
|
+
var globalDragTargetsRef = useRef([]);
|
|
524
528
|
|
|
525
529
|
var onDocumentDrop = function onDocumentDrop(event) {
|
|
526
530
|
if (rootRef.current && rootRef.current.contains(event.target)) {
|
|
@@ -544,7 +548,63 @@ export function useDropzone() {
|
|
|
544
548
|
document.removeEventListener("drop", onDocumentDrop);
|
|
545
549
|
}
|
|
546
550
|
};
|
|
547
|
-
}, [rootRef, preventDropOnDocument]); //
|
|
551
|
+
}, [rootRef, preventDropOnDocument]); // Track global drag state for document-level drag events
|
|
552
|
+
|
|
553
|
+
useEffect(function () {
|
|
554
|
+
var onDocumentDragEnter = function onDocumentDragEnter(event) {
|
|
555
|
+
globalDragTargetsRef.current = [].concat(_toConsumableArray(globalDragTargetsRef.current), [event.target]);
|
|
556
|
+
|
|
557
|
+
if (isEvtWithFiles(event)) {
|
|
558
|
+
dispatch({
|
|
559
|
+
isDragGlobal: true,
|
|
560
|
+
type: "setDragGlobal"
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
var onDocumentDragLeave = function onDocumentDragLeave(event) {
|
|
566
|
+
// Only deactivate once we've left all children
|
|
567
|
+
globalDragTargetsRef.current = globalDragTargetsRef.current.filter(function (el) {
|
|
568
|
+
return el !== event.target && el !== null;
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
if (globalDragTargetsRef.current.length > 0) {
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
dispatch({
|
|
576
|
+
isDragGlobal: false,
|
|
577
|
+
type: "setDragGlobal"
|
|
578
|
+
});
|
|
579
|
+
};
|
|
580
|
+
|
|
581
|
+
var onDocumentDragEnd = function onDocumentDragEnd() {
|
|
582
|
+
globalDragTargetsRef.current = [];
|
|
583
|
+
dispatch({
|
|
584
|
+
isDragGlobal: false,
|
|
585
|
+
type: "setDragGlobal"
|
|
586
|
+
});
|
|
587
|
+
};
|
|
588
|
+
|
|
589
|
+
var onDocumentDropGlobal = function onDocumentDropGlobal() {
|
|
590
|
+
globalDragTargetsRef.current = [];
|
|
591
|
+
dispatch({
|
|
592
|
+
isDragGlobal: false,
|
|
593
|
+
type: "setDragGlobal"
|
|
594
|
+
});
|
|
595
|
+
};
|
|
596
|
+
|
|
597
|
+
document.addEventListener("dragenter", onDocumentDragEnter, false);
|
|
598
|
+
document.addEventListener("dragleave", onDocumentDragLeave, false);
|
|
599
|
+
document.addEventListener("dragend", onDocumentDragEnd, false);
|
|
600
|
+
document.addEventListener("drop", onDocumentDropGlobal, false);
|
|
601
|
+
return function () {
|
|
602
|
+
document.removeEventListener("dragenter", onDocumentDragEnter);
|
|
603
|
+
document.removeEventListener("dragleave", onDocumentDragLeave);
|
|
604
|
+
document.removeEventListener("dragend", onDocumentDragEnd);
|
|
605
|
+
document.removeEventListener("drop", onDocumentDropGlobal);
|
|
606
|
+
};
|
|
607
|
+
}, [rootRef]); // Auto focus the root when autoFocus is true
|
|
548
608
|
|
|
549
609
|
useEffect(function () {
|
|
550
610
|
if (!disabled && autoFocus && rootRef.current) {
|
|
@@ -970,6 +1030,11 @@ function reducer(state, action) {
|
|
|
970
1030
|
isDragReject: action.isDragReject
|
|
971
1031
|
});
|
|
972
1032
|
|
|
1033
|
+
case "setDragGlobal":
|
|
1034
|
+
return _objectSpread(_objectSpread({}, state), {}, {
|
|
1035
|
+
isDragGlobal: action.isDragGlobal
|
|
1036
|
+
});
|
|
1037
|
+
|
|
973
1038
|
case "reset":
|
|
974
1039
|
return _objectSpread({}, initialState);
|
|
975
1040
|
|
package/dist/es/utils/index.js
CHANGED
|
@@ -69,19 +69,43 @@ export var TOO_MANY_FILES_REJECTION = {
|
|
|
69
69
|
code: TOO_MANY_FILES,
|
|
70
70
|
message: "Too many files"
|
|
71
71
|
};
|
|
72
|
+
/**
|
|
73
|
+
* Check if the given file is a DataTransferItem with an empty type.
|
|
74
|
+
*
|
|
75
|
+
* During drag events, browsers may return DataTransferItem objects instead of File objects.
|
|
76
|
+
* Some browsers (e.g., Chrome) return an empty MIME type for certain file types (like .md files)
|
|
77
|
+
* on DataTransferItem during drag events, even though the type is correctly set during drop.
|
|
78
|
+
*
|
|
79
|
+
* This function detects such cases by checking for:
|
|
80
|
+
* 1. Empty type string
|
|
81
|
+
* 2. Presence of getAsFile method (indicates it's a DataTransferItem, not a File)
|
|
82
|
+
*
|
|
83
|
+
* We accept these during drag to provide proper UI feedback, while maintaining
|
|
84
|
+
* strict validation during drop when real File objects are available.
|
|
85
|
+
*
|
|
86
|
+
* @param {File | DataTransferItem} file
|
|
87
|
+
* @returns {boolean}
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
export function isDataTransferItemWithEmptyType(file) {
|
|
91
|
+
return file.type === "" && typeof file.getAsFile === "function";
|
|
92
|
+
}
|
|
72
93
|
/**
|
|
73
94
|
* Check if file is accepted.
|
|
74
95
|
*
|
|
75
96
|
* Firefox versions prior to 53 return a bogus MIME type for every file drag,
|
|
76
97
|
* so dragovers with that MIME type will always be accepted.
|
|
77
98
|
*
|
|
99
|
+
* Chrome/other browsers may return an empty MIME type for files during drag events,
|
|
100
|
+
* so we accept those as well (we'll validate properly on drop).
|
|
101
|
+
*
|
|
78
102
|
* @param {File} file
|
|
79
103
|
* @param {string} accept
|
|
80
104
|
* @returns
|
|
81
105
|
*/
|
|
82
106
|
|
|
83
107
|
export function fileAccepted(file, accept) {
|
|
84
|
-
var isAcceptable = file.type === "application/x-moz-file" || accepts(file, accept);
|
|
108
|
+
var isAcceptable = file.type === "application/x-moz-file" || accepts(file, accept) || isDataTransferItemWithEmptyType(file);
|
|
85
109
|
return [isAcceptable, isAcceptable ? null : getInvalidTypeRejectionErr(accept)];
|
|
86
110
|
}
|
|
87
111
|
export function fileMatchSize(file, minSize, maxSize) {
|