46 lines
1003 B
TypeScript
46 lines
1003 B
TypeScript
import React, {
|
|
useCallback,
|
|
useEffect,
|
|
useRef,
|
|
ReactNode,
|
|
MutableRefObject,
|
|
} from 'react';
|
|
|
|
interface ClickOutsideProps {
|
|
children?: ReactNode;
|
|
onClickOutside: () => void;
|
|
excludedElements: MutableRefObject<any>[];
|
|
}
|
|
|
|
const ClickOutside = ({
|
|
children,
|
|
onClickOutside,
|
|
excludedElements,
|
|
}: ClickOutsideProps) => {
|
|
const wrapperRef = useRef(null);
|
|
|
|
const handleClickOutside = useCallback(
|
|
(event) => {
|
|
if (
|
|
wrapperRef.current &&
|
|
!wrapperRef.current.contains(event.target) &&
|
|
!excludedElements.some((el) => el.current.contains(event.target))
|
|
) {
|
|
onClickOutside();
|
|
}
|
|
},
|
|
[wrapperRef, onClickOutside, ...excludedElements],
|
|
);
|
|
|
|
useEffect(() => {
|
|
document.addEventListener('mousedown', handleClickOutside);
|
|
return () => {
|
|
document.removeEventListener('mousedown', handleClickOutside);
|
|
};
|
|
}, [handleClickOutside]);
|
|
|
|
return <div ref={wrapperRef}>{children}</div>;
|
|
};
|
|
|
|
export default ClickOutside;
|