package.lib.modifiers.computeStyles.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core Show documentation
Show all versions of core Show documentation
Tooltip and Popover Positioning Engine
import { top, left, right, bottom, end } from "../enums.js";
import getOffsetParent from "../dom-utils/getOffsetParent.js";
import getWindow from "../dom-utils/getWindow.js";
import getDocumentElement from "../dom-utils/getDocumentElement.js";
import getComputedStyle from "../dom-utils/getComputedStyle.js";
import getBasePlacement from "../utils/getBasePlacement.js";
import getVariation from "../utils/getVariation.js";
import { round } from "../utils/math.js"; // eslint-disable-next-line import/no-unused-modules
var unsetSides = {
top: 'auto',
right: 'auto',
bottom: 'auto',
left: 'auto'
}; // Round the offsets to the nearest suitable subpixel based on the DPR.
// Zooming can change the DPR, but it seems to report a value that will
// cleanly divide the values into the appropriate subpixels.
function roundOffsetsByDPR(_ref) {
var x = _ref.x,
y = _ref.y;
var win = window;
var dpr = win.devicePixelRatio || 1;
return {
x: round(x * dpr) / dpr || 0,
y: round(y * dpr) / dpr || 0
};
}
export function mapToStyles(_ref2) {
var _Object$assign2;
var popper = _ref2.popper,
popperRect = _ref2.popperRect,
placement = _ref2.placement,
variation = _ref2.variation,
offsets = _ref2.offsets,
position = _ref2.position,
gpuAcceleration = _ref2.gpuAcceleration,
adaptive = _ref2.adaptive,
roundOffsets = _ref2.roundOffsets,
isFixed = _ref2.isFixed;
var _offsets$x = offsets.x,
x = _offsets$x === void 0 ? 0 : _offsets$x,
_offsets$y = offsets.y,
y = _offsets$y === void 0 ? 0 : _offsets$y;
var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({
x: x,
y: y
}) : {
x: x,
y: y
};
x = _ref3.x;
y = _ref3.y;
var hasX = offsets.hasOwnProperty('x');
var hasY = offsets.hasOwnProperty('y');
var sideX = left;
var sideY = top;
var win = window;
if (adaptive) {
var offsetParent = getOffsetParent(popper);
var heightProp = 'clientHeight';
var widthProp = 'clientWidth';
if (offsetParent === getWindow(popper)) {
offsetParent = getDocumentElement(popper);
if (getComputedStyle(offsetParent).position !== 'static' && position === 'absolute') {
heightProp = 'scrollHeight';
widthProp = 'scrollWidth';
}
} // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it
offsetParent = offsetParent;
if (placement === top || (placement === left || placement === right) && variation === end) {
sideY = bottom;
var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]
offsetParent[heightProp];
y -= offsetY - popperRect.height;
y *= gpuAcceleration ? 1 : -1;
}
if (placement === left || (placement === top || placement === bottom) && variation === end) {
sideX = right;
var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]
offsetParent[widthProp];
x -= offsetX - popperRect.width;
x *= gpuAcceleration ? 1 : -1;
}
}
var commonStyles = Object.assign({
position: position
}, adaptive && unsetSides);
var _ref4 = roundOffsets === true ? roundOffsetsByDPR({
x: x,
y: y
}) : {
x: x,
y: y
};
x = _ref4.x;
y = _ref4.y;
if (gpuAcceleration) {
var _Object$assign;
return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign));
}
return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2));
}
function computeStyles(_ref5) {
var state = _ref5.state,
options = _ref5.options;
var _options$gpuAccelerat = options.gpuAcceleration,
gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,
_options$adaptive = options.adaptive,
adaptive = _options$adaptive === void 0 ? true : _options$adaptive,
_options$roundOffsets = options.roundOffsets,
roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;
if (process.env.NODE_ENV !== "production") {
var transitionProperty = getComputedStyle(state.elements.popper).transitionProperty || '';
if (adaptive && ['transform', 'top', 'right', 'bottom', 'left'].some(function (property) {
return transitionProperty.indexOf(property) >= 0;
})) {
console.warn(['Popper: Detected CSS transitions on at least one of the following', 'CSS properties: "transform", "top", "right", "bottom", "left".', '\n\n', 'Disable the "computeStyles" modifier\'s `adaptive` option to allow', 'for smooth transitions, or remove these properties from the CSS', 'transition declaration on the popper element if only transitioning', 'opacity or background-color for example.', '\n\n', 'We recommend using the popper element as a wrapper around an inner', 'element that can have any CSS property transitioned for animations.'].join(' '));
}
}
var commonStyles = {
placement: getBasePlacement(state.placement),
variation: getVariation(state.placement),
popper: state.elements.popper,
popperRect: state.rects.popper,
gpuAcceleration: gpuAcceleration,
isFixed: state.options.strategy === 'fixed'
};
if (state.modifiersData.popperOffsets != null) {
state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {
offsets: state.modifiersData.popperOffsets,
position: state.options.strategy,
adaptive: adaptive,
roundOffsets: roundOffsets
})));
}
if (state.modifiersData.arrow != null) {
state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {
offsets: state.modifiersData.arrow,
position: 'absolute',
adaptive: false,
roundOffsets: roundOffsets
})));
}
state.attributes.popper = Object.assign({}, state.attributes.popper, {
'data-popper-placement': state.placement
});
} // eslint-disable-next-line import/no-unused-modules
export default {
name: 'computeStyles',
enabled: true,
phase: 'beforeWrite',
fn: computeStyles,
data: {}
};