Advertisement
Guest User

Untitled

a guest
Apr 21st, 2019
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.20 KB | None | 0 0
  1. import * as React from 'react';
  2.  
  3. export interface IClickOutsideProps {
  4. onClick: () => void;
  5. /** element to add the click event listener, default selector is body */
  6. parentTargetQuerySelector?: string;
  7. }
  8.  
  9. /**
  10. * Function Component to re-use the behavior of click outside
  11. *
  12. * expects to have a children and a defined onClick callback
  13. */
  14. const ClickOutside: React.FunctionComponent<IClickOutsideProps> = ({
  15. parentTargetQuerySelector = 'body',
  16. children,
  17. onClick
  18. }) => {
  19. const refs = React.Children.map(children, () => React.useRef<any>(null));
  20.  
  21. const appElement = window.document.querySelector(parentTargetQuerySelector) || window.document;
  22.  
  23. const handleClick = React.useCallback(
  24. (e: Event) => {
  25. const isOutside = refs.every(ref => {
  26. if (!ref.current) {
  27. return false;
  28. }
  29. return !ref.current!.contains(e.target);
  30. });
  31.  
  32. if (isOutside) {
  33. onClick();
  34. }
  35. },
  36. [onClick]
  37. );
  38.  
  39. React.useEffect(() => {
  40. appElement.addEventListener('click', handleClick);
  41. return () => appElement.removeEventListener('click', handleClick);
  42. }, [handleClick]);
  43.  
  44. return <>{React.Children.map(children, (element: any, idx) => React.cloneElement(element, { ref: refs[idx] }))}</>;
  45. };
  46.  
  47. export default ClickOutside;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement