Skip to content

Instantly share code, notes, and snippets.

@dmwyatt
Created April 2, 2021 17:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmwyatt/193601c57f85a57bc3089aa48554cc08 to your computer and use it in GitHub Desktop.
Save dmwyatt/193601c57f85a57bc3089aa48554cc08 to your computer and use it in GitHub Desktop.
[clickOutsideDector] React component to detect if the component it's wrapping is clicked outside of. #React #ui
// https://css-tricks.com/click-outside-detector/
// https://codepen.io/chriscoyier/project/editor/AxPzxn
import React, { useEffect, useRef, forwardRef } from 'https://cdn.skypack.dev/react';
const ClickOutsideDetector = forwardRef(function ClickOutsideDetector(
{ listen, onClickOutside, ignore, ...props },
ref
) {
const container = ref || useRef(null);
const onKeyUp = (e) => {
// If the user hits ESC, it's considered a click outside!
if (e.keyCode === 27) onClickOutside()
handleEvent(e);
};
const handleEvent = (e) => {
if (container.current.contains(e.target)) return;
// This ignore prop is used mostly for the buttons/links that toggle menus and drawers
if (ignore && ignore.contains && ignore.contains(e.target)) {
return;
}
onClickOutside();
};
useEffect(() => {
if (listen && onClickOutside) {
// Add listeners
document.addEventListener('mousedown', handleEvent, false);
document.addEventListener('touchend', handleEvent, false);
document.addEventListener('keyup', onKeyUp);
return () => {
// Remove listeners
document.removeEventListener('mousedown', handleEvent, false);
document.removeEventListener('touchend', handleEvent, false);
document.removeEventListener('keyup', onKeyUp);
};
}
});
return <div ref={container} {...props} />;
});
export default ClickOutsideDetector;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment