@awsui/components-react
Version:
AWS UI is a collection of [React](https://reactjs.org/) components that help create intuitive, responsive, and accessible user experiences for web applications. It is developed by Amazon Web Services (AWS). This work is available under the terms of the [A
127 lines (126 loc) • 6.18 kB
JavaScript
import { getOverflowParentDimensions, getOverflowParents } from '../../utils/scrollable-containers';
var AVAILABLE_SPACE_RESERVE = 50;
var getClosestParentDimensions = function (element) {
var parents = getOverflowParents(element).map(function (el) {
var _a = el.getBoundingClientRect(), height = _a.height, width = _a.width, top = _a.top, left = _a.left;
return {
height: height,
width: width,
top: top,
left: left
};
});
return parents.shift();
};
export var focusPreservingScroll = function (element) {
var savedScrollPositions = saveParentScrollPositions(element);
element.focus();
restoreParentScrollPositions(savedScrollPositions);
};
var saveParentScrollPositions = function (element) {
return getOverflowParents(element).map(function (el) { return ({ scrollParent: el, prevScrollTop: el.scrollTop }); });
};
export var getAvailableSpace = function (trigger, dropdown) {
var overflowParents = getOverflowParentDimensions(dropdown);
var _a = trigger.getBoundingClientRect(), triggerBottom = _a.bottom, triggerLeft = _a.left, triggerRight = _a.right;
return overflowParents.reduce(function (_a, overflowParent) {
var above = _a.above, below = _a.below, left = _a.left, right = _a.right;
var offsetTop = triggerBottom - overflowParent.top;
var currentAbove = offsetTop - trigger.offsetHeight - AVAILABLE_SPACE_RESERVE;
var currentBelow = overflowParent.height - offsetTop - AVAILABLE_SPACE_RESERVE;
var currentLeft = triggerRight - overflowParent.left - AVAILABLE_SPACE_RESERVE;
var currentRight = overflowParent.left + overflowParent.width - triggerLeft - AVAILABLE_SPACE_RESERVE;
return {
above: Math.min(above, currentAbove),
below: Math.min(below, currentBelow),
left: Math.min(left, currentLeft),
right: Math.min(right, currentRight)
};
}, { above: Number.MAX_VALUE, below: Number.MAX_VALUE, left: Number.MAX_VALUE, right: Number.MAX_VALUE });
};
export var getInteriorAvailableSpace = function (trigger, dropdown) {
var overflowParents = getOverflowParentDimensions(dropdown, true);
var _a = trigger.getBoundingClientRect(), triggerBottom = _a.bottom, triggerTop = _a.top, triggerLeft = _a.left, triggerRight = _a.right;
return overflowParents.reduce(function (_a, overflowParent) {
var above = _a.above, below = _a.below, left = _a.left, right = _a.right;
var currentAbove = triggerBottom - overflowParent.top - trigger.offsetHeight - AVAILABLE_SPACE_RESERVE;
var currentBelow = overflowParent.height - triggerTop + overflowParent.top - AVAILABLE_SPACE_RESERVE;
var currentLeft = triggerLeft - overflowParent.left - AVAILABLE_SPACE_RESERVE;
var currentRight = overflowParent.left + overflowParent.width - triggerRight - AVAILABLE_SPACE_RESERVE;
return {
above: Math.min(above, currentAbove),
below: Math.min(below, currentBelow),
left: Math.min(left, currentLeft),
right: Math.min(right, currentRight)
};
}, { above: Number.MAX_VALUE, below: Number.MAX_VALUE, left: Number.MAX_VALUE, right: Number.MAX_VALUE });
};
export var getDropdownPosition = function (trigger, dropdown, prefersDownDirection) {
if (prefersDownDirection === void 0) { prefersDownDirection = false; }
var availableSpace = getAvailableSpace(trigger, dropdown);
var triggerWidth = trigger.getBoundingClientRect().width;
var requiredWidth = dropdown.getBoundingClientRect().width;
var idealWidth = Math.max(requiredWidth, triggerWidth);
var dropLeft;
var width = idealWidth;
if (idealWidth <= availableSpace.right) {
dropLeft = false;
}
else if (idealWidth <= availableSpace.left) {
dropLeft = true;
}
else {
dropLeft = availableSpace.left > availableSpace.right;
width = Math.max(availableSpace.left, availableSpace.right, triggerWidth);
}
var dropUp = availableSpace.below < dropdown.offsetHeight && availableSpace.above > availableSpace.below;
if (prefersDownDirection && dropUp && availableSpace.above < dropdown.offsetHeight) {
dropUp = false;
}
return {
dropUp: dropUp,
dropLeft: dropLeft,
height: dropUp ? availableSpace.above + "px" : availableSpace.below + "px",
width: width + "px"
};
};
export var getInteriorDropdownPosition = function (trigger, dropdown) {
var availableSpace = getInteriorAvailableSpace(trigger, dropdown);
var _a = trigger.getBoundingClientRect(), triggerBottom = _a.bottom, triggerTop = _a.top, triggerWidth = _a.width;
var _b = getClosestParentDimensions(trigger), parentDropdownTop = _b.top, parentDropdownHeight = _b.height;
var dropLeft;
var width = dropdown.getBoundingClientRect().width;
var top = triggerTop - parentDropdownTop;
if (width <= availableSpace.right) {
dropLeft = false;
}
else if (width <= availableSpace.left) {
dropLeft = true;
}
else {
dropLeft = availableSpace.left > availableSpace.right;
width = Math.max(availableSpace.left, availableSpace.right);
}
var left = dropLeft ? 0 - width : triggerWidth;
var dropUp = availableSpace.below < dropdown.offsetHeight && availableSpace.above > availableSpace.below;
var bottom = dropUp ? parentDropdownTop + parentDropdownHeight - triggerBottom : 0;
return {
dropUp: dropUp,
dropLeft: dropLeft,
height: dropUp ? availableSpace.above + "px" : availableSpace.below + "px",
width: width + "px",
top: top + "px",
bottom: bottom + "px",
left: left + "px"
};
};
var restoreParentScrollPositions = function (savedScrollPositions) {
window.setTimeout(function () {
savedScrollPositions.forEach(function (_a) {
var scrollParent = _a.scrollParent, prevScrollTop = _a.prevScrollTop;
if (scrollParent.scrollTop !== prevScrollTop) {
scrollParent.scrollTop = prevScrollTop;
}
});
}, 0);
};