Skip to content

Commit fdff9f2

Browse files
committed
fix(utils): useDropzone fix around onDragLeave behavior
1 parent 644971d commit fdff9f2

File tree

2 files changed

+46
-9
lines changed

2 files changed

+46
-9
lines changed

packages/utils/src/__tests__/useDropzone.tsx

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1-
import React, { ReactElement } from "react";
1+
import React, { ReactElement, ReactNode } from "react";
22
import cn from "classnames";
33
import { fireEvent, render } from "@testing-library/react";
44

55
import { DropzoneHanders, useDropzone } from "../useDropzone";
66

7-
function Test(props: DropzoneHanders<HTMLElement>): ReactElement {
8-
const [isOver, handlers] = useDropzone(props);
7+
function Test({
8+
children,
9+
...options
10+
}: DropzoneHanders<HTMLElement> & { children?: ReactNode }): ReactElement {
11+
const [isOver, handlers] = useDropzone(options);
912

1013
return (
11-
<div
12-
data-testid="dropzone"
13-
{...handlers}
14-
className={cn(isOver && "over")}
15-
/>
14+
<div data-testid="dropzone" {...handlers} className={cn(isOver && "over")}>
15+
{children}
16+
</div>
1617
);
1718
}
1819

@@ -95,4 +96,33 @@ describe("useDropzone", () => {
9596
expect(onDragLeave).not.toBeCalled();
9697
expect(onDrop).not.toBeCalled();
9798
});
99+
100+
it("should not disable the isOver state if a dragleave event is called on a child element", () => {
101+
const { getByTestId } = render(
102+
<Test>
103+
<div data-testid="child1" />
104+
<div data-testid="child2" />
105+
</Test>
106+
);
107+
108+
const dropzone = getByTestId("dropzone");
109+
const child1 = getByTestId("child1");
110+
const child2 = getByTestId("child2");
111+
expect(dropzone).not.toHaveClass("over");
112+
113+
fireEvent.dragEnter(dropzone);
114+
expect(dropzone).toHaveClass("over");
115+
116+
fireEvent.dragOver(child1);
117+
expect(dropzone).toHaveClass("over");
118+
119+
fireEvent.dragLeave(child1);
120+
expect(dropzone).toHaveClass("over");
121+
122+
fireEvent.dragOver(child2);
123+
expect(dropzone).toHaveClass("over");
124+
125+
fireEvent.dragLeave(dropzone);
126+
expect(dropzone).not.toHaveClass("over");
127+
});
98128
});

packages/utils/src/useDropzone.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,14 @@ export function useDropzone<E extends HTMLElement>(
9191
propOnDragLeave?.(event);
9292
event.preventDefault();
9393
event.stopPropagation();
94-
setOver(false);
94+
95+
if (
96+
!event.target ||
97+
event.currentTarget === event.target ||
98+
!event.currentTarget.contains(event.target as HTMLElement)
99+
) {
100+
setOver(false);
101+
}
95102
},
96103
[propOnDragLeave]
97104
);

0 commit comments

Comments
 (0)