|
|
import getOffsetParent from '../utils/getOffsetParent'; |
|
|
import getBoundaries from '../utils/getBoundaries'; |
|
|
import getSupportedPropertyName from '../utils/getSupportedPropertyName'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export default function preventOverflow(data, options) { |
|
|
let boundariesElement = |
|
|
options.boundariesElement || getOffsetParent(data.instance.popper); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (data.instance.reference === boundariesElement) { |
|
|
boundariesElement = getOffsetParent(boundariesElement); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const transformProp = getSupportedPropertyName('transform'); |
|
|
const popperStyles = data.instance.popper.style; |
|
|
const { top, left, [transformProp]: transform } = popperStyles; |
|
|
popperStyles.top = ''; |
|
|
popperStyles.left = ''; |
|
|
popperStyles[transformProp] = ''; |
|
|
|
|
|
const boundaries = getBoundaries( |
|
|
data.instance.popper, |
|
|
data.instance.reference, |
|
|
options.padding, |
|
|
boundariesElement, |
|
|
data.positionFixed |
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
popperStyles.top = top; |
|
|
popperStyles.left = left; |
|
|
popperStyles[transformProp] = transform; |
|
|
|
|
|
options.boundaries = boundaries; |
|
|
|
|
|
const order = options.priority; |
|
|
let popper = data.offsets.popper; |
|
|
|
|
|
const check = { |
|
|
primary(placement) { |
|
|
let value = popper[placement]; |
|
|
if ( |
|
|
popper[placement] < boundaries[placement] && |
|
|
!options.escapeWithReference |
|
|
) { |
|
|
value = Math.max(popper[placement], boundaries[placement]); |
|
|
} |
|
|
return { [placement]: value }; |
|
|
}, |
|
|
secondary(placement) { |
|
|
const mainSide = placement === 'right' ? 'left' : 'top'; |
|
|
let value = popper[mainSide]; |
|
|
if ( |
|
|
popper[placement] > boundaries[placement] && |
|
|
!options.escapeWithReference |
|
|
) { |
|
|
value = Math.min( |
|
|
popper[mainSide], |
|
|
boundaries[placement] - |
|
|
(placement === 'right' ? popper.width : popper.height) |
|
|
); |
|
|
} |
|
|
return { [mainSide]: value }; |
|
|
}, |
|
|
}; |
|
|
|
|
|
order.forEach(placement => { |
|
|
const side = |
|
|
['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary'; |
|
|
popper = { ...popper, ...check[side](placement) }; |
|
|
}); |
|
|
|
|
|
data.offsets.popper = popper; |
|
|
|
|
|
return data; |
|
|
} |
|
|
|