@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
98 lines • 4.28 kB
JavaScript
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { findUpUntil } from '@awsui/component-toolkit/dom';
export const getOverflowParents = (element) => {
const parents = [];
let node = element;
while ((node = node.parentElement) && node !== element.ownerDocument.body) {
if (getComputedStyle(node).overflow !== 'visible') {
parents.push(node);
}
}
return parents;
};
export const getOverflowParentDimensions = ({ element, excludeClosestParent = false, expandToViewport = false, canExpandOutsideViewport = false, }) => {
var _a, _b, _c, _d, _e;
const parents = expandToViewport
? []
: getOverflowParents(element).map(el => {
const { height, width, top, left } = el.getBoundingClientRect();
return {
// Treat the whole scrollable area as the available height
// if we're allowed to expand past the viewport.
blockSize: canExpandOutsideViewport ? el.scrollHeight : height,
inlineSize: width,
insetBlockStart: top,
insetInlineStart: left,
};
});
if (canExpandOutsideViewport && !expandToViewport) {
const document = element.ownerDocument;
const documentDimensions = document.documentElement.getBoundingClientRect();
parents.push({
inlineSize: Math.max(documentDimensions.width, document.documentElement.clientWidth),
blockSize: Math.max(documentDimensions.height, document.documentElement.clientHeight),
insetBlockStart: documentDimensions.top,
insetInlineStart: documentDimensions.left,
});
}
else {
const owningWindow = (_a = element.ownerDocument.defaultView) !== null && _a !== void 0 ? _a : window;
parents.push({
blockSize: (_c = (_b = owningWindow.visualViewport) === null || _b === void 0 ? void 0 : _b.height) !== null && _c !== void 0 ? _c : owningWindow.innerHeight,
inlineSize: (_e = (_d = owningWindow.visualViewport) === null || _d === void 0 ? void 0 : _d.width) !== null && _e !== void 0 ? _e : owningWindow.innerWidth,
insetBlockStart: 0,
insetInlineStart: 0,
});
}
if (excludeClosestParent && !expandToViewport) {
parents.shift();
}
return parents;
};
/**
* Calls `scrollIntoView` on the provided element with sensible defaults. If
* the element does not exist or does not support the `scrollIntoView`
* method, it will do nothing. This wrapper is created to support environments
* where the native function is not available like JSDom (feature request:
* https://github.com/jsdom/jsdom/issues/1422).
*
* @param element to be scrolled into view
* @param options native options for `scrollIntoView`
*/
export function scrollElementIntoView(element, options = { block: 'nearest', inline: 'nearest' }) {
var _a;
(_a = element === null || element === void 0 ? void 0 : element.scrollIntoView) === null || _a === void 0 ? void 0 : _a.call(element, options);
}
export function calculateScroll({ insetBlockStart, blockSize }) {
if (insetBlockStart < 0) {
return insetBlockStart;
}
else if (insetBlockStart + blockSize > window.innerHeight) {
if (blockSize > window.innerHeight) {
return insetBlockStart;
}
else {
return insetBlockStart + blockSize - window.innerHeight;
}
}
return 0;
}
/**
* For elements with fixed position, the browser's native scrollIntoView API doesn't work,
* so we need to manually scroll to the element's position.
* Supports only vertical scrolling.
*/
export function scrollRectangleIntoView(box, scrollableParent) {
const scrollAmount = calculateScroll(box);
if (scrollAmount) {
(scrollableParent || window).scrollBy(0, scrollAmount);
}
}
export function getFirstScrollableParent(element) {
return (findUpUntil(element, el => {
const overflows = el.scrollHeight > el.clientHeight;
return overflows && ['scroll', 'auto'].includes(getComputedStyle(el).overflowY);
}) || undefined);
}
//# sourceMappingURL=scrollable-containers.js.map