UNPKG

@liveblocks/react-ui

Version:

A set of React pre-built components for the Liveblocks products. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.

90 lines (87 loc) 2.69 kB
import { useLatest } from '@liveblocks/react/_private'; import { useEffect, useState } from 'react'; let optionlessIntersectionObserver; const optionlessIntersectionCallbacks = /* @__PURE__ */ new WeakMap(); const individualIntersectionObservers = /* @__PURE__ */ new WeakMap(); function observe(element, callback, options) { if (!options) { if (!optionlessIntersectionObserver) { optionlessIntersectionObserver = new IntersectionObserver((entries) => { for (const entry of entries) { const callback2 = optionlessIntersectionCallbacks.get(entry.target); callback2?.(entry); } }); } optionlessIntersectionCallbacks.set(element, callback); optionlessIntersectionObserver.observe(element); } else { const observer = new IntersectionObserver( (entries) => { for (const entry of entries) { callback?.(entry); } }, { root: options.root?.current, rootMargin: typeof options.rootMargin === "number" ? `${options.rootMargin}px` : options.rootMargin, threshold: options.threshold } ); individualIntersectionObservers.set(element, observer); observer.observe(element); } } function unobserve(element, options) { if (!options) { optionlessIntersectionCallbacks.delete(element); optionlessIntersectionObserver?.unobserve(element); } else { const observer = individualIntersectionObservers.get(element); observer?.unobserve(element); individualIntersectionObservers.delete(element); } } function useIntersectionCallback(ref, callback, options) { const enabled = options?.enabled ?? true; const latestCallback = useLatest(callback); const { root, rootMargin, threshold } = options ?? {}; useEffect(() => { const element = ref.current; if (!element) { return; } const observeOptions = { root, rootMargin, threshold }; if (enabled) { observe( element, (entry) => { latestCallback.current(entry.isIntersecting, entry); }, observeOptions ); } else { unobserve(element, observeOptions); } return () => { unobserve(element, observeOptions); }; }, [ref, enabled, latestCallback, root, rootMargin, threshold]); } function useVisible(ref, options) { const [isVisible, setVisible] = useState( options?.initialValue !== void 0 ? options.initialValue : false ); useIntersectionCallback( ref, (isIntersecting) => setVisible(isIntersecting), options ); return isVisible; } export { useIntersectionCallback, useVisible }; //# sourceMappingURL=use-visible.js.map