@szhsin/react-menu
Version:
React component for building accessible menu, dropdown, submenu, context menu, and more
75 lines (71 loc) • 2.23 kB
JavaScript
;
var placeLeftorRight = require('./placeLeftorRight.cjs');
var placeToporBottom = require('./placeToporBottom.cjs');
const positionMenu = ({
arrow,
align,
direction,
gap,
shift,
position,
anchorRect,
arrowRef,
positionHelpers
}) => {
const {
menuRect,
containerRect
} = positionHelpers;
const isHorizontal = direction === 'left' || direction === 'right';
let horizontalOffset = isHorizontal ? gap : shift;
let verticalOffset = isHorizontal ? shift : gap;
if (arrow) {
const arrowElt = arrowRef.current;
if (isHorizontal) {
horizontalOffset += arrowElt.offsetWidth;
} else {
verticalOffset += arrowElt.offsetHeight;
}
}
const placeLeftX = anchorRect.left - containerRect.left - menuRect.width - horizontalOffset;
const placeRightX = anchorRect.right - containerRect.left + horizontalOffset;
const placeTopY = anchorRect.top - containerRect.top - menuRect.height - verticalOffset;
const placeBottomY = anchorRect.bottom - containerRect.top + verticalOffset;
let placeToporBottomX, placeLeftorRightY;
if (align === 'end') {
placeToporBottomX = anchorRect.right - containerRect.left - menuRect.width;
placeLeftorRightY = anchorRect.bottom - containerRect.top - menuRect.height;
} else if (align === 'center') {
placeToporBottomX = anchorRect.left - containerRect.left - (menuRect.width - anchorRect.width) / 2;
placeLeftorRightY = anchorRect.top - containerRect.top - (menuRect.height - anchorRect.height) / 2;
} else {
placeToporBottomX = anchorRect.left - containerRect.left;
placeLeftorRightY = anchorRect.top - containerRect.top;
}
placeToporBottomX += horizontalOffset;
placeLeftorRightY += verticalOffset;
const options = {
...positionHelpers,
anchorRect,
placeLeftX,
placeRightX,
placeLeftorRightY,
placeTopY,
placeBottomY,
placeToporBottomX,
arrowRef,
arrow,
direction,
position
};
switch (direction) {
case 'left':
case 'right':
return placeLeftorRight.placeLeftorRight(options);
case 'top':
case 'bottom':
default:
return placeToporBottom.placeToporBottom(options);
}
};
exports.positionMenu = positionMenu;