diff --git a/src/click_outside_wrapper.tsx b/src/click_outside_wrapper.tsx index 7b7b68e89..0fc49627e 100644 --- a/src/click_outside_wrapper.tsx +++ b/src/click_outside_wrapper.tsx @@ -44,9 +44,9 @@ const useDetectClickOutside = ( [ignoreClass], ); useEffect(() => { - document.addEventListener("mousedown", handleClickOutside); + document.addEventListener("mousedown", handleClickOutside, true); return () => { - document.removeEventListener("mousedown", handleClickOutside); + document.removeEventListener("mousedown", handleClickOutside, true); }; }, [handleClickOutside]); return ref; diff --git a/src/test/click_outside_wrapper.test.tsx b/src/test/click_outside_wrapper.test.tsx index 6f5ee5725..de86cceb9 100644 --- a/src/test/click_outside_wrapper.test.tsx +++ b/src/test/click_outside_wrapper.test.tsx @@ -42,6 +42,26 @@ describe("ClickOutsideWrapper", () => { expect(onClickOutsideMock).toHaveBeenCalledTimes(1); }); + it("calls onClickOutside when an outside element stops mousedown propagation", () => { + const { getByTestId } = render( +
+ +
Inside
+
+ +
, + ); + + fireEvent.mouseDown(getByTestId("outside")); + + expect(onClickOutsideMock).toHaveBeenCalledTimes(1); + }); + it("does not call onClickOutside when clicking inside the wrapper", () => { const { container } = render( @@ -190,6 +210,7 @@ describe("ClickOutsideWrapper", () => { expect(removeEventListenerSpy).toHaveBeenCalledWith( "mousedown", expect.any(Function), + true, ); removeEventListenerSpy.mockRestore(); diff --git a/src/test/datepicker_test.test.tsx b/src/test/datepicker_test.test.tsx index 31b239b37..63757240b 100644 --- a/src/test/datepicker_test.test.tsx +++ b/src/test/datepicker_test.test.tsx @@ -2865,6 +2865,24 @@ describe("DatePicker", () => { expect(onClickOutsideSpy).toHaveBeenCalledTimes(1); }); + it("should close when an outside element stops mousedown propagation", () => { + const { container, getByRole } = render( +
+ + +
, + ); + + fireEvent.focus(safeQuerySelector(container, "input")); + expect(container.querySelector(".react-datepicker")).not.toBeNull(); + + fireEvent.mouseDown(getByRole("button", { name: "Outside" })); + + expect(container.querySelector(".react-datepicker")).toBeNull(); + }); + it("should not close date picker when onClickOutside calls preventDefault", () => { const onClickOutside = (event: MouseEvent) => { event.preventDefault();