All files / src/common/hooks useClickOutside.ts

7.69% Statements 2/26
100% Branches 0/0
0% Functions 0/1
7.69% Lines 2/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 381x       1x                                                                  
import { useEffect, useRef } from 'react';
 
type Event = MouseEvent | TouchEvent;
 
export function useClickOutside<T extends HTMLElement = HTMLElement>(
  handler: (event: Event) => void
) {
  const ref = useRef<T>(null);
  const savedHandler = useRef(handler);
 
  useEffect(() => {
    savedHandler.current = handler;
  }, [handler]);
 
  useEffect(() => {
    const listener = (event: Event) => {
      const element = ref.current;
      
      // Do nothing if clicking ref's element or descendent elements
      if (!element || element.contains(event.target as Node)) {
        return;
      }
      
      savedHandler.current(event);
    };
 
    document.addEventListener('mousedown', listener);
    document.addEventListener('touchstart', listener);
 
    return () => {
      document.removeEventListener('mousedown', listener);
      document.removeEventListener('touchstart', listener);
    };
  }, [ref]);
 
  return ref;
}