Skip to content

Instantly share code, notes, and snippets.

@loopdream
Last active July 19, 2022 20:06
Show Gist options
  • Save loopdream/9492cc5785a21d27ffa810375b0cb071 to your computer and use it in GitHub Desktop.
Save loopdream/9492cc5785a21d27ffa810375b0cb071 to your computer and use it in GitHub Desktop.
/**
* This component comes from https://github.com/tj/react-click-outside.
*
* It was copied and converted to use hooks and TypeScript
*/
import React, { useEffect, useRef } from "react";
export interface Props {
children: React.ReactNode;
onClickOutside(e: TouchEvent | MouseEvent): void;
}
const ClickOutside = ({
children,
onClickOutside,
...props
}: Props): JSX.Element => {
const container = useRef<HTMLDivElement>(null);
const isTouch = useRef(false);
const handle = (e: TouchEvent | MouseEvent) => {
if (e.type === "touchend") isTouch.current = true;
if (e.type === "click" && isTouch.current) return;
const el = container.current;
if (el && !el.contains(e.target as HTMLElement)) onClickOutside(e);
};
useEffect(() => {
document.addEventListener("touchend", handle, true);
document.addEventListener("click", handle, true);
return () => {
document.removeEventListener("touchend", handle, true);
document.removeEventListener("click", handle, true);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<div {...props} ref={container}>
{children}
</div>
);
};
export default ClickOutside;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment