@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
64 lines • 2.5 kB
JavaScript
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { getLogicalBoundingClientRect } from '@awsui/component-toolkit/internal';
import { getOverflowParents } from '../internal/utils/scrollable-containers';
/**
* @param containerRef ref to surrounding container with sticky element
* @param stickyRef ref to sticky element scrolled inside of containerRef
* @param containerOffset offset between header and container
* originating borders or paddings
*/
export default function stickyScrolling(containerRef, stickyRef) {
const scrollToTop = () => {
if (!containerRef.current || !stickyRef.current) {
return;
}
const scrollingOffset = calculateScrollingOffset(containerRef.current, stickyRef.current);
if (scrollingOffset > 0) {
scrollUpBy(scrollingOffset, containerRef.current);
}
};
const scrollToItem = (item) => {
if (!item || !containerRef.current || !stickyRef.current) {
return;
}
const stickyBottom = getLogicalBoundingClientRect(stickyRef.current).insetBlockEnd;
const scrollingOffset = stickyBottom - getLogicalBoundingClientRect(item).insetBlockStart;
if (scrollingOffset > 0) {
scrollUpBy(scrollingOffset, containerRef.current);
}
};
return {
scrollToTop,
scrollToItem,
};
}
/**
* Calculates the scrolling offset between container and
* sticky element with container offset caused by border
* or padding
* @param container
* @param sticky element inside of container
* @param containerOffset caused by borders or paddings
*/
export function calculateScrollingOffset(container, sticky) {
const stickyRect = getLogicalBoundingClientRect(sticky);
const containerRect = getLogicalBoundingClientRect(container);
return stickyRect.insetBlockStart - containerRect.insetBlockStart;
}
/**
* Scrolls suitable parent of container up by amount of pixels
* @param amount pixels to be scrolled up
* @param container used to determine next parent element for scrolling
*/
export function scrollUpBy(amount, container) {
const parent = getOverflowParents(container);
if (parent.length) {
// Take next overflow parent in stack
parent[0].scrollTop -= amount;
}
else {
window.scrollTo({ top: window.pageYOffset - amount });
}
}
//# sourceMappingURL=sticky-scrolling.js.map