@modern-kit/react
Version:
72 lines (68 loc) • 2.62 kB
JavaScript
import { useRef, useCallback } from 'react';
import { isWindow } from '@modern-kit/utils';
const getAlignPosition = (containerDimension, targetDimension, align) => {
if (align === "start") {
return 0;
}
if (align === "center") {
return -containerDimension / 2 + targetDimension / 2;
}
return -containerDimension + targetDimension;
};
const calculateTargetPositionFromWindow = (targetRect, options) => ({
top: targetRect.top + window.scrollY + options.offsetY + getAlignPosition(window.innerHeight, targetRect.height, options.alignY),
left: targetRect.left + window.scrollX + options.offsetX + getAlignPosition(window.innerWidth, targetRect.width, options.alignX)
});
const calculateTargetPositionFromElement = (targetRect, container, options) => {
const containerRect = container.getBoundingClientRect();
return {
top: targetRect.top - containerRect.top + container.scrollTop + options.offsetY + getAlignPosition(containerRect.height, targetRect.height, options.alignY),
left: targetRect.left - containerRect.left + container.scrollLeft + options.offsetX + getAlignPosition(containerRect.width, targetRect.width, options.alignX)
};
};
const getRelativePosition = (container, target, scrollToOptions) => {
const targetRect = target.getBoundingClientRect();
const options = {
offsetX: scrollToOptions?.offsetX ?? 0,
offsetY: scrollToOptions?.offsetY ?? 0,
alignY: scrollToOptions?.alignY ?? "start",
alignX: scrollToOptions?.alignX ?? "start"
};
return isWindow(container) ? calculateTargetPositionFromWindow(targetRect, options) : calculateTargetPositionFromElement(targetRect, container, options);
};
function useScrollTo() {
const containerRef = useRef(null);
const scrollToPosition = useCallback(
(scrollToOptions = {}) => {
const { left = 0, top = 0, behavior = "auto" } = scrollToOptions;
const scrollElement = containerRef.current ?? window;
scrollElement.scrollTo({
left,
top,
behavior
});
},
[]
);
const scrollToElement = useCallback(
(target, scrollToElementOptions = {}) => {
if (!target) return;
const scrollElement = containerRef.current ?? window;
const { behavior = "auto" } = scrollToElementOptions;
const { left, top } = getRelativePosition(
scrollElement,
target,
scrollToElementOptions
);
scrollElement.scrollTo({
top,
left,
behavior
});
},
[]
);
return { containerRef, scrollToPosition, scrollToElement };
}
export { useScrollTo };
//# sourceMappingURL=index.mjs.map