SHARE
TWEET

Untitled

a guest Jul 21st, 2019 59 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React from "react";
  2.  
  3. export default function useClickOutside(onClickOutside, exempt = []) {
  4.   const container = React.useRef(null);
  5.   const mouseDownTargetIsOutside = React.useRef(false);
  6.  
  7.   React.useEffect(() => {
  8.     /* if the click event doesnt start outside of the element then we want to ignore it */
  9.     /* imagine if someone clicked while swiping the cursor, if it started inside, then they probably */
  10.     /* wouldn't expect mouseup to fire like it was outside */
  11.     function onMouseDown(event) {
  12.       /* If the target is inside, then don't fire click outside handler */
  13.       if (container.current && container.current.contains(event.target)) {
  14.         mouseDownTargetIsOutside.current = false;
  15.         return;
  16.       }
  17.  
  18.       mouseDownTargetIsOutside.current = true;
  19.     }
  20.  
  21.     function onMouseUp(event) {
  22.       /* If both targets weren't outside then we can bail early */
  23.       const mouseUpTargetIsOutside =
  24.         !container.current || !container.current.contains(event.target);
  25.       if (!mouseDownTargetIsOutside.current || !mouseUpTargetIsOutside) {
  26.         return;
  27.       }
  28.  
  29.       /* exempt is an array of strings (css selectors) or html elements */
  30.       /* Here we figure out if the target matches either, or is nested inside an exempt element */
  31.       const targetIsExempt = exempt.some(selectorOrElement => {
  32.         if (typeof selectorOrElement === "string") {
  33.           return Boolean(event.target.closest(selectorOrElement));
  34.         } else if (
  35.           selectorOrElement instanceof HTMLElement ||
  36.           selectorOrElement.current instanceof HTMLElement
  37.         ) {
  38.           const element = selectorOrElement.current || selectorOrElement;
  39.           return event.target === element || element.contains(event.target);
  40.         }
  41.  
  42.         return false;
  43.       });
  44.  
  45.       if (targetIsExempt) {
  46.         return;
  47.       }
  48.  
  49.       onClickOutside(event, container);
  50.     }
  51.  
  52.     window.addEventListener("mousedown", onMouseDown, true);
  53.     window.addEventListener("mouseup", onMouseUp, true);
  54.  
  55.     return () => {
  56.       window.removeEventListener("mousedown", onMouseDown, true);
  57.       window.removeEventListener("mouseup", onMouseUp, true);
  58.     };
  59.   });
  60.  
  61.   return container;
  62. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top