123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- const getParentElement = element => element.parentElement || element.getRootNode().host || null;
- const getElementRect = element => {
- const rect = element.getBoundingClientRect();
- const scaleX = 'offsetWidth' in element && Math.abs(rect.width) / element.offsetWidth || 1;
- const scaleY = 'offsetHeight' in element && Math.abs(rect.height) / element.offsetHeight || 1;
- return {
- top: rect.top,
- right: rect.left + element.clientWidth * scaleX,
- bottom: rect.top + element.clientHeight * scaleY,
- left: rect.left
- };
- };
- const paddingValueToInt = value => {
- const number = parseInt(value, 10);
- return Number.isNaN(number) ? 0 : number;
- };
- // Follow the steps described in https://www.w3.org/TR/cssom-view-1/#element-scrolling-members,
- // assuming that the scroll option is set to 'nearest'.
- const getScrollDistance = (targetStart, targetEnd, scrollStart, scrollEnd, scrollPaddingStart, scrollPaddingEnd) => {
- if (targetStart < scrollStart && targetEnd > scrollEnd) {
- return 0;
- }
- if (targetStart < scrollStart) {
- return -(scrollStart - targetStart + scrollPaddingStart);
- }
- if (targetEnd > scrollEnd) {
- return targetEnd - targetStart > scrollEnd - scrollStart ? targetStart + scrollPaddingStart - scrollStart : targetEnd - scrollEnd + scrollPaddingEnd;
- }
- return 0;
- };
- const scrollRectIntoView = (root, targetRect) => {
- const document = root.ownerDocument;
- let rect = targetRect;
- let current = root;
- while (current) {
- const isDocumentBody = current === document.body;
- const bounding = isDocumentBody ? {
- top: 0,
- right: window.visualViewport?.width ?? document.documentElement.clientWidth,
- bottom: window.visualViewport?.height ?? document.documentElement.clientHeight,
- left: 0
- } : getElementRect(current);
- const style = getComputedStyle(current);
- const scrollDistanceX = getScrollDistance(rect.left, rect.right, bounding.left, bounding.right, paddingValueToInt(style.scrollPaddingLeft), paddingValueToInt(style.scrollPaddingRight));
- const scrollDistanceY = getScrollDistance(rect.top, rect.bottom, bounding.top, bounding.bottom, paddingValueToInt(style.scrollPaddingTop), paddingValueToInt(style.scrollPaddingBottom));
- if (scrollDistanceX || scrollDistanceY) {
- if (isDocumentBody) {
- document.defaultView?.scrollBy(scrollDistanceX, scrollDistanceY);
- } else {
- const {
- scrollLeft,
- scrollTop
- } = current;
- if (scrollDistanceY) {
- current.scrollTop += scrollDistanceY;
- }
- if (scrollDistanceX) {
- current.scrollLeft += scrollDistanceX;
- }
- const scrolledLeft = current.scrollLeft - scrollLeft;
- const scrolledTop = current.scrollTop - scrollTop;
- rect = {
- left: rect.left - scrolledLeft,
- top: rect.top - scrolledTop,
- right: rect.right - scrolledLeft,
- bottom: rect.bottom - scrolledTop
- };
- }
- }
- current = isDocumentBody || style.position === 'fixed' ? null : getParentElement(current);
- }
- };
- export default scrollRectIntoView;
- //# sourceMappingURL=scrollRectIntoView.js.map
|