@netdata/netdata-ui
Version:
netdata UI kit
82 lines • 2.63 kB
JavaScript
import { useCallback, useEffect, useRef, useState } from "react";
import uuid from "../../mixins/uuid";
var roots = new Map();
var observers = {};
var totalObservers = {};
var callbacks = new Map();
var getRootId = function getRootId(root) {
if (roots.has(root)) return roots.get(root);
var id = uuid();
roots.set(root, id);
return id;
};
var getId = function getId(_ref) {
var root = _ref.root,
rootMargin = _ref.rootMargin,
threshold = _ref.threshold;
return getRootId(root) + "|" + rootMargin + "|" + threshold;
};
var intersectionCallback = function intersectionCallback(entries) {
entries.forEach(function (entry) {
var target = entry.target,
isIntersecting = entry.isIntersecting;
var cb = callbacks.get(target);
cb == null || cb(isIntersecting);
});
};
var observe = function observe(callback, element, options) {
var id = getId(options);
if (!(id in observers)) {
observers[id] = new IntersectionObserver(intersectionCallback, options);
totalObservers[id] = 0;
}
var observer = observers[id];
observer.observe(element);
callbacks.set(element, callback);
totalObservers[id] = totalObservers[id] + 1;
return function () {
callbacks["delete"](element);
observer.unobserve(element);
totalObservers[id] = totalObservers[id] - 1;
if (totalObservers[id] > 0) return;
observer.disconnect();
callbacks["delete"](callback);
delete observers[id];
delete totalObservers[id];
};
};
export default (function (_ref2) {
var root = _ref2.root,
rootMargin = _ref2.rootMargin,
threshold = _ref2.threshold,
onVisibility = _ref2.onVisibility,
_ref2$defaultVisible = _ref2.defaultVisible,
defaultVisible = _ref2$defaultVisible === void 0 ? false : _ref2$defaultVisible;
var ref = useRef();
var unObserveRef = useRef();
var _useState = useState(defaultVisible),
visible = _useState[0],
setVisible = _useState[1];
var setRef = useCallback(function (element) {
ref.current = element;
unObserveRef.current == null || unObserveRef.current();
unObserveRef.current = null;
if (!element) return;
var options = {
root: root,
rootMargin: rootMargin,
threshold: threshold
};
unObserveRef.current = observe(function (value) {
if (onVisibility) onVisibility(value);
setVisible(value);
}, element, options);
}, [root, rootMargin, threshold, onVisibility]);
useEffect(function () {
return function () {
unObserveRef.current == null || unObserveRef.current();
unObserveRef.current = null;
};
}, []);
return [setRef, ref, visible];
});