import { MaybeRef , noop , unRef } from '@react-hooks-library/shared' ; import { useCallback , useEffect , useRef , useState } from 'react' ; import { _document } from '../_ssr.config' ; import { useIsSupported } from '../useIsSupported' ; import { useUnMount } from '../useUnMount' ; export interface IntersectionObserverOptions { default root ? : MaybeRef < Element | Document | undefined | null > ; default rootMargin ? : string ; default threshold ? : number | number [ ] ; } param target param options param callback see https see https export function useIntersectionObserver ( target , options = { } , callback = noop ) { const { root = _document , rootMargin = '0px' , threshold = 0 } = options ; const [ inView , setInView ] = useState ( false ) ; const [ entry , setEntry ] = useState < IntersectionObserverEntry | null > ( null ) ; const isSupported = useIsSupported ( ( ) => 'IntersectionObserver' in window ) ; const observer = useRef < IntersectionObserver | null > ( null ) ; const stop = useCallback ( ( ) => { if ( ! observer . current ) return ; observer . current . disconnect ( ) ; observer . current = null ; } , [ ] ) ; useUnMount ( stop ) ; useEffect ( ( ) => { const el = unRef ( target ) ; const rootEl = unRef ( root ) ; if ( ! ( isSupported && el && rootEl ) ) return ; observer . current = new window . IntersectionObserver ( ( entries , observer ) => { const thresholds = Array . isArray ( threshold ) ? threshold : [ threshold ] ; entries . forEach ( ( entry ) => { const inView = entry . isIntersecting && thresholds . some ( ( threshold ) => entry . intersectionRatio >= threshold ) ; setInView ( inView ) ; setEntry ( entry ) ; } ) ; callback ( entries , observer ) ; } , { root : rootEl , rootMargin , threshold } ) ; observer . current ?. observe ( el ) ; return stop ; } , [ callback , isSupported , root , rootMargin , stop , target , threshold ] ) ; return { isSupported , stop , inView , entry } ; }