@wulperstudio/cms
Version:
Wulper Studio Library Components CMS
77 lines • 3.21 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
/* eslint-disable no-undef */
import { useState, useCallback, useEffect, useRef } from 'react';
var DEFAULT_ROOT_MARGIN = '0px';
var DEFAULT_THRESHOLD = [0];
// For more info:
// https://developers.google.com/web/updates/2016/04/intersectionobserver
// https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
export var useIntersectionObserver = function useIntersectionObserver(args) {
var _args$rootMargin, _args$threshold;
var rootMargin = (_args$rootMargin = args == null ? void 0 : args.rootMargin) != null ? _args$rootMargin : DEFAULT_ROOT_MARGIN;
var threshold = (_args$threshold = args == null ? void 0 : args.threshold) != null ? _args$threshold : DEFAULT_THRESHOLD;
var nodeRef = useRef(null);
var rootRef = useRef(null);
var observerRef = useRef(null);
var _useState = useState(),
_useState2 = _slicedToArray(_useState, 2),
entry = _useState2[0],
setEntry = _useState2[1];
var unobserve = useCallback(function () {
// Disconnect the current observer (if there is one)
var currentObserver = observerRef.current;
currentObserver == null || currentObserver.disconnect();
observerRef.current = null;
}, []);
var observe = useCallback(function () {
var node = nodeRef.current;
if (node) {
var root = rootRef.current;
var options = {
root: root,
rootMargin: rootMargin,
threshold: threshold
};
// Create a observer for current "node" with given options.
var observer = new IntersectionObserver(function (_ref) {
var _ref2 = _slicedToArray(_ref, 1),
newEntry = _ref2[0];
setEntry(newEntry);
}, options);
observer.observe(node);
observerRef.current = observer;
}
}, [rootMargin, threshold]);
var initializeObserver = useCallback(function () {
unobserve();
observe();
}, [observe, unobserve]);
var refCallback = useCallback(function (node) {
nodeRef.current = node;
initializeObserver();
}, [initializeObserver]);
var rootRefCallback = useCallback(function (rootNode) {
rootRef.current = rootNode;
initializeObserver();
}, [initializeObserver]);
useEffect(function () {
// After React 18, StrictMode unmounts and mounts components to be sure
// if they are resilient effects being mounted and destroyed multiple times.
// This a behavior to be sure nothing breaks when off-screen components
// can preserve their state with future React versions.
// So in StrictMode, React unmounts the component, clean-up of this useEffect gets triggered and
// we stop observing the node. But we need to start observing after component
// re-mounts with its preserved state.
// So to handle this case, we call initializeObserver here.
// https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#updates-to-strict-mode
initializeObserver();
return function () {
// We disconnect the observer on unmount to prevent memory leaks etc.
unobserve();
};
}, [initializeObserver, unobserve]);
return [refCallback, {
entry: entry,
rootRef: rootRefCallback
}];
};