ClickAwayListener.tsx 893 B

12345678910111213141516171819202122232425262728293031323334353637383940
  1. import React, { useEffect, useRef } from 'react';
  2. type Props = {
  3. onClick: (e: MouseEvent | TouchEvent) => void;
  4. children: React.ReactNode;
  5. };
  6. const ClickAwayListener: React.FC<Props> = ({
  7. onClick,
  8. children,
  9. ...rest
  10. }: Props) => {
  11. const node = useRef<HTMLDivElement>(null);
  12. useEffect(() => {
  13. const handleClick = (e: MouseEvent | TouchEvent) => {
  14. if (node.current && node.current.contains(e.target as HTMLElement)) {
  15. return;
  16. }
  17. onClick(e);
  18. };
  19. document.addEventListener('mousedown', handleClick);
  20. document.addEventListener('touchstart', handleClick);
  21. return () => {
  22. document.removeEventListener('mousedown', handleClick);
  23. document.removeEventListener('touchstart', handleClick);
  24. };
  25. }, [onClick]);
  26. return (
  27. <span ref={node} {...rest}>
  28. {children}
  29. </span>
  30. );
  31. };
  32. export default ClickAwayListener;