All files / Rindu/hooks useNearScreen.ts

5.26% Statements 1/19
0% Branches 0/15
0% Functions 0/4
5.88% Lines 1/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 5419x                                                                                                          
import { MutableRefObject, useEffect, useRef, useState } from "react";
 
interface UserNearScreen {
  distance: string;
  externalRef?: MutableRefObject<unknown>;
  once?: boolean;
  observe: boolean;
}
 
export function useNearScreen({
  distance = "100px",
  externalRef,
  once = true,
  observe,
}: UserNearScreen): {
  isNearScreen: boolean;
  fromRef: MutableRefObject<undefined>;
} {
  const [isNearScreen, setIsNearScreen] = useState(false);
  const fromRef = useRef();
 
  useEffect(() => {
    const element = externalRef ? externalRef.current : fromRef.current;
 
    function onChange(
      entries: IntersectionObserverEntry[],
      observer: IntersectionObserver
    ) {
      const element = entries[0];
 
      if (element.isIntersecting) {
        setIsNearScreen(true);
        Iif (once) {
          observer.disconnect();
        }
      } else Iif (!once) {
        setIsNearScreen(false);
      }
    }
 
    const observer = observe
      ? new IntersectionObserver(onChange, {
          rootMargin: distance,
        })
      : undefined;
 
    Iif (element && observe) observer?.observe(element as HTMLElement);
 
    return () => observer && observer.disconnect();
  });
 
  return { isNearScreen, fromRef };
}