@nex-ui/react
Version:
🎉 A beautiful, modern, and reliable React component library.
49 lines (46 loc) • 2.32 kB
JavaScript
import { clamp } from '@nex-ui/utils';
import { detectOverflow } from '../detectOverflow.mjs';
import { getSideAxis, getAlignment, getOppositeAxis, getAxisLength } from '../utils.mjs';
const shift = ()=>{
return {
name: 'shift',
fn: (state)=>{
const { placement, rects } = state;
const overflow = detectOverflow(state);
const mainAxis = getSideAxis(placement);
const alignment = getAlignment(placement);
const crossAxis = getOppositeAxis(mainAxis);
const crossAxisLength = getAxisLength(crossAxis);
const minSide = mainAxis === 'y' ? 'left' : 'top';
const maxSide = mainAxis === 'y' ? 'right' : 'bottom';
const mainAxisCoord = rects.popper[mainAxis];
let positiveMaxOverflow;
let negativeMaxOverflow;
switch(alignment){
case 'start':
positiveMaxOverflow = rects.reference[crossAxisLength];
negativeMaxOverflow = rects.popper[crossAxisLength];
break;
case 'end':
positiveMaxOverflow = rects.popper[crossAxisLength];
negativeMaxOverflow = rects.reference[crossAxisLength];
break;
default:
positiveMaxOverflow = rects.reference[crossAxisLength] + rects.reference[crossAxis] - rects.popper[crossAxis];
negativeMaxOverflow = positiveMaxOverflow;
}
// When moving in the positive cross-axis direction, offset is determined by the minimum boundary
// When moving in the negative cross-axis direction, offset is determined by the maximum boundary
const crossAxisCoord = clamp(rects.popper[crossAxis], rects.popper[crossAxis] + Math.min(overflow[minSide], positiveMaxOverflow), rects.popper[crossAxis] - Math.min(overflow[maxSide], negativeMaxOverflow));
return {
[mainAxis]: mainAxisCoord,
[crossAxis]: crossAxisCoord,
data: {
[mainAxis]: mainAxisCoord - rects.popper[mainAxis],
[crossAxis]: crossAxisCoord - rects.popper[crossAxis]
}
};
}
};
};
export { shift };