UNPKG

5.71 kBJavaScriptView Raw
1import { top, left, right, bottom, end } from "../enums.js";
2import getOffsetParent from "../dom-utils/getOffsetParent.js";
3import getWindow from "../dom-utils/getWindow.js";
4import getDocumentElement from "../dom-utils/getDocumentElement.js";
5import getComputedStyle from "../dom-utils/getComputedStyle.js";
6import getBasePlacement from "../utils/getBasePlacement.js";
7import getVariation from "../utils/getVariation.js";
8import { round } from "../utils/math.js"; // eslint-disable-next-line import/no-unused-modules
9
10var unsetSides = {
11 top: 'auto',
12 right: 'auto',
13 bottom: 'auto',
14 left: 'auto'
15}; // Round the offsets to the nearest suitable subpixel based on the DPR.
16// Zooming can change the DPR, but it seems to report a value that will
17// cleanly divide the values into the appropriate subpixels.
18
19function roundOffsetsByDPR(_ref, win) {
20 var x = _ref.x,
21 y = _ref.y;
22 var dpr = win.devicePixelRatio || 1;
23 return {
24 x: round(x * dpr) / dpr || 0,
25 y: round(y * dpr) / dpr || 0
26 };
27}
28
29export function mapToStyles(_ref2) {
30 var _Object$assign2;
31
32 var popper = _ref2.popper,
33 popperRect = _ref2.popperRect,
34 placement = _ref2.placement,
35 variation = _ref2.variation,
36 offsets = _ref2.offsets,
37 position = _ref2.position,
38 gpuAcceleration = _ref2.gpuAcceleration,
39 adaptive = _ref2.adaptive,
40 roundOffsets = _ref2.roundOffsets,
41 isFixed = _ref2.isFixed;
42 var _offsets$x = offsets.x,
43 x = _offsets$x === void 0 ? 0 : _offsets$x,
44 _offsets$y = offsets.y,
45 y = _offsets$y === void 0 ? 0 : _offsets$y;
46
47 var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({
48 x: x,
49 y: y
50 }) : {
51 x: x,
52 y: y
53 };
54
55 x = _ref3.x;
56 y = _ref3.y;
57 var hasX = offsets.hasOwnProperty('x');
58 var hasY = offsets.hasOwnProperty('y');
59 var sideX = left;
60 var sideY = top;
61 var win = window;
62
63 if (adaptive) {
64 var offsetParent = getOffsetParent(popper);
65 var heightProp = 'clientHeight';
66 var widthProp = 'clientWidth';
67
68 if (offsetParent === getWindow(popper)) {
69 offsetParent = getDocumentElement(popper);
70
71 if (getComputedStyle(offsetParent).position !== 'static' && position === 'absolute') {
72 heightProp = 'scrollHeight';
73 widthProp = 'scrollWidth';
74 }
75 } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it
76
77
78 offsetParent = offsetParent;
79
80 if (placement === top || (placement === left || placement === right) && variation === end) {
81 sideY = bottom;
82 var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]
83 offsetParent[heightProp];
84 y -= offsetY - popperRect.height;
85 y *= gpuAcceleration ? 1 : -1;
86 }
87
88 if (placement === left || (placement === top || placement === bottom) && variation === end) {
89 sideX = right;
90 var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]
91 offsetParent[widthProp];
92 x -= offsetX - popperRect.width;
93 x *= gpuAcceleration ? 1 : -1;
94 }
95 }
96
97 var commonStyles = Object.assign({
98 position: position
99 }, adaptive && unsetSides);
100
101 var _ref4 = roundOffsets === true ? roundOffsetsByDPR({
102 x: x,
103 y: y
104 }, getWindow(popper)) : {
105 x: x,
106 y: y
107 };
108
109 x = _ref4.x;
110 y = _ref4.y;
111
112 if (gpuAcceleration) {
113 var _Object$assign;
114
115 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));
116 }
117
118 return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2));
119}
120
121function computeStyles(_ref5) {
122 var state = _ref5.state,
123 options = _ref5.options;
124 var _options$gpuAccelerat = options.gpuAcceleration,
125 gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,
126 _options$adaptive = options.adaptive,
127 adaptive = _options$adaptive === void 0 ? true : _options$adaptive,
128 _options$roundOffsets = options.roundOffsets,
129 roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;
130 var commonStyles = {
131 placement: getBasePlacement(state.placement),
132 variation: getVariation(state.placement),
133 popper: state.elements.popper,
134 popperRect: state.rects.popper,
135 gpuAcceleration: gpuAcceleration,
136 isFixed: state.options.strategy === 'fixed'
137 };
138
139 if (state.modifiersData.popperOffsets != null) {
140 state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {
141 offsets: state.modifiersData.popperOffsets,
142 position: state.options.strategy,
143 adaptive: adaptive,
144 roundOffsets: roundOffsets
145 })));
146 }
147
148 if (state.modifiersData.arrow != null) {
149 state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {
150 offsets: state.modifiersData.arrow,
151 position: 'absolute',
152 adaptive: false,
153 roundOffsets: roundOffsets
154 })));
155 }
156
157 state.attributes.popper = Object.assign({}, state.attributes.popper, {
158 'data-popper-placement': state.placement
159 });
160} // eslint-disable-next-line import/no-unused-modules
161
162
163export default {
164 name: 'computeStyles',
165 enabled: true,
166 phase: 'beforeWrite',
167 fn: computeStyles,
168 data: {}
169};
\No newline at end of file