32 lines
1.1 KiB
TypeScript
32 lines
1.1 KiB
TypeScript
import { useRef, useState, useEffect } from "react";
|
|
import { DEFAULT_INTERSECTION_OPTIONS } from "utils/constants";
|
|
|
|
export const useIsVisible = (
|
|
elementRef: React.MutableRefObject<HTMLElement | null>,
|
|
parentSelector?: string | React.MutableRefObject<HTMLElement | null>,
|
|
alwaysVisible = false
|
|
): boolean => {
|
|
const watching = useRef(false);
|
|
const [isVisible, setIsVisible] = useState(alwaysVisible);
|
|
|
|
useEffect(() => {
|
|
if (alwaysVisible || !elementRef.current || watching.current) return;
|
|
|
|
watching.current = true;
|
|
|
|
new IntersectionObserver(
|
|
(entries) =>
|
|
entries.forEach(({ isIntersecting }) => setIsVisible(isIntersecting)),
|
|
{
|
|
root:
|
|
(typeof parentSelector === "object" && parentSelector.current) ||
|
|
(typeof parentSelector === "string" &&
|
|
elementRef.current.closest(parentSelector)) ||
|
|
elementRef.current.parentElement,
|
|
...DEFAULT_INTERSECTION_OPTIONS,
|
|
}
|
|
).observe(elementRef.current);
|
|
}, [alwaysVisible, elementRef, parentSelector]);
|
|
|
|
return isVisible;
|
|
};
|