@shopify/polaris
Version:
Shopify’s product component library
83 lines (74 loc) • 3.71 kB
JavaScript
import { Rect } from '../../../utilities/geometry.js';
function calculateVerticalPosition(activatorRect, overlayRect, overlayMargins, scrollableContainerRect, containerRect, preferredPosition, fixed) {
var activatorTop = activatorRect.top;
var activatorBottom = activatorTop + activatorRect.height;
var spaceAbove = activatorRect.top;
var spaceBelow = containerRect.height - activatorRect.top - activatorRect.height;
var desiredHeight = overlayRect.height;
var verticalMargins = overlayMargins.activator + overlayMargins.container;
var minimumSpaceToScroll = overlayMargins.container;
var distanceToTopScroll = activatorRect.top - Math.max(scrollableContainerRect.top, 0);
var distanceToBottomScroll = containerRect.top + Math.min(containerRect.height, scrollableContainerRect.top + scrollableContainerRect.height) - (activatorRect.top + activatorRect.height);
var enoughSpaceFromTopScroll = distanceToTopScroll >= minimumSpaceToScroll;
var enoughSpaceFromBottomScroll = distanceToBottomScroll >= minimumSpaceToScroll;
var heightIfBelow = Math.min(spaceBelow, desiredHeight);
var heightIfAbove = Math.min(spaceAbove, desiredHeight);
var containerRectTop = fixed ? 0 : containerRect.top;
var positionIfAbove = {
height: heightIfAbove - verticalMargins,
top: activatorTop + containerRectTop - heightIfAbove,
positioning: 'above'
};
var positionIfBelow = {
height: heightIfBelow - verticalMargins,
top: activatorBottom + containerRectTop,
positioning: 'below'
};
if (preferredPosition === 'above') {
return (enoughSpaceFromTopScroll || distanceToTopScroll >= distanceToBottomScroll && !enoughSpaceFromBottomScroll) && (spaceAbove > desiredHeight || spaceAbove > spaceBelow) ? positionIfAbove : positionIfBelow;
}
if (preferredPosition === 'below') {
return (enoughSpaceFromBottomScroll || distanceToBottomScroll >= distanceToTopScroll && !enoughSpaceFromTopScroll) && (spaceBelow > desiredHeight || spaceBelow > spaceAbove) ? positionIfBelow : positionIfAbove;
}
if (enoughSpaceFromTopScroll && enoughSpaceFromBottomScroll) {
return spaceAbove > spaceBelow ? positionIfAbove : positionIfBelow;
}
return distanceToTopScroll > minimumSpaceToScroll ? positionIfAbove : positionIfBelow;
}
function calculateHorizontalPosition(activatorRect, overlayRect, containerRect, overlayMargins, preferredAlignment) {
var maximum = containerRect.width - overlayRect.width;
if (preferredAlignment === 'left') {
return Math.min(maximum, Math.max(0, activatorRect.left - overlayMargins.horizontal));
} else if (preferredAlignment === 'right') {
var activatorRight = containerRect.width - (activatorRect.left + activatorRect.width);
return Math.min(maximum, Math.max(0, activatorRight - overlayMargins.horizontal));
}
return Math.min(maximum, Math.max(0, activatorRect.center.x - overlayRect.width / 2));
}
function rectIsOutsideOfRect(inner, outer) {
var {
center
} = inner;
return center.y < outer.top || center.y > outer.top + outer.height;
}
function intersectionWithViewport(rect, viewport = windowRect()) {
var top = Math.max(rect.top, 0);
var left = Math.max(rect.left, 0);
var bottom = Math.min(rect.top + rect.height, viewport.height);
var right = Math.min(rect.left + rect.width, viewport.width);
return new Rect({
top,
left,
height: bottom - top,
width: right - left
});
}
function windowRect() {
return new Rect({
top: window.scrollY,
left: window.scrollX,
height: window.innerHeight,
width: document.body.clientWidth
});
}
export { calculateHorizontalPosition, calculateVerticalPosition, intersectionWithViewport, rectIsOutsideOfRect, windowRect };