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.

1 lines 6.85 kB
{"version":3,"file":"use-visible.cjs","sources":["../../src/utils/use-visible.ts"],"sourcesContent":["import { useLatest } from \"@liveblocks/react/_private\";\nimport { type RefObject, useEffect, useState } from \"react\";\n\ninterface ObserveOptions {\n rootMargin?: string | number;\n root?: RefObject<Element>;\n threshold?: number | number[];\n}\n\ninterface Options extends ObserveOptions {\n enabled?: boolean;\n}\n\ninterface VisibleOptions<T = boolean> extends Options {\n initialValue?: T;\n}\n\ntype IntersectionObserverSingleCallback = (\n entry: IntersectionObserverEntry\n) => void;\n\nlet optionlessIntersectionObserver: IntersectionObserver | undefined;\nconst optionlessIntersectionCallbacks = new WeakMap<\n Element,\n IntersectionObserverSingleCallback\n>();\n\nconst individualIntersectionObservers = new WeakMap<\n Element,\n IntersectionObserver\n>();\n\nfunction observe(\n element: Element,\n callback: IntersectionObserverSingleCallback,\n options?: ObserveOptions\n) {\n // Observers without options share a common IntersectionObserver instance, ones with options have their own\n if (!options) {\n if (!optionlessIntersectionObserver) {\n optionlessIntersectionObserver = new IntersectionObserver((entries) => {\n for (const entry of entries) {\n const callback = optionlessIntersectionCallbacks.get(entry.target);\n\n callback?.(entry);\n }\n });\n }\n\n optionlessIntersectionCallbacks.set(element, callback);\n optionlessIntersectionObserver.observe(element);\n } else {\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n callback?.(entry);\n }\n },\n {\n root: options.root?.current,\n rootMargin:\n typeof options.rootMargin === \"number\"\n ? `${options.rootMargin}px`\n : options.rootMargin,\n threshold: options.threshold,\n }\n );\n\n individualIntersectionObservers.set(element, observer);\n observer.observe(element);\n }\n}\n\nfunction unobserve(element: Element, options?: ObserveOptions) {\n if (!options) {\n optionlessIntersectionCallbacks.delete(element);\n optionlessIntersectionObserver?.unobserve(element);\n } else {\n const observer = individualIntersectionObservers.get(element);\n\n observer?.unobserve(element);\n individualIntersectionObservers.delete(element);\n }\n}\n\n/**\n * Observe when an element enters or exits the viewport.\n *\n * If you only need to get a stateful visibility value, use the higher level hook `useVisible` instead.\n */\nexport function useIntersectionCallback(\n ref: RefObject<Element>,\n callback: (isIntersecting: boolean, entry: IntersectionObserverEntry) => void,\n options?: Options\n) {\n const enabled = options?.enabled ?? true;\n const latestCallback = useLatest(callback);\n const { root, rootMargin, threshold } = options ?? {};\n\n useEffect(() => {\n const element = ref.current;\n\n if (!element) {\n return;\n }\n\n const observeOptions: ObserveOptions = {\n root,\n rootMargin,\n threshold,\n };\n\n if (enabled) {\n observe(\n element,\n (entry) => {\n // The intersection observer entry might be useful in some cases but the main information\n // is whether the element is intersecting or not so we pass that as the first argument.\n latestCallback.current(entry.isIntersecting, entry);\n },\n observeOptions\n );\n } else {\n unobserve(element, observeOptions);\n }\n\n return () => {\n unobserve(element, observeOptions);\n };\n }, [ref, enabled, latestCallback, root, rootMargin, threshold]);\n}\n\n/**\n * Observe whether an element is currently visible or not.\n */\nexport function useVisible<T extends boolean | null = boolean>(\n ref: RefObject<Element>,\n options?: VisibleOptions<T>\n) {\n const [isVisible, setVisible] = useState(\n options?.initialValue !== undefined ? options.initialValue : false\n );\n\n useIntersectionCallback(\n ref,\n (isIntersecting) => setVisible(isIntersecting),\n options\n );\n\n return isVisible;\n}\n"],"names":["callback","useLatest","useEffect","useState"],"mappings":"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"}