react-dropzone 14.4.0 → 15.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/package.json CHANGED
@@ -197,7 +197,7 @@
197
197
  "webpack-blocks": "^2.1.0"
198
198
  },
199
199
  "typings": "typings/react-dropzone.d.ts",
200
- "version": "14.4.0",
200
+ "version": "15.0.0",
201
201
  "engines": {
202
202
  "node": ">= 10.13"
203
203
  },
package/src/index.js CHANGED
@@ -85,10 +85,10 @@ Dropzone.propTypes = {
85
85
  * @param {boolean} params.isFileDialogActive File dialog is opened
86
86
  * @param {boolean} params.isDragActive Active drag is in progress
87
87
  * @param {boolean} params.isDragAccept Dragged files are accepted
88
- * @param {boolean} params.isDragReject Some dragged files are rejected
88
+ * @param {boolean} params.isDragReject True only during an active drag when some dragged files would be rejected. After drop, this resets to false. Use fileRejections for post-drop errors.
89
89
  * @param {boolean} params.isDragGlobal Files are being dragged anywhere on the document
90
90
  * @param {File[]} params.acceptedFiles Accepted files
91
- * @param {FileRejection[]} params.fileRejections Rejected files and why they were rejected
91
+ * @param {FileRejection[]} params.fileRejections Rejected files and why they were rejected. This persists after drop and is the source of truth for post-drop rejections.
92
92
  */
93
93
  children: PropTypes.func,
94
94
 
@@ -283,7 +283,7 @@ export default Dropzone;
283
283
  *
284
284
  * @callback dropCb
285
285
  * @param {File[]} acceptedFiles List of accepted files
286
- * @param {FileRejection[]} fileRejections List of rejected files and why they were rejected
286
+ * @param {FileRejection[]} fileRejections List of rejected files and why they were rejected. This is the authoritative source for post-drop file rejections.
287
287
  * @param {(DragEvent|Event)} event A drag event or input change event (if files were selected via the file dialog)
288
288
  */
289
289
 
@@ -323,10 +323,10 @@ export default Dropzone;
323
323
  * @property {boolean} isFileDialogActive File dialog is opened
324
324
  * @property {boolean} isDragActive Active drag is in progress
325
325
  * @property {boolean} isDragAccept Dragged files are accepted
326
- * @property {boolean} isDragReject Some dragged files are rejected
326
+ * @property {boolean} isDragReject True only during an active drag when some dragged files would be rejected. After drop, this resets to false. Use fileRejections for post-drop errors.
327
327
  * @property {boolean} isDragGlobal Files are being dragged anywhere on the document
328
328
  * @property {File[]} acceptedFiles Accepted files
329
- * @property {FileRejection[]} fileRejections Rejected files and why they were rejected
329
+ * @property {FileRejection[]} fileRejections Rejected files and why they were rejected. This persists after drop and is the source of truth for post-drop rejections.
330
330
  */
331
331
 
332
332
  /**
@@ -407,6 +407,10 @@ const initialState = {
407
407
  * Note that the `onDrop` callback will always be invoked regardless if the dropped files were accepted or rejected.
408
408
  * If you'd like to react to a specific scenario, use the `onDropAccepted`/`onDropRejected` props.
409
409
  *
410
+ * The second parameter (fileRejections) is the authoritative list of rejected files after a drop.
411
+ * Use this parameter or the fileRejections state property to handle post-drop file rejections,
412
+ * as isDragReject only indicates rejection state during active drag operations.
413
+ *
410
414
  * `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.
411
415
  * For example, with [SuperAgent](https://github.com/visionmedia/superagent) as a http/ajax library:
412
416
  *
@@ -756,7 +760,6 @@ export function useDropzone(props = {}) {
756
760
  dispatch({
757
761
  acceptedFiles,
758
762
  fileRejections,
759
- isDragReject: fileRejections.length > 0,
760
763
  type: "setFiles",
761
764
  });
762
765
 
@@ -1079,7 +1082,7 @@ function reducer(state, action) {
1079
1082
  ...state,
1080
1083
  acceptedFiles: action.acceptedFiles,
1081
1084
  fileRejections: action.fileRejections,
1082
- isDragReject: action.isDragReject,
1085
+ isDragReject: false,
1083
1086
  };
1084
1087
  case "setDragGlobal":
1085
1088
  return {
package/src/index.spec.js CHANGED
@@ -2639,7 +2639,8 @@ describe("useDropzone() hook", () => {
2639
2639
  expect(matchToErrorCode(rejectedFileErrorList, "file-invalid-type")).toBe(
2640
2640
  true
2641
2641
  );
2642
- expect(dropzone).toHaveTextContent("dragReject");
2642
+ // After drop, isDragReject should be false even if files were rejected
2643
+ expect(dropzone).not.toHaveTextContent("dragReject");
2643
2644
  });
2644
2645
 
2645
2646
  it("resets {isDragActive, isDragAccept, isDragReject}", async () => {
@@ -2678,6 +2679,66 @@ describe("useDropzone() hook", () => {
2678
2679
  expect(dropzone).not.toHaveTextContent("dragReject");
2679
2680
  });
2680
2681
 
2682
+ it("isDragReject is false after rejected drop and updates correctly on new drag", async () => {
2683
+ const { container } = render(
2684
+ <Dropzone
2685
+ accept={{
2686
+ "image/*": [],
2687
+ }}
2688
+ >
2689
+ {({
2690
+ getRootProps,
2691
+ getInputProps,
2692
+ isDragActive,
2693
+ isDragAccept,
2694
+ isDragReject,
2695
+ fileRejections,
2696
+ }) => (
2697
+ <div {...getRootProps()}>
2698
+ <input {...getInputProps()} />
2699
+ {isDragActive && "dragActive"}
2700
+ {isDragAccept && "dragAccept"}
2701
+ {isDragReject && "dragReject"}
2702
+ {fileRejections.length > 0 && "hasRejections"}
2703
+ </div>
2704
+ )}
2705
+ </Dropzone>
2706
+ );
2707
+ const dropzone = container.querySelector("div");
2708
+
2709
+ // Drop rejected files
2710
+ await act(() => fireEvent.drop(dropzone, createDtWithFiles(files)));
2711
+
2712
+ // After drop, isDragReject should be false but fileRejections should be populated
2713
+ expect(dropzone).not.toHaveTextContent("dragActive");
2714
+ expect(dropzone).not.toHaveTextContent("dragAccept");
2715
+ expect(dropzone).not.toHaveTextContent("dragReject");
2716
+ expect(dropzone).toHaveTextContent("hasRejections");
2717
+
2718
+ // New drag with rejected files should set isDragReject to true
2719
+ await act(() => fireEvent.dragEnter(dropzone, createDtWithFiles(files)));
2720
+
2721
+ expect(dropzone).toHaveTextContent("dragActive");
2722
+ expect(dropzone).not.toHaveTextContent("dragAccept");
2723
+ expect(dropzone).toHaveTextContent("dragReject");
2724
+
2725
+ // Drag leave should reset drag state
2726
+ await act(() => fireEvent.dragLeave(dropzone, createDtWithFiles(files)));
2727
+
2728
+ expect(dropzone).not.toHaveTextContent("dragActive");
2729
+ expect(dropzone).not.toHaveTextContent("dragAccept");
2730
+ expect(dropzone).not.toHaveTextContent("dragReject");
2731
+ // But fileRejections should still be there from the previous drop
2732
+ expect(dropzone).toHaveTextContent("hasRejections");
2733
+
2734
+ // New drag with accepted files should set isDragAccept
2735
+ await act(() => fireEvent.dragEnter(dropzone, createDtWithFiles(images)));
2736
+
2737
+ expect(dropzone).toHaveTextContent("dragActive");
2738
+ expect(dropzone).toHaveTextContent("dragAccept");
2739
+ expect(dropzone).not.toHaveTextContent("dragReject");
2740
+ });
2741
+
2681
2742
  it("sets {isDragGlobal} to true when drag event is detected on document", async () => {
2682
2743
  const { container } = render(
2683
2744
  <Dropzone>
Binary file