Skip to content

Instantly share code, notes, and snippets.

@franciscofsales
Created December 11, 2019 14:06
Show Gist options
  • Save franciscofsales/914d8eabfb483f61885d620d3af4abce to your computer and use it in GitHub Desktop.
Save franciscofsales/914d8eabfb483f61885d620d3af4abce to your computer and use it in GitHub Desktop.
Custom hook to trigger callback when there is a click outside the passed in elements or its children
import { useEffect } from 'react';
/**
* Hook that handles clicks outside of the passed refs or its children
*/
export default function useClickOutside(refs: Array<any>, callback: any) {
/**
* Handle click on outside of element
*/
function handleClickOutside(event: { target: any }) {
let clickedOutside = true;
const inspectElement = (elem: any): boolean | null => {
if (elem && elem.current && elem.current.contains(event.target)) {
clickedOutside = false;
return false;
}
if (
elem &&
elem.current &&
elem.current.children &&
elem.current.children.length
) {
for (let j = 0; j < elem.current.children.length; j += 1) {
inspectElement(elem.current.children.item(j));
}
} else {
return true;
}
return null;
};
refs.forEach(ref => {
inspectElement(ref);
});
if (clickedOutside && callback) {
callback();
}
}
useEffect(() => {
// Bind the event listener
document.addEventListener('mousedown', handleClickOutside);
return () => {
// Unbind the event listener on clean up
document.removeEventListener('mousedown', handleClickOutside);
};
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment