@carbon/ibm-products
Version:
Carbon for IBM Products
77 lines (70 loc) • 2.24 kB
JavaScript
/**
* Copyright IBM Corp. 2020, 2025
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
;
var React = require('react');
var scrollableAncestor = require('../utils/scrollableAncestor.js');
const windowExists = typeof window !== `undefined`;
const useTargetScroll = function (target, effect, deps, throttleInterval) {
const scrollPosition = React.useRef({});
const throttleTimeout = React.useRef(null);
const getScrollPosition = () => {
if (!target || !windowExists && target === window) {
return {
scrollX: -1,
scrollY: -1
};
} //
let scrollX, scrollY;
if (target === window) {
scrollX = window.scrollX;
scrollY = window.scrollY;
} else {
scrollX = target.scrollLeft;
scrollY = target.scrollTop;
}
return {
scrollX,
scrollY
};
};
const doGetScrollPosition = () => {
const newVal = {
previous: scrollPosition.current,
current: getScrollPosition()
};
// call effect
effect(newVal);
scrollPosition.current = newVal.current;
throttleTimeout.current = null;
};
React.useLayoutEffect(() => {
const handleScroll = () => {
if (throttleInterval) {
if (throttleTimeout.current === null) {
throttleTimeout.current = setTimeout(doGetScrollPosition, throttleInterval);
}
} else {
doGetScrollPosition();
}
};
if (target) {
target.addEventListener('scroll', handleScroll);
doGetScrollPosition();
}
return () => target && target.removeEventListener('scroll', handleScroll);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, deps);
};
function useNearestScroll(ref, effect, deps) {
let throttle = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
let scrollableTarget = scrollableAncestor.scrollableAncestor(ref.current);
if (scrollableTarget && (document.body === scrollableTarget || scrollableTarget.contains(document.body))) {
scrollableTarget = window;
}
return useTargetScroll(scrollableTarget, effect, deps, throttle);
}
exports.useNearestScroll = useNearestScroll;