UNPKG

react-intersection-observer-hook

Version:
155 lines (149 loc) 5.01 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { useIntersectionObserver: () => use_intersection_observer_default, useTrackVisibility: () => use_track_visibility_default }); module.exports = __toCommonJS(src_exports); // src/use-intersection-observer.ts var import_react = require("react"); // src/utils.ts function createObserverCache() { const cachesByRoot = /* @__PURE__ */ new Map(); function getObserver({ root, rootMargin, threshold }) { let cacheByRoot = cachesByRoot.get(root); if (!cacheByRoot) { cacheByRoot = /* @__PURE__ */ new Map(); cachesByRoot.set(root, cacheByRoot); } const cacheKey = JSON.stringify({ rootMargin, threshold }); let cachedObserver = cacheByRoot.get(cacheKey); if (!cachedObserver) { const entryCallbacks = /* @__PURE__ */ new Map(); const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { const callback = entryCallbacks.get(entry.target); callback?.(entry); }); }, { root, rootMargin, threshold } ); cachedObserver = { observer, entryCallbacks }; cacheByRoot.set(cacheKey, cachedObserver); } return { observe: (node, callback) => { cachedObserver.entryCallbacks.set(node, callback); cachedObserver.observer.observe(node); }, unobserve: (node) => { cachedObserver.entryCallbacks.delete(node); cachedObserver.observer.unobserve(node); } }; } return { getObserver }; } // src/use-intersection-observer.ts var DEFAULT_ROOT_MARGIN = "0px"; var DEFAULT_THRESHOLD = [0]; var observerCache = createObserverCache(); function useIntersectionObserver(args) { const rootMargin = args?.rootMargin ?? DEFAULT_ROOT_MARGIN; const threshold = args?.threshold ?? DEFAULT_THRESHOLD; const nodeRef = (0, import_react.useRef)(null); const rootRef = (0, import_react.useRef)(null); const observerRef = (0, import_react.useRef)(null); const [entry, setEntry] = (0, import_react.useState)(); const reinitializeObserver = (0, import_react.useCallback)(() => { function cleanupObserver() { const observer = observerRef.current; const node = nodeRef.current; if (node) { observer?.unobserve(node); setEntry(void 0); } observerRef.current = null; } function initializeObserver() { const node = nodeRef.current; if (!node) return; const observer = observerCache.getObserver({ root: rootRef.current, rootMargin, threshold }); observer.observe(node, (observedEntry) => { setEntry(observedEntry); }); observerRef.current = observer; } cleanupObserver(); initializeObserver(); }, [rootMargin, threshold]); const refCallback = (0, import_react.useCallback)( (node) => { nodeRef.current = node; reinitializeObserver(); return () => { nodeRef.current = null; reinitializeObserver(); }; }, [reinitializeObserver] ); const rootRefCallback = (0, import_react.useCallback)( (rootNode) => { rootRef.current = rootNode; reinitializeObserver(); return () => { rootRef.current = null; reinitializeObserver(); }; }, [reinitializeObserver] ); return [refCallback, { entry, rootRef: rootRefCallback }]; } var use_intersection_observer_default = useIntersectionObserver; // src/use-track-visibility.ts var import_react2 = require("react"); function useTrackVisibility(args) { const { once, ...rest } = args ?? {}; const [ref, result] = use_intersection_observer_default(rest); const isVisible = Boolean(result.entry?.isIntersecting); const [isVisibleOnce, setIsVisibleOnce] = (0, import_react2.useState)(isVisible); if (once && isVisible && !isVisibleOnce) { setIsVisibleOnce(true); } return [ref, { ...result, isVisible: once ? isVisibleOnce : isVisible }]; } var use_track_visibility_default = useTrackVisibility; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { useIntersectionObserver, useTrackVisibility });