75 lines
1.7 KiB
JavaScript
75 lines
1.7 KiB
JavaScript
import getBoundaries from '../utils/getBoundaries';
|
|
|
|
function getArea({ width, height }) {
|
|
return width * height;
|
|
}
|
|
|
|
/**
|
|
* Utility used to transform the `auto` placement to the placement with more
|
|
* available space.
|
|
* @method
|
|
* @memberof Popper.Utils
|
|
* @argument {Object} data - The data object generated by update method
|
|
* @argument {Object} options - Modifiers configuration and options
|
|
* @returns {Object} The data object, properly modified
|
|
*/
|
|
export default function computeAutoPlacement(
|
|
placement,
|
|
refRect,
|
|
popper,
|
|
reference,
|
|
boundariesElement,
|
|
padding = 0
|
|
) {
|
|
if (placement.indexOf('auto') === -1) {
|
|
return placement;
|
|
}
|
|
|
|
const boundaries = getBoundaries(
|
|
popper,
|
|
reference,
|
|
padding,
|
|
boundariesElement
|
|
);
|
|
|
|
const rects = {
|
|
top: {
|
|
width: boundaries.width,
|
|
height: refRect.top - boundaries.top,
|
|
},
|
|
right: {
|
|
width: boundaries.right - refRect.right,
|
|
height: boundaries.height,
|
|
},
|
|
bottom: {
|
|
width: boundaries.width,
|
|
height: boundaries.bottom - refRect.bottom,
|
|
},
|
|
left: {
|
|
width: refRect.left - boundaries.left,
|
|
height: boundaries.height,
|
|
},
|
|
};
|
|
|
|
const sortedAreas = Object.keys(rects)
|
|
.map(key => ({
|
|
key,
|
|
...rects[key],
|
|
area: getArea(rects[key]),
|
|
}))
|
|
.sort((a, b) => b.area - a.area);
|
|
|
|
const filteredAreas = sortedAreas.filter(
|
|
({ width, height }) =>
|
|
width >= popper.clientWidth && height >= popper.clientHeight
|
|
);
|
|
|
|
const computedPlacement = filteredAreas.length > 0
|
|
? filteredAreas[0].key
|
|
: sortedAreas[0].key;
|
|
|
|
const variation = placement.split('-')[1];
|
|
|
|
return computedPlacement + (variation ? `-${variation}` : '');
|
|
}
|