@atlaskit/popper
Version:
A wrapper for React Popper for situations which require a bespoke popup where other ADS components are deemed unsuitable
90 lines (89 loc) • 3.25 kB
JavaScript
export function getMaxSizeModifiers({
viewportPadding
}) {
return [{
/**
* Performing DOM measurements in the 'read' phase,
* which is the convention for popper modifiers
*/
name: 'maxSizeData',
enabled: true,
phase: 'read',
fn({
state,
name
}) {
if (!window.visualViewport) {
return;
}
state.modifiersData[name] = {
viewport: {
width: window.visualViewport.width,
height: window.visualViewport.height
}
};
}
}, {
/**
* Applying max size CSS
*/
name: 'maxSize',
enabled: true,
phase: 'beforeWrite',
requiresIfExists: ['offset', 'preventOverflow', 'flip'],
fn({
state
}) {
var _data$viewport, _data$viewport2, _state$modifiersData$, _state$modifiersData, _state$modifiersData$2;
const data = state.modifiersData.maxSizeData;
if (typeof (data === null || data === void 0 ? void 0 : (_data$viewport = data.viewport) === null || _data$viewport === void 0 ? void 0 : _data$viewport.width) !== 'number' || typeof (data === null || data === void 0 ? void 0 : (_data$viewport2 = data.viewport) === null || _data$viewport2 === void 0 ? void 0 : _data$viewport2.height) !== 'number') {
// This shouldn't occur in a real browser but might in non-browser test environments
return;
}
const {
viewport
} = data;
const {
popperOffsets = {
x: 0,
y: 0
}
} = state.modifiersData;
const [basePlacement] = state.placement.split('-');
const placementOffset = (_state$modifiersData$ = (_state$modifiersData = state.modifiersData) === null || _state$modifiersData === void 0 ? void 0 : (_state$modifiersData$2 = _state$modifiersData.offset) === null || _state$modifiersData$2 === void 0 ? void 0 : _state$modifiersData$2[state.placement]) !== null && _state$modifiersData$ !== void 0 ? _state$modifiersData$ : {
x: 0,
y: 0
};
// By default we set these to the entire viewport (minus padding)
// Each placement direction will overwrite one of these
let maxWidth = viewport.width - 2 * viewportPadding;
let maxHeight = viewport.height - 2 * viewportPadding;
if (basePlacement === 'top') {
maxHeight = state.rects.reference.y +
// Viewport-relative position of reference element
placementOffset.y -
// Space between popper and reference
viewportPadding;
}
if (basePlacement === 'bottom') {
maxHeight = viewport.height - popperOffsets.y -
// Viewport-relative position of popper
viewportPadding;
}
if (basePlacement === 'left') {
maxWidth = state.rects.reference.x +
// Viewport-relative position of reference element
placementOffset.x -
// Space between popper and reference
viewportPadding;
}
if (basePlacement === 'right') {
maxWidth = viewport.width - popperOffsets.x -
// Viewport-relative position of popper
viewportPadding;
}
state.styles.popper.maxWidth = `${maxWidth}px`;
state.styles.popper.maxHeight = `${maxHeight}px`;
}
}];
}