UNPKG

@shopify/polaris

Version:

Shopify’s product component library

83 lines (74 loc) 3.71 kB
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 };