useOnClickOutside.tsx 924 B

123456789101112131415161718192021222324252627282930313233
  1. import {useEffect} from 'react';
  2. // hook from https://usehooks.com/useOnClickOutside/
  3. function useOnClickOutside<T extends HTMLElement = HTMLElement>(
  4. ref: React.RefObject<T>,
  5. handler: (event: MouseEvent | TouchEvent) => void
  6. ) {
  7. useEffect(
  8. () => {
  9. const listener = (event: MouseEvent | TouchEvent) => {
  10. const el = ref?.current;
  11. // Do nothing if clicking ref's element or descendent elements
  12. if (!el || el.contains(event.target as Node)) {
  13. return;
  14. }
  15. handler(event);
  16. };
  17. document.addEventListener('mousedown', listener);
  18. document.addEventListener('touchstart', listener);
  19. return () => {
  20. document.removeEventListener('mousedown', listener);
  21. document.removeEventListener('touchstart', listener);
  22. };
  23. },
  24. // Reload only if ref or handler changes
  25. [ref, handler]
  26. );
  27. }
  28. export default useOnClickOutside;