diff --git a/packages/useclickaway/__tests__/useclickaway.test.ts b/packages/useclickaway/__tests__/useclickaway.test.ts deleted file mode 100644 index 2b27ba5..0000000 --- a/packages/useclickaway/__tests__/useclickaway.test.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { useClickAway } from '../src'; - -describe('@artifak/useclickaway', () => { - it('needs tests', () => { - // - }); -}); diff --git a/packages/useclickaway/__tests__/useclickaway.test.tsx b/packages/useclickaway/__tests__/useclickaway.test.tsx new file mode 100644 index 0000000..6199f36 --- /dev/null +++ b/packages/useclickaway/__tests__/useclickaway.test.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { useClickAway } from '../src'; + +describe('@artifak/useclickaway', () => { + const onClickAway = jest.fn(); + + const Dummy = () => { + const ref: React.RefObject = React.createRef(); + + useClickAway(ref, onClickAway); + + const onClick = () => { + console.log('Clicked'); + }; + + return ( +
+ Wrapper +
+ Click Me +
+
+ ); + }; + + it('calls the clickAway callback when click event occurs on non-target ref', () => { + render(); + + const Wrapper = screen.getByText('Wrapper'); + + Wrapper.focus(); + Wrapper.click(); + + expect(onClickAway).toHaveBeenCalled(); + }); +}); diff --git a/packages/useclickaway/src/index.ts b/packages/useclickaway/src/index.ts index a3f5468..f8a8768 100644 --- a/packages/useclickaway/src/index.ts +++ b/packages/useclickaway/src/index.ts @@ -1,3 +1,18 @@ -export function useClickAway() { - // TODO +import { useEffect, RefObject } from 'react'; + +export function useClickAway( + ref: RefObject, + onClickAway: (e: Event) => void +) { + const handleClick = (e: Event) => { + ref.current && !ref.current.contains(e.target as Node) && onClickAway(e); + }; + + useEffect(() => { + document.addEventListener('click', handleClick); + + return function unmountUseClickAway() { + document.removeEventListener('click', handleClick); + }; + }, [ref]); }