import { useEffect } from "react"; // Improved version of https://usehooks.com/useOnClickOutside/ const useClickOutside = (ref, handler) => { useEffect(() => { let startedInside = false; let startedWhenMounted = false; const listener = (event) => { // Do nothing if `mousedown` or `touchstart` started inside ref element if (startedInside || !startedWhenMounted) return; // Do nothing if clicking ref's element or descendent elements if (!ref.current || ref.current.contains(event.target)) return; handler(event); }; const validateEventStart = (event) => { startedWhenMounted = ref.current; startedInside = ref.current && ref.current.contains(event.target); }; document.addEventListener("mousedown", validateEventStart); document.addEventListener("touchstart", validateEventStart); document.addEventListener("click", listener); return () => { document.removeEventListener("mousedown", validateEventStart); document.removeEventListener("touchstart", validateEventStart); document.removeEventListener("click", listener); }; }, [ref, handler]); }; export default useClickOutside;