Created
April 2, 2021 17:02
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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