@wulperstudio/cms
Version:
Wulper Studio Library Components CMS
85 lines (83 loc) • 3.59 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useIntersectionObserver = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _react = require("react");
/* eslint-disable no-undef */
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
var useIntersectionObserver = exports.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 = (0, _react.useRef)(null);
var rootRef = (0, _react.useRef)(null);
var observerRef = (0, _react.useRef)(null);
var _useState = (0, _react.useState)(),
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
entry = _useState2[0],
setEntry = _useState2[1];
var unobserve = (0, _react.useCallback)(function () {
// Disconnect the current observer (if there is one)
var currentObserver = observerRef.current;
currentObserver == null || currentObserver.disconnect();
observerRef.current = null;
}, []);
var observe = (0, _react.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 = (0, _slicedToArray2["default"])(_ref, 1),
newEntry = _ref2[0];
setEntry(newEntry);
}, options);
observer.observe(node);
observerRef.current = observer;
}
}, [rootMargin, threshold]);
var initializeObserver = (0, _react.useCallback)(function () {
unobserve();
observe();
}, [observe, unobserve]);
var refCallback = (0, _react.useCallback)(function (node) {
nodeRef.current = node;
initializeObserver();
}, [initializeObserver]);
var rootRefCallback = (0, _react.useCallback)(function (rootNode) {
rootRef.current = rootNode;
initializeObserver();
}, [initializeObserver]);
(0, _react.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
}];
};