@modern-kit/react
Version:
60 lines (57 loc) • 1.78 kB
JavaScript
import { useState, useRef, useCallback } from 'react';
import { usePreservedCallback } from '../usePreservedCallback/index.mjs';
import { noop } from '@modern-kit/utils';
function useIntersectionObserver({
onIntersectStart = noop,
onIntersectEnd = noop,
enabled = true,
calledOnce = false,
root = null,
threshold = 0,
rootMargin = "0px 0px 0px 0px"
} = {}) {
const [isIntersecting, setIsIntersecting] = useState(false);
const [hasIntersected, setHasIntersected] = useState(false);
const observerRef = useRef(null);
const calledCount = useRef(0);
const intersectionObserverCallback = usePreservedCallback(
([entry], observer) => {
if (!entry) return;
const targetElement = entry.target;
setIsIntersecting(entry.isIntersecting);
if (entry.isIntersecting) {
calledCount.current += 1;
setHasIntersected(true);
onIntersectStart(entry);
} else if (isIntersecting) {
calledCount.current += 1;
onIntersectEnd(entry);
}
if (calledOnce && calledCount.current > 1) {
observer.unobserve(targetElement);
}
}
);
const targetRef = useCallback(
(node) => {
if (observerRef.current) {
observerRef.current.disconnect();
observerRef.current = null;
}
if (node == null || !enabled) return;
observerRef.current = new IntersectionObserver(
intersectionObserverCallback,
{
threshold,
root,
rootMargin
}
);
observerRef.current.observe(node);
},
[enabled, threshold, root, rootMargin, intersectionObserverCallback]
);
return { ref: targetRef, isIntersecting, hasIntersected };
}
export { useIntersectionObserver };
//# sourceMappingURL=index.mjs.map