import { RefObject, useCallback, useEffect } from 'react'; const isRefArray = ( r: RefObject | RefObject[] ): r is RefObject[] => { return 'length' in r; }; const isTarget = (ref: RefObject, event: MouseEvent) => { return ref && ref.current && ref.current.contains(event.target); }; const trueForAny = (array: any[], condition: (props: any) => boolean) => { return array.reduce((conditionAlreadyMet, value) => { return conditionAlreadyMet || condition(value); }, false); }; const useOutsideClick = ( ref: RefObject | RefObject[], onclick: () => void ) => { const handleClick = useCallback( (click: MouseEvent) => { if (isRefArray(ref)) { if (trueForAny(ref, (ref: RefObject) => isTarget(ref, click))) { return; } } else { if (isTarget(ref, click)) { return; } } onclick(); }, [onclick, ref] ); useEffect(() => { document.addEventListener('click', handleClick); return () => { document.removeEventListener('click', handleClick); }; }, [handleClick]); return ref; }; export default useOutsideClick;