utils/use-untersection-tracking.ts (49 lines of code) (raw):

import { useEffect, useRef, useState } from 'react'; /** * Tracks the intersection of a target DOM element * with the viewport and triggers a callback * when the element becomes visible. */ export const useIntersectionTracking = ( callback: () => void, visibilityDelay: number = 5000 ) => { const threshold = 0.3; const triggerOnce = true; const elementRef = useRef<HTMLElement>(null); const [hasTriggered, setHasTriggered] = useState(false); const timeoutRef = useRef<NodeJS.Timeout | null>(null); useEffect(() => { const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting && (!triggerOnce || !hasTriggered)) { if (timeoutRef.current) { clearTimeout(timeoutRef.current); } timeoutRef.current = setTimeout(() => { callback(); if (triggerOnce) { setHasTriggered(true); } timeoutRef.current = null; }, visibilityDelay); } else { if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; } } }, { threshold } ); if (elementRef.current) { observer.observe(elementRef.current); } return () => { if (timeoutRef.current) { clearTimeout(timeoutRef.current); } if (elementRef.current) { observer.unobserve(elementRef.current); } }; }, [callback, threshold, triggerOnce, hasTriggered, visibilityDelay]); return elementRef; };