Files
supabase/apps/ui-library/hooks/useIntersectionObserver.ts
2026-03-09 14:32:44 +01:00

40 lines
1.2 KiB
TypeScript

import { RefCallback, useCallback, useRef, useState } from 'react'
// https://github.com/uidotdev/usehooks/blob/945436df0037bc21133379a5e13f1bd73f1ffc36/index.js#L512
export function useIntersectionObserver<T extends Element>(
options: {
root?: Element | Document | null
rootMargin?: string
threshold?: number | number[]
} = {}
): [RefCallback<T>, IntersectionObserverEntry | null] {
const { threshold = 1, root = null, rootMargin = '0px' } = options
const [entry, setEntry] = useState<IntersectionObserverEntry | null>(null)
const previousObserver = useRef<IntersectionObserver | null>(null)
const customRef = useCallback(
(node: T | null) => {
if (previousObserver.current) {
previousObserver.current.disconnect()
previousObserver.current = null
}
if (node?.nodeType === Node.ELEMENT_NODE) {
const observer = new IntersectionObserver(
([entry]) => {
setEntry(entry)
},
{ threshold, root, rootMargin }
)
observer.observe(node)
previousObserver.current = observer
}
},
[threshold, root, rootMargin]
)
return [customRef, entry]
}