@awsui/components-react
Version:
On July 19th, 2022, we launched [Cloudscape Design System](https://cloudscape.design). Cloudscape is an evolution of AWS-UI. It consists of user interface guidelines, front-end components, design resources, and development tools for building intuitive, en
95 lines • 3.71 kB
JavaScript
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { KeyboardCode } from '@dnd-kit/core';
import { canUseDOM, subtract as getCoordinatesDelta } from '@dnd-kit/utilities';
function isDocumentScrollingElement(element) {
if (!canUseDOM || !element) {
return false;
}
return element === document.scrollingElement;
}
function getScrollPosition(scrollingContainer) {
const minScroll = {
x: 0,
y: 0,
};
const dimensions = isDocumentScrollingElement(scrollingContainer)
? {
height: window.innerHeight,
width: window.innerWidth,
}
: {
height: scrollingContainer.clientHeight,
width: scrollingContainer.clientWidth,
};
const maxScroll = {
x: scrollingContainer.scrollWidth - dimensions.width,
y: scrollingContainer.scrollHeight - dimensions.height,
};
const isTop = scrollingContainer.scrollTop <= minScroll.y;
const isLeft = scrollingContainer.scrollLeft <= minScroll.x;
const isBottom = scrollingContainer.scrollTop >= maxScroll.y;
const isRight = scrollingContainer.scrollLeft >= maxScroll.x;
return {
isTop,
isLeft,
isBottom,
isRight,
maxScroll,
minScroll,
};
}
function getScrollElementRect(element) {
if (element === document.scrollingElement) {
const { innerWidth, innerHeight } = window;
return {
top: 0,
left: 0,
right: innerWidth,
bottom: innerHeight,
width: innerWidth,
height: innerHeight,
};
}
const { top, left, right, bottom } = element.getBoundingClientRect();
return {
top,
left,
right,
bottom,
width: element.clientWidth,
height: element.clientHeight,
};
}
export function applyScroll({ currentCoordinates, direction, newCoordinates, scrollableAncestors, }) {
for (const scrollContainer of scrollableAncestors) {
const coordinatesDelta = getCoordinatesDelta(newCoordinates, currentCoordinates);
const { isTop, isBottom, maxScroll, minScroll } = getScrollPosition(scrollContainer);
const scrollElementRect = getScrollElementRect(scrollContainer);
const clampedCoordinates = {
y: Math.min(direction === KeyboardCode.Down
? scrollElementRect.bottom - scrollElementRect.height / 2
: scrollElementRect.bottom, Math.max(direction === KeyboardCode.Down
? scrollElementRect.top
: scrollElementRect.top + scrollElementRect.height / 2, newCoordinates.y)),
};
const canScrollY = (direction === KeyboardCode.Down && !isBottom) || (direction === KeyboardCode.Up && !isTop);
if (canScrollY && clampedCoordinates.y !== newCoordinates.y) {
const newScrollCoordinates = scrollContainer.scrollTop + coordinatesDelta.y;
const canScrollToNewCoordinates = (direction === KeyboardCode.Down && newScrollCoordinates <= maxScroll.y) ||
(direction === KeyboardCode.Up && newScrollCoordinates >= minScroll.y);
if (canScrollToNewCoordinates) {
// We don't need to update coordinates, the scroll adjustment alone will trigger
// logic to auto-detect the new container we are over
scrollContainer.scrollTo({
top: newScrollCoordinates,
behavior: 'smooth',
});
return true;
}
break;
}
}
return false;
}
//# sourceMappingURL=scroll.js.map