diff --git a/src/__tests__/useOnclickoutside.tsx b/src/__tests__/useOnclickoutside.tsx index 16d3bc3d..0a77f28a 100644 --- a/src/__tests__/useOnclickoutside.tsx +++ b/src/__tests__/useOnclickoutside.tsx @@ -1,4 +1,4 @@ -import { FC, useRef } from "react"; +import { FC, useState, useRef } from "react"; import { render, fireEvent, screen } from "@testing-library/react"; import useOnclickOutside, { DEFAULT_IGNORE_CLASS, Callback, Options } from ".."; @@ -15,12 +15,14 @@ const Compo: FC = ({ callback, ...options }: Props) => { + const [show, setShow] = useState(false); const ref1 = useRef(); const ref2 = useRef(); + const ref3 = useRef(); const ref = useOnclickOutside(callback, { ...options, // @ts-expect-error - refs: refOpt && [ref1, ref2], + refs: refOpt && [ref1, ref2, ref3], }); return ( @@ -31,6 +33,11 @@ const Compo: FC = ({
+ {/* @ts-expect-error */} + {show &&
} +
@@ -121,6 +128,16 @@ describe("useOnclickOutside", () => { } ); + it("should not trigger callback when clicking/touching inside of the dynamic ref", () => { + const cb = renderHelper({ refOpt: true }); + + fireEvent.click(getByTestId("btn")); + fireEvent.mouseDown(getByTestId("ref-3")); + fireEvent.touchStart(getByTestId("ref-3")); + + expect(cb).not.toHaveBeenCalled(); + }); + it("should trigger callback when clicking/touching outside of the targets", () => { const cb = renderHelper(); const out = getByTestId("out-1"); diff --git a/src/index.ts b/src/index.ts index 58e42be3..fc38c7f7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -43,9 +43,9 @@ const useOnclickOutside = ( callback: Callback, { refs: refsOpt, - disabled = false, + disabled, eventTypes = ["mousedown", "touchstart"], - excludeScrollbar = false, + excludeScrollbar, ignoreClass = DEFAULT_IGNORE_CLASS, detectIFrame = true, }: Options = {} @@ -66,16 +66,19 @@ const useOnclickOutside = ( () => { if (!refsOpt?.length && !refsState.length) return; - const els: El[] = []; - (refsOpt || refsState).forEach( - ({ current }) => current && els.push(current) - ); + const getEls = () => { + const els: El[] = []; + (refsOpt || refsState).forEach( + ({ current }) => current && els.push(current) + ); + return els; + }; const handler = (e: any) => { if ( !hasIgnoreClass(e, ignoreClass) && !(excludeScrollbar && clickedOnScrollbar(e)) && - els.every((el) => !el.contains(e.target)) + getEls().every((el) => !el.contains(e.target)) ) callbackRef.current(e); }; @@ -88,7 +91,7 @@ const useOnclickOutside = ( if ( activeElement?.tagName === "IFRAME" && !hasIgnoreClass(activeElement, ignoreClass) && - !els.includes(activeElement as HTMLIFrameElement) + !getEls().includes(activeElement as HTMLIFrameElement) ) callbackRef.current(e); }, 0);