UNPKG

61.4 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5var top = 'top';
6var bottom = 'bottom';
7var right = 'right';
8var left = 'left';
9var auto = 'auto';
10var basePlacements = [top, bottom, right, left];
11var start = 'start';
12var end = 'end';
13var clippingParents = 'clippingParents';
14var viewport = 'viewport';
15var popper = 'popper';
16var reference = 'reference';
17var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) {
18 return acc.concat([placement + "-" + start, placement + "-" + end]);
19}, []);
20var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) {
21 return acc.concat([placement, placement + "-" + start, placement + "-" + end]);
22}, []); // modifiers that need to read the DOM
23
24var beforeRead = 'beforeRead';
25var read = 'read';
26var afterRead = 'afterRead'; // pure-logic modifiers
27
28var beforeMain = 'beforeMain';
29var main = 'main';
30var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)
31
32var beforeWrite = 'beforeWrite';
33var write = 'write';
34var afterWrite = 'afterWrite';
35var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];
36
37function getBasePlacement(placement) {
38 return placement.split('-')[0];
39}
40
41function getBoundingClientRect(element) {
42 var rect = element.getBoundingClientRect();
43 return {
44 width: rect.width,
45 height: rect.height,
46 top: rect.top,
47 right: rect.right,
48 bottom: rect.bottom,
49 left: rect.left,
50 x: rect.left,
51 y: rect.top
52 };
53}
54
55// means it doesn't take into account transforms.
56
57function getLayoutRect(element) {
58 var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed.
59 // Fixes https://github.com/popperjs/popper-core/issues/1223
60
61 var width = element.offsetWidth;
62 var height = element.offsetHeight;
63
64 if (Math.abs(clientRect.width - width) <= 0.5) {
65 width = clientRect.width;
66 }
67
68 if (Math.abs(clientRect.height - height) <= 0.5) {
69 height = clientRect.height;
70 }
71
72 return {
73 x: element.offsetLeft,
74 y: element.offsetTop,
75 width: width,
76 height: height
77 };
78}
79
80/*:: import type { Window } from '../types'; */
81
82/*:: declare function getWindow(node: Node | Window): Window; */
83function getWindow(node) {
84 if (node == null) {
85 return window;
86 }
87
88 if (node.toString() !== '[object Window]') {
89 var ownerDocument = node.ownerDocument;
90 return ownerDocument ? ownerDocument.defaultView || window : window;
91 }
92
93 return node;
94}
95
96/*:: declare function isElement(node: mixed): boolean %checks(node instanceof
97 Element); */
98
99function isElement(node) {
100 var OwnElement = getWindow(node).Element;
101 return node instanceof OwnElement || node instanceof Element;
102}
103/*:: declare function isHTMLElement(node: mixed): boolean %checks(node instanceof
104 HTMLElement); */
105
106
107function isHTMLElement(node) {
108 var OwnElement = getWindow(node).HTMLElement;
109 return node instanceof OwnElement || node instanceof HTMLElement;
110}
111/*:: declare function isShadowRoot(node: mixed): boolean %checks(node instanceof
112 ShadowRoot); */
113
114
115function isShadowRoot(node) {
116 // IE 11 has no ShadowRoot
117 if (typeof ShadowRoot === 'undefined') {
118 return false;
119 }
120
121 var OwnElement = getWindow(node).ShadowRoot;
122 return node instanceof OwnElement || node instanceof ShadowRoot;
123}
124
125function contains(parent, child) {
126 var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method
127
128 if (parent.contains(child)) {
129 return true;
130 } // then fallback to custom implementation with Shadow DOM support
131 else if (rootNode && isShadowRoot(rootNode)) {
132 var next = child;
133
134 do {
135 if (next && parent.isSameNode(next)) {
136 return true;
137 } // $FlowFixMe[prop-missing]: need a better way to handle this...
138
139
140 next = next.parentNode || next.host;
141 } while (next);
142 } // Give up, the result is false
143
144
145 return false;
146}
147
148function getNodeName(element) {
149 return element ? (element.nodeName || '').toLowerCase() : null;
150}
151
152function getComputedStyle(element) {
153 return getWindow(element).getComputedStyle(element);
154}
155
156function isTableElement(element) {
157 return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;
158}
159
160function getDocumentElement(element) {
161 // $FlowFixMe[incompatible-return]: assume body is always available
162 return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing]
163 element.document) || window.document).documentElement;
164}
165
166function getParentNode(element) {
167 if (getNodeName(element) === 'html') {
168 return element;
169 }
170
171 return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle
172 // $FlowFixMe[incompatible-return]
173 // $FlowFixMe[prop-missing]
174 element.assignedSlot || // step into the shadow DOM of the parent of a slotted node
175 element.parentNode || ( // DOM Element detected
176 isShadowRoot(element) ? element.host : null) || // ShadowRoot detected
177 // $FlowFixMe[incompatible-call]: HTMLElement is a Node
178 getDocumentElement(element) // fallback
179
180 );
181}
182
183function getTrueOffsetParent(element) {
184 if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837
185 getComputedStyle(element).position === 'fixed') {
186 return null;
187 }
188
189 return element.offsetParent;
190} // `.offsetParent` reports `null` for fixed elements, while absolute elements
191// return the containing block
192
193
194function getContainingBlock(element) {
195 var isFirefox = navigator.userAgent.toLowerCase().includes('firefox');
196 var currentNode = getParentNode(element);
197
198 while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {
199 var css = getComputedStyle(currentNode); // This is non-exhaustive but covers the most common CSS properties that
200 // create a containing block.
201 // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
202
203 if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].includes(css.willChange) || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') {
204 return currentNode;
205 } else {
206 currentNode = currentNode.parentNode;
207 }
208 }
209
210 return null;
211} // Gets the closest ancestor positioned element. Handles some edge cases,
212// such as table ancestors and cross browser bugs.
213
214
215function getOffsetParent(element) {
216 var window = getWindow(element);
217 var offsetParent = getTrueOffsetParent(element);
218
219 while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') {
220 offsetParent = getTrueOffsetParent(offsetParent);
221 }
222
223 if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static')) {
224 return window;
225 }
226
227 return offsetParent || getContainingBlock(element) || window;
228}
229
230function getMainAxisFromPlacement(placement) {
231 return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';
232}
233
234var max = Math.max;
235var min = Math.min;
236var round = Math.round;
237
238function within(min$1, value, max$1) {
239 return max(min$1, min(value, max$1));
240}
241
242function getFreshSideObject() {
243 return {
244 top: 0,
245 right: 0,
246 bottom: 0,
247 left: 0
248 };
249}
250
251function mergePaddingObject(paddingObject) {
252 return Object.assign({}, getFreshSideObject(), paddingObject);
253}
254
255function expandToHashMap(value, keys) {
256 return keys.reduce(function (hashMap, key) {
257 hashMap[key] = value;
258 return hashMap;
259 }, {});
260}
261
262var toPaddingObject = function toPaddingObject(padding, state) {
263 padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, {
264 placement: state.placement
265 })) : padding;
266 return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));
267};
268
269function arrow(_ref) {
270 var _state$modifiersData$;
271
272 var state = _ref.state,
273 name = _ref.name,
274 options = _ref.options;
275 var arrowElement = state.elements.arrow;
276 var popperOffsets = state.modifiersData.popperOffsets;
277 var basePlacement = getBasePlacement(state.placement);
278 var axis = getMainAxisFromPlacement(basePlacement);
279 var isVertical = [left, right].indexOf(basePlacement) >= 0;
280 var len = isVertical ? 'height' : 'width';
281
282 if (!arrowElement || !popperOffsets) {
283 return;
284 }
285
286 var paddingObject = toPaddingObject(options.padding, state);
287 var arrowRect = getLayoutRect(arrowElement);
288 var minProp = axis === 'y' ? top : left;
289 var maxProp = axis === 'y' ? bottom : right;
290 var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len];
291 var startDiff = popperOffsets[axis] - state.rects.reference[axis];
292 var arrowOffsetParent = getOffsetParent(arrowElement);
293 var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;
294 var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is
295 // outside of the popper bounds
296
297 var min = paddingObject[minProp];
298 var max = clientSize - arrowRect[len] - paddingObject[maxProp];
299 var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;
300 var offset = within(min, center, max); // Prevents breaking syntax highlighting...
301
302 var axisProp = axis;
303 state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);
304}
305
306function effect$1(_ref2) {
307 var state = _ref2.state,
308 options = _ref2.options;
309 var _options$element = options.element,
310 arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element;
311
312 if (arrowElement == null) {
313 return;
314 } // CSS selector
315
316
317 if (typeof arrowElement === 'string') {
318 arrowElement = state.elements.popper.querySelector(arrowElement);
319
320 if (!arrowElement) {
321 return;
322 }
323 }
324
325 if (process.env.NODE_ENV !== "production") {
326 if (!isHTMLElement(arrowElement)) {
327 console.error(['Popper: "arrow" element must be an HTMLElement (not an SVGElement).', 'To use an SVG arrow, wrap it in an HTMLElement that will be used as', 'the arrow.'].join(' '));
328 }
329 }
330
331 if (!contains(state.elements.popper, arrowElement)) {
332 if (process.env.NODE_ENV !== "production") {
333 console.error(['Popper: "arrow" modifier\'s `element` must be a child of the popper', 'element.'].join(' '));
334 }
335
336 return;
337 }
338
339 state.elements.arrow = arrowElement;
340} // eslint-disable-next-line import/no-unused-modules
341
342
343var arrow$1 = {
344 name: 'arrow',
345 enabled: true,
346 phase: 'main',
347 fn: arrow,
348 effect: effect$1,
349 requires: ['popperOffsets'],
350 requiresIfExists: ['preventOverflow']
351};
352
353var unsetSides = {
354 top: 'auto',
355 right: 'auto',
356 bottom: 'auto',
357 left: 'auto'
358}; // Round the offsets to the nearest suitable subpixel based on the DPR.
359// Zooming can change the DPR, but it seems to report a value that will
360// cleanly divide the values into the appropriate subpixels.
361
362function roundOffsetsByDPR(_ref) {
363 var x = _ref.x,
364 y = _ref.y;
365 var win = window;
366 var dpr = win.devicePixelRatio || 1;
367 return {
368 x: round(round(x * dpr) / dpr) || 0,
369 y: round(round(y * dpr) / dpr) || 0
370 };
371}
372
373function mapToStyles(_ref2) {
374 var _Object$assign2;
375
376 var popper = _ref2.popper,
377 popperRect = _ref2.popperRect,
378 placement = _ref2.placement,
379 offsets = _ref2.offsets,
380 position = _ref2.position,
381 gpuAcceleration = _ref2.gpuAcceleration,
382 adaptive = _ref2.adaptive,
383 roundOffsets = _ref2.roundOffsets;
384
385 var _ref3 = roundOffsets === true ? roundOffsetsByDPR(offsets) : typeof roundOffsets === 'function' ? roundOffsets(offsets) : offsets,
386 _ref3$x = _ref3.x,
387 x = _ref3$x === void 0 ? 0 : _ref3$x,
388 _ref3$y = _ref3.y,
389 y = _ref3$y === void 0 ? 0 : _ref3$y;
390
391 var hasX = offsets.hasOwnProperty('x');
392 var hasY = offsets.hasOwnProperty('y');
393 var sideX = left;
394 var sideY = top;
395 var win = window;
396
397 if (adaptive) {
398 var offsetParent = getOffsetParent(popper);
399 var heightProp = 'clientHeight';
400 var widthProp = 'clientWidth';
401
402 if (offsetParent === getWindow(popper)) {
403 offsetParent = getDocumentElement(popper);
404
405 if (getComputedStyle(offsetParent).position !== 'static') {
406 heightProp = 'scrollHeight';
407 widthProp = 'scrollWidth';
408 }
409 } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it
410
411 /*:: offsetParent = (offsetParent: Element); */
412
413
414 if (placement === top) {
415 sideY = bottom; // $FlowFixMe[prop-missing]
416
417 y -= offsetParent[heightProp] - popperRect.height;
418 y *= gpuAcceleration ? 1 : -1;
419 }
420
421 if (placement === left) {
422 sideX = right; // $FlowFixMe[prop-missing]
423
424 x -= offsetParent[widthProp] - popperRect.width;
425 x *= gpuAcceleration ? 1 : -1;
426 }
427 }
428
429 var commonStyles = Object.assign({
430 position: position
431 }, adaptive && unsetSides);
432
433 if (gpuAcceleration) {
434 var _Object$assign;
435
436 return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) < 2 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign));
437 }
438
439 return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2));
440}
441
442function computeStyles(_ref4) {
443 var state = _ref4.state,
444 options = _ref4.options;
445 var _options$gpuAccelerat = options.gpuAcceleration,
446 gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,
447 _options$adaptive = options.adaptive,
448 adaptive = _options$adaptive === void 0 ? true : _options$adaptive,
449 _options$roundOffsets = options.roundOffsets,
450 roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;
451
452 if (process.env.NODE_ENV !== "production") {
453 var transitionProperty = getComputedStyle(state.elements.popper).transitionProperty || '';
454
455 if (adaptive && ['transform', 'top', 'right', 'bottom', 'left'].some(function (property) {
456 return transitionProperty.indexOf(property) >= 0;
457 })) {
458 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(' '));
459 }
460 }
461
462 var commonStyles = {
463 placement: getBasePlacement(state.placement),
464 popper: state.elements.popper,
465 popperRect: state.rects.popper,
466 gpuAcceleration: gpuAcceleration
467 };
468
469 if (state.modifiersData.popperOffsets != null) {
470 state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {
471 offsets: state.modifiersData.popperOffsets,
472 position: state.options.strategy,
473 adaptive: adaptive,
474 roundOffsets: roundOffsets
475 })));
476 }
477
478 if (state.modifiersData.arrow != null) {
479 state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {
480 offsets: state.modifiersData.arrow,
481 position: 'absolute',
482 adaptive: false,
483 roundOffsets: roundOffsets
484 })));
485 }
486
487 state.attributes.popper = Object.assign({}, state.attributes.popper, {
488 'data-popper-placement': state.placement
489 });
490} // eslint-disable-next-line import/no-unused-modules
491
492
493var computeStyles$1 = {
494 name: 'computeStyles',
495 enabled: true,
496 phase: 'beforeWrite',
497 fn: computeStyles,
498 data: {}
499};
500
501var passive = {
502 passive: true
503};
504
505function effect(_ref) {
506 var state = _ref.state,
507 instance = _ref.instance,
508 options = _ref.options;
509 var _options$scroll = options.scroll,
510 scroll = _options$scroll === void 0 ? true : _options$scroll,
511 _options$resize = options.resize,
512 resize = _options$resize === void 0 ? true : _options$resize;
513 var window = getWindow(state.elements.popper);
514 var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);
515
516 if (scroll) {
517 scrollParents.forEach(function (scrollParent) {
518 scrollParent.addEventListener('scroll', instance.update, passive);
519 });
520 }
521
522 if (resize) {
523 window.addEventListener('resize', instance.update, passive);
524 }
525
526 return function () {
527 if (scroll) {
528 scrollParents.forEach(function (scrollParent) {
529 scrollParent.removeEventListener('scroll', instance.update, passive);
530 });
531 }
532
533 if (resize) {
534 window.removeEventListener('resize', instance.update, passive);
535 }
536 };
537} // eslint-disable-next-line import/no-unused-modules
538
539
540var eventListeners = {
541 name: 'eventListeners',
542 enabled: true,
543 phase: 'write',
544 fn: function fn() {},
545 effect: effect,
546 data: {}
547};
548
549var hash$1 = {
550 left: 'right',
551 right: 'left',
552 bottom: 'top',
553 top: 'bottom'
554};
555function getOppositePlacement(placement) {
556 return placement.replace(/left|right|bottom|top/g, function (matched) {
557 return hash$1[matched];
558 });
559}
560
561var hash = {
562 start: 'end',
563 end: 'start'
564};
565function getOppositeVariationPlacement(placement) {
566 return placement.replace(/start|end/g, function (matched) {
567 return hash[matched];
568 });
569}
570
571function getWindowScroll(node) {
572 var win = getWindow(node);
573 var scrollLeft = win.pageXOffset;
574 var scrollTop = win.pageYOffset;
575 return {
576 scrollLeft: scrollLeft,
577 scrollTop: scrollTop
578 };
579}
580
581function getWindowScrollBarX(element) {
582 // If <html> has a CSS width greater than the viewport, then this will be
583 // incorrect for RTL.
584 // Popper 1 is broken in this case and never had a bug report so let's assume
585 // it's not an issue. I don't think anyone ever specifies width on <html>
586 // anyway.
587 // Browsers where the left scrollbar doesn't cause an issue report `0` for
588 // this (e.g. Edge 2019, IE11, Safari)
589 return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;
590}
591
592function getViewportRect(element) {
593 var win = getWindow(element);
594 var html = getDocumentElement(element);
595 var visualViewport = win.visualViewport;
596 var width = html.clientWidth;
597 var height = html.clientHeight;
598 var x = 0;
599 var y = 0; // NB: This isn't supported on iOS <= 12. If the keyboard is open, the popper
600 // can be obscured underneath it.
601 // Also, `html.clientHeight` adds the bottom bar height in Safari iOS, even
602 // if it isn't open, so if this isn't available, the popper will be detected
603 // to overflow the bottom of the screen too early.
604
605 if (visualViewport) {
606 width = visualViewport.width;
607 height = visualViewport.height; // Uses Layout Viewport (like Chrome; Safari does not currently)
608 // In Chrome, it returns a value very close to 0 (+/-) but contains rounding
609 // errors due to floating point numbers, so we need to check precision.
610 // Safari returns a number <= 0, usually < -1 when pinch-zoomed
611 // Feature detection fails in mobile emulation mode in Chrome.
612 // Math.abs(win.innerWidth / visualViewport.scale - visualViewport.width) <
613 // 0.001
614 // Fallback here: "Not Safari" userAgent
615
616 if (!/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {
617 x = visualViewport.offsetLeft;
618 y = visualViewport.offsetTop;
619 }
620 }
621
622 return {
623 width: width,
624 height: height,
625 x: x + getWindowScrollBarX(element),
626 y: y
627 };
628}
629
630// of the `<html>` and `<body>` rect bounds if horizontally scrollable
631
632function getDocumentRect(element) {
633 var _element$ownerDocumen;
634
635 var html = getDocumentElement(element);
636 var winScroll = getWindowScroll(element);
637 var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;
638 var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);
639 var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);
640 var x = -winScroll.scrollLeft + getWindowScrollBarX(element);
641 var y = -winScroll.scrollTop;
642
643 if (getComputedStyle(body || html).direction === 'rtl') {
644 x += max(html.clientWidth, body ? body.clientWidth : 0) - width;
645 }
646
647 return {
648 width: width,
649 height: height,
650 x: x,
651 y: y
652 };
653}
654
655function isScrollParent(element) {
656 // Firefox wants us to check `-x` and `-y` variations as well
657 var _getComputedStyle = getComputedStyle(element),
658 overflow = _getComputedStyle.overflow,
659 overflowX = _getComputedStyle.overflowX,
660 overflowY = _getComputedStyle.overflowY;
661
662 return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);
663}
664
665function getScrollParent(node) {
666 if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {
667 // $FlowFixMe[incompatible-return]: assume body is always available
668 return node.ownerDocument.body;
669 }
670
671 if (isHTMLElement(node) && isScrollParent(node)) {
672 return node;
673 }
674
675 return getScrollParent(getParentNode(node));
676}
677
678/*
679given a DOM element, return the list of all scroll parents, up the list of ancesors
680until we get to the top window object. This list is what we attach scroll listeners
681to, because if any of these parent elements scroll, we'll need to re-calculate the
682reference element's position.
683*/
684
685function listScrollParents(element, list) {
686 var _element$ownerDocumen;
687
688 if (list === void 0) {
689 list = [];
690 }
691
692 var scrollParent = getScrollParent(element);
693 var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);
694 var win = getWindow(scrollParent);
695 var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;
696 var updatedList = list.concat(target);
697 return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here
698 updatedList.concat(listScrollParents(getParentNode(target)));
699}
700
701function rectToClientRect(rect) {
702 return Object.assign({}, rect, {
703 left: rect.x,
704 top: rect.y,
705 right: rect.x + rect.width,
706 bottom: rect.y + rect.height
707 });
708}
709
710function getInnerBoundingClientRect(element) {
711 var rect = getBoundingClientRect(element);
712 rect.top = rect.top + element.clientTop;
713 rect.left = rect.left + element.clientLeft;
714 rect.bottom = rect.top + element.clientHeight;
715 rect.right = rect.left + element.clientWidth;
716 rect.width = element.clientWidth;
717 rect.height = element.clientHeight;
718 rect.x = rect.left;
719 rect.y = rect.top;
720 return rect;
721}
722
723function getClientRectFromMixedType(element, clippingParent) {
724 return clippingParent === viewport ? rectToClientRect(getViewportRect(element)) : isHTMLElement(clippingParent) ? getInnerBoundingClientRect(clippingParent) : rectToClientRect(getDocumentRect(getDocumentElement(element)));
725} // A "clipping parent" is an overflowable container with the characteristic of
726// clipping (or hiding) overflowing elements with a position different from
727// `initial`
728
729
730function getClippingParents(element) {
731 var clippingParents = listScrollParents(getParentNode(element));
732 var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle(element).position) >= 0;
733 var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;
734
735 if (!isElement(clipperElement)) {
736 return [];
737 } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414
738
739
740 return clippingParents.filter(function (clippingParent) {
741 return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body';
742 });
743} // Gets the maximum area that the element is visible in due to any number of
744// clipping parents
745
746
747function getClippingRect(element, boundary, rootBoundary) {
748 var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);
749 var clippingParents = [].concat(mainClippingParents, [rootBoundary]);
750 var firstClippingParent = clippingParents[0];
751 var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {
752 var rect = getClientRectFromMixedType(element, clippingParent);
753 accRect.top = max(rect.top, accRect.top);
754 accRect.right = min(rect.right, accRect.right);
755 accRect.bottom = min(rect.bottom, accRect.bottom);
756 accRect.left = max(rect.left, accRect.left);
757 return accRect;
758 }, getClientRectFromMixedType(element, firstClippingParent));
759 clippingRect.width = clippingRect.right - clippingRect.left;
760 clippingRect.height = clippingRect.bottom - clippingRect.top;
761 clippingRect.x = clippingRect.left;
762 clippingRect.y = clippingRect.top;
763 return clippingRect;
764}
765
766function getVariation(placement) {
767 return placement.split('-')[1];
768}
769
770function computeOffsets(_ref) {
771 var reference = _ref.reference,
772 element = _ref.element,
773 placement = _ref.placement;
774 var basePlacement = placement ? getBasePlacement(placement) : null;
775 var variation = placement ? getVariation(placement) : null;
776 var commonX = reference.x + reference.width / 2 - element.width / 2;
777 var commonY = reference.y + reference.height / 2 - element.height / 2;
778 var offsets;
779
780 switch (basePlacement) {
781 case top:
782 offsets = {
783 x: commonX,
784 y: reference.y - element.height
785 };
786 break;
787
788 case bottom:
789 offsets = {
790 x: commonX,
791 y: reference.y + reference.height
792 };
793 break;
794
795 case right:
796 offsets = {
797 x: reference.x + reference.width,
798 y: commonY
799 };
800 break;
801
802 case left:
803 offsets = {
804 x: reference.x - element.width,
805 y: commonY
806 };
807 break;
808
809 default:
810 offsets = {
811 x: reference.x,
812 y: reference.y
813 };
814 }
815
816 var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;
817
818 if (mainAxis != null) {
819 var len = mainAxis === 'y' ? 'height' : 'width';
820
821 switch (variation) {
822 case start:
823 offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);
824 break;
825
826 case end:
827 offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);
828 break;
829 }
830 }
831
832 return offsets;
833}
834
835function detectOverflow(state, options) {
836 if (options === void 0) {
837 options = {};
838 }
839
840 var _options = options,
841 _options$placement = _options.placement,
842 placement = _options$placement === void 0 ? state.placement : _options$placement,
843 _options$boundary = _options.boundary,
844 boundary = _options$boundary === void 0 ? clippingParents : _options$boundary,
845 _options$rootBoundary = _options.rootBoundary,
846 rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary,
847 _options$elementConte = _options.elementContext,
848 elementContext = _options$elementConte === void 0 ? popper : _options$elementConte,
849 _options$altBoundary = _options.altBoundary,
850 altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary,
851 _options$padding = _options.padding,
852 padding = _options$padding === void 0 ? 0 : _options$padding;
853 var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));
854 var altContext = elementContext === popper ? reference : popper;
855 var referenceElement = state.elements.reference;
856 var popperRect = state.rects.popper;
857 var element = state.elements[altBoundary ? altContext : elementContext];
858 var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary);
859 var referenceClientRect = getBoundingClientRect(referenceElement);
860 var popperOffsets = computeOffsets({
861 reference: referenceClientRect,
862 element: popperRect,
863 strategy: 'absolute',
864 placement: placement
865 });
866 var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets));
867 var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect
868 // 0 or negative = within the clipping rect
869
870 var overflowOffsets = {
871 top: clippingClientRect.top - elementClientRect.top + paddingObject.top,
872 bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,
873 left: clippingClientRect.left - elementClientRect.left + paddingObject.left,
874 right: elementClientRect.right - clippingClientRect.right + paddingObject.right
875 };
876 var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element
877
878 if (elementContext === popper && offsetData) {
879 var offset = offsetData[placement];
880 Object.keys(overflowOffsets).forEach(function (key) {
881 var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;
882 var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x';
883 overflowOffsets[key] += offset[axis] * multiply;
884 });
885 }
886
887 return overflowOffsets;
888}
889
890/*:: type OverflowsMap = { [ComputedPlacement]: number }; */
891
892/*;; type OverflowsMap = { [key in ComputedPlacement]: number }; */
893function computeAutoPlacement(state, options) {
894 if (options === void 0) {
895 options = {};
896 }
897
898 var _options = options,
899 placement = _options.placement,
900 boundary = _options.boundary,
901 rootBoundary = _options.rootBoundary,
902 padding = _options.padding,
903 flipVariations = _options.flipVariations,
904 _options$allowedAutoP = _options.allowedAutoPlacements,
905 allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP;
906 var variation = getVariation(placement);
907 var placements$1 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) {
908 return getVariation(placement) === variation;
909 }) : basePlacements;
910 var allowedPlacements = placements$1.filter(function (placement) {
911 return allowedAutoPlacements.indexOf(placement) >= 0;
912 });
913
914 if (allowedPlacements.length === 0) {
915 allowedPlacements = placements$1;
916
917 if (process.env.NODE_ENV !== "production") {
918 console.error(['Popper: The `allowedAutoPlacements` option did not allow any', 'placements. Ensure the `placement` option matches the variation', 'of the allowed placements.', 'For example, "auto" cannot be used to allow "bottom-start".', 'Use "auto-start" instead.'].join(' '));
919 }
920 } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...
921
922
923 var overflows = allowedPlacements.reduce(function (acc, placement) {
924 acc[placement] = detectOverflow(state, {
925 placement: placement,
926 boundary: boundary,
927 rootBoundary: rootBoundary,
928 padding: padding
929 })[getBasePlacement(placement)];
930 return acc;
931 }, {});
932 return Object.keys(overflows).sort(function (a, b) {
933 return overflows[a] - overflows[b];
934 });
935}
936
937function getExpandedFallbackPlacements(placement) {
938 if (getBasePlacement(placement) === auto) {
939 return [];
940 }
941
942 var oppositePlacement = getOppositePlacement(placement);
943 return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];
944}
945
946function flip(_ref) {
947 var state = _ref.state,
948 options = _ref.options,
949 name = _ref.name;
950
951 if (state.modifiersData[name]._skip) {
952 return;
953 }
954
955 var _options$mainAxis = options.mainAxis,
956 checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,
957 _options$altAxis = options.altAxis,
958 checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis,
959 specifiedFallbackPlacements = options.fallbackPlacements,
960 padding = options.padding,
961 boundary = options.boundary,
962 rootBoundary = options.rootBoundary,
963 altBoundary = options.altBoundary,
964 _options$flipVariatio = options.flipVariations,
965 flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio,
966 allowedAutoPlacements = options.allowedAutoPlacements;
967 var preferredPlacement = state.options.placement;
968 var basePlacement = getBasePlacement(preferredPlacement);
969 var isBasePlacement = basePlacement === preferredPlacement;
970 var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));
971 var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {
972 return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {
973 placement: placement,
974 boundary: boundary,
975 rootBoundary: rootBoundary,
976 padding: padding,
977 flipVariations: flipVariations,
978 allowedAutoPlacements: allowedAutoPlacements
979 }) : placement);
980 }, []);
981 var referenceRect = state.rects.reference;
982 var popperRect = state.rects.popper;
983 var checksMap = new Map();
984 var makeFallbackChecks = true;
985 var firstFittingPlacement = placements[0];
986
987 for (var i = 0; i < placements.length; i++) {
988 var placement = placements[i];
989
990 var _basePlacement = getBasePlacement(placement);
991
992 var isStartVariation = getVariation(placement) === start;
993 var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;
994 var len = isVertical ? 'width' : 'height';
995 var overflow = detectOverflow(state, {
996 placement: placement,
997 boundary: boundary,
998 rootBoundary: rootBoundary,
999 altBoundary: altBoundary,
1000 padding: padding
1001 });
1002 var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;
1003
1004 if (referenceRect[len] > popperRect[len]) {
1005 mainVariationSide = getOppositePlacement(mainVariationSide);
1006 }
1007
1008 var altVariationSide = getOppositePlacement(mainVariationSide);
1009 var checks = [];
1010
1011 if (checkMainAxis) {
1012 checks.push(overflow[_basePlacement] <= 0);
1013 }
1014
1015 if (checkAltAxis) {
1016 checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);
1017 }
1018
1019 if (checks.every(function (check) {
1020 return check;
1021 })) {
1022 firstFittingPlacement = placement;
1023 makeFallbackChecks = false;
1024 break;
1025 }
1026
1027 checksMap.set(placement, checks);
1028 }
1029
1030 if (makeFallbackChecks) {
1031 // `2` may be desired in some cases – research later
1032 var numberOfChecks = flipVariations ? 3 : 1;
1033
1034 var _loop = function _loop(_i) {
1035 var fittingPlacement = placements.find(function (placement) {
1036 var checks = checksMap.get(placement);
1037
1038 if (checks) {
1039 return checks.slice(0, _i).every(function (check) {
1040 return check;
1041 });
1042 }
1043 });
1044
1045 if (fittingPlacement) {
1046 firstFittingPlacement = fittingPlacement;
1047 return "break";
1048 }
1049 };
1050
1051 for (var _i = numberOfChecks; _i > 0; _i--) {
1052 var _ret = _loop(_i);
1053
1054 if (_ret === "break") break;
1055 }
1056 }
1057
1058 if (state.placement !== firstFittingPlacement) {
1059 state.modifiersData[name]._skip = true;
1060 state.placement = firstFittingPlacement;
1061 state.reset = true;
1062 }
1063} // eslint-disable-next-line import/no-unused-modules
1064
1065
1066var flip$1 = {
1067 name: 'flip',
1068 enabled: true,
1069 phase: 'main',
1070 fn: flip,
1071 requiresIfExists: ['offset'],
1072 data: {
1073 _skip: false
1074 }
1075};
1076
1077function getSideOffsets(overflow, rect, preventedOffsets) {
1078 if (preventedOffsets === void 0) {
1079 preventedOffsets = {
1080 x: 0,
1081 y: 0
1082 };
1083 }
1084
1085 return {
1086 top: overflow.top - rect.height - preventedOffsets.y,
1087 right: overflow.right - rect.width + preventedOffsets.x,
1088 bottom: overflow.bottom - rect.height + preventedOffsets.y,
1089 left: overflow.left - rect.width - preventedOffsets.x
1090 };
1091}
1092
1093function isAnySideFullyClipped(overflow) {
1094 return [top, right, bottom, left].some(function (side) {
1095 return overflow[side] >= 0;
1096 });
1097}
1098
1099function hide(_ref) {
1100 var state = _ref.state,
1101 name = _ref.name;
1102 var referenceRect = state.rects.reference;
1103 var popperRect = state.rects.popper;
1104 var preventedOffsets = state.modifiersData.preventOverflow;
1105 var referenceOverflow = detectOverflow(state, {
1106 elementContext: 'reference'
1107 });
1108 var popperAltOverflow = detectOverflow(state, {
1109 altBoundary: true
1110 });
1111 var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);
1112 var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);
1113 var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);
1114 var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);
1115 state.modifiersData[name] = {
1116 referenceClippingOffsets: referenceClippingOffsets,
1117 popperEscapeOffsets: popperEscapeOffsets,
1118 isReferenceHidden: isReferenceHidden,
1119 hasPopperEscaped: hasPopperEscaped
1120 };
1121 state.attributes.popper = Object.assign({}, state.attributes.popper, {
1122 'data-popper-reference-hidden': isReferenceHidden,
1123 'data-popper-escaped': hasPopperEscaped
1124 });
1125} // eslint-disable-next-line import/no-unused-modules
1126
1127
1128var hide$1 = {
1129 name: 'hide',
1130 enabled: true,
1131 phase: 'main',
1132 requiresIfExists: ['preventOverflow'],
1133 fn: hide
1134};
1135
1136function distanceAndSkiddingToXY(placement, rects, offset) {
1137 var basePlacement = getBasePlacement(placement);
1138 var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;
1139
1140 var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, {
1141 placement: placement
1142 })) : offset,
1143 skidding = _ref[0],
1144 distance = _ref[1];
1145
1146 skidding = skidding || 0;
1147 distance = (distance || 0) * invertDistance;
1148 return [left, right].indexOf(basePlacement) >= 0 ? {
1149 x: distance,
1150 y: skidding
1151 } : {
1152 x: skidding,
1153 y: distance
1154 };
1155}
1156
1157function offset(_ref2) {
1158 var state = _ref2.state,
1159 options = _ref2.options,
1160 name = _ref2.name;
1161 var _options$offset = options.offset,
1162 offset = _options$offset === void 0 ? [0, 0] : _options$offset;
1163 var data = placements.reduce(function (acc, placement) {
1164 acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);
1165 return acc;
1166 }, {});
1167 var _data$state$placement = data[state.placement],
1168 x = _data$state$placement.x,
1169 y = _data$state$placement.y;
1170
1171 if (state.modifiersData.popperOffsets != null) {
1172 state.modifiersData.popperOffsets.x += x;
1173 state.modifiersData.popperOffsets.y += y;
1174 }
1175
1176 state.modifiersData[name] = data;
1177} // eslint-disable-next-line import/no-unused-modules
1178
1179
1180var offset$1 = {
1181 name: 'offset',
1182 enabled: true,
1183 phase: 'main',
1184 requires: ['popperOffsets'],
1185 fn: offset
1186};
1187
1188function popperOffsets(_ref) {
1189 var state = _ref.state,
1190 name = _ref.name;
1191 // Offsets are the actual position the popper needs to have to be
1192 // properly positioned near its reference element
1193 // This is the most basic placement, and will be adjusted by
1194 // the modifiers in the next step
1195 state.modifiersData[name] = computeOffsets({
1196 reference: state.rects.reference,
1197 element: state.rects.popper,
1198 strategy: 'absolute',
1199 placement: state.placement
1200 });
1201} // eslint-disable-next-line import/no-unused-modules
1202
1203
1204var popperOffsets$1 = {
1205 name: 'popperOffsets',
1206 enabled: true,
1207 phase: 'read',
1208 fn: popperOffsets,
1209 data: {}
1210};
1211
1212function getAltAxis(axis) {
1213 return axis === 'x' ? 'y' : 'x';
1214}
1215
1216function preventOverflow(_ref) {
1217 var state = _ref.state,
1218 options = _ref.options,
1219 name = _ref.name;
1220 var _options$mainAxis = options.mainAxis,
1221 checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,
1222 _options$altAxis = options.altAxis,
1223 checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis,
1224 boundary = options.boundary,
1225 rootBoundary = options.rootBoundary,
1226 altBoundary = options.altBoundary,
1227 padding = options.padding,
1228 _options$tether = options.tether,
1229 tether = _options$tether === void 0 ? true : _options$tether,
1230 _options$tetherOffset = options.tetherOffset,
1231 tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;
1232 var overflow = detectOverflow(state, {
1233 boundary: boundary,
1234 rootBoundary: rootBoundary,
1235 padding: padding,
1236 altBoundary: altBoundary
1237 });
1238 var basePlacement = getBasePlacement(state.placement);
1239 var variation = getVariation(state.placement);
1240 var isBasePlacement = !variation;
1241 var mainAxis = getMainAxisFromPlacement(basePlacement);
1242 var altAxis = getAltAxis(mainAxis);
1243 var popperOffsets = state.modifiersData.popperOffsets;
1244 var referenceRect = state.rects.reference;
1245 var popperRect = state.rects.popper;
1246 var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, {
1247 placement: state.placement
1248 })) : tetherOffset;
1249 var data = {
1250 x: 0,
1251 y: 0
1252 };
1253
1254 if (!popperOffsets) {
1255 return;
1256 }
1257
1258 if (checkMainAxis || checkAltAxis) {
1259 var mainSide = mainAxis === 'y' ? top : left;
1260 var altSide = mainAxis === 'y' ? bottom : right;
1261 var len = mainAxis === 'y' ? 'height' : 'width';
1262 var offset = popperOffsets[mainAxis];
1263 var min$1 = popperOffsets[mainAxis] + overflow[mainSide];
1264 var max$1 = popperOffsets[mainAxis] - overflow[altSide];
1265 var additive = tether ? -popperRect[len] / 2 : 0;
1266 var minLen = variation === start ? referenceRect[len] : popperRect[len];
1267 var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go
1268 // outside the reference bounds
1269
1270 var arrowElement = state.elements.arrow;
1271 var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {
1272 width: 0,
1273 height: 0
1274 };
1275 var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject();
1276 var arrowPaddingMin = arrowPaddingObject[mainSide];
1277 var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want
1278 // to include its full size in the calculation. If the reference is small
1279 // and near the edge of a boundary, the popper can overflow even if the
1280 // reference is not overflowing as well (e.g. virtual elements with no
1281 // width or height)
1282
1283 var arrowLen = within(0, referenceRect[len], arrowRect[len]);
1284 var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - tetherOffsetValue : minLen - arrowLen - arrowPaddingMin - tetherOffsetValue;
1285 var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + tetherOffsetValue : maxLen + arrowLen + arrowPaddingMax + tetherOffsetValue;
1286 var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);
1287 var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;
1288 var offsetModifierValue = state.modifiersData.offset ? state.modifiersData.offset[state.placement][mainAxis] : 0;
1289 var tetherMin = popperOffsets[mainAxis] + minOffset - offsetModifierValue - clientOffset;
1290 var tetherMax = popperOffsets[mainAxis] + maxOffset - offsetModifierValue;
1291
1292 if (checkMainAxis) {
1293 var preventedOffset = within(tether ? min(min$1, tetherMin) : min$1, offset, tether ? max(max$1, tetherMax) : max$1);
1294 popperOffsets[mainAxis] = preventedOffset;
1295 data[mainAxis] = preventedOffset - offset;
1296 }
1297
1298 if (checkAltAxis) {
1299 var _mainSide = mainAxis === 'x' ? top : left;
1300
1301 var _altSide = mainAxis === 'x' ? bottom : right;
1302
1303 var _offset = popperOffsets[altAxis];
1304
1305 var _min = _offset + overflow[_mainSide];
1306
1307 var _max = _offset - overflow[_altSide];
1308
1309 var _preventedOffset = within(tether ? min(_min, tetherMin) : _min, _offset, tether ? max(_max, tetherMax) : _max);
1310
1311 popperOffsets[altAxis] = _preventedOffset;
1312 data[altAxis] = _preventedOffset - _offset;
1313 }
1314 }
1315
1316 state.modifiersData[name] = data;
1317} // eslint-disable-next-line import/no-unused-modules
1318
1319
1320var preventOverflow$1 = {
1321 name: 'preventOverflow',
1322 enabled: true,
1323 phase: 'main',
1324 fn: preventOverflow,
1325 requiresIfExists: ['offset']
1326};
1327
1328function getHTMLElementScroll(element) {
1329 return {
1330 scrollLeft: element.scrollLeft,
1331 scrollTop: element.scrollTop
1332 };
1333}
1334
1335function getNodeScroll(node) {
1336 if (node === getWindow(node) || !isHTMLElement(node)) {
1337 return getWindowScroll(node);
1338 } else {
1339 return getHTMLElementScroll(node);
1340 }
1341}
1342
1343// Composite means it takes into account transforms as well as layout.
1344
1345function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {
1346 if (isFixed === void 0) {
1347 isFixed = false;
1348 }
1349
1350 var documentElement = getDocumentElement(offsetParent);
1351 var rect = getBoundingClientRect(elementOrVirtualElement);
1352 var isOffsetParentAnElement = isHTMLElement(offsetParent);
1353 var scroll = {
1354 scrollLeft: 0,
1355 scrollTop: 0
1356 };
1357 var offsets = {
1358 x: 0,
1359 y: 0
1360 };
1361
1362 if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
1363 if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078
1364 isScrollParent(documentElement)) {
1365 scroll = getNodeScroll(offsetParent);
1366 }
1367
1368 if (isHTMLElement(offsetParent)) {
1369 offsets = getBoundingClientRect(offsetParent);
1370 offsets.x += offsetParent.clientLeft;
1371 offsets.y += offsetParent.clientTop;
1372 } else if (documentElement) {
1373 offsets.x = getWindowScrollBarX(documentElement);
1374 }
1375 }
1376
1377 return {
1378 x: rect.left + scroll.scrollLeft - offsets.x,
1379 y: rect.top + scroll.scrollTop - offsets.y,
1380 width: rect.width,
1381 height: rect.height
1382 };
1383}
1384
1385function order(modifiers) {
1386 var map = new Map();
1387 var visited = new Set();
1388 var result = [];
1389 modifiers.forEach(function (modifier) {
1390 map.set(modifier.name, modifier);
1391 }); // On visiting object, check for its dependencies and visit them recursively
1392
1393 function sort(modifier) {
1394 visited.add(modifier.name);
1395 var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);
1396 requires.forEach(function (dep) {
1397 if (!visited.has(dep)) {
1398 var depModifier = map.get(dep);
1399
1400 if (depModifier) {
1401 sort(depModifier);
1402 }
1403 }
1404 });
1405 result.push(modifier);
1406 }
1407
1408 modifiers.forEach(function (modifier) {
1409 if (!visited.has(modifier.name)) {
1410 // check for visited object
1411 sort(modifier);
1412 }
1413 });
1414 return result;
1415}
1416
1417function orderModifiers(modifiers) {
1418 // order based on dependencies
1419 var orderedModifiers = order(modifiers); // order based on phase
1420
1421 return modifierPhases.reduce(function (acc, phase) {
1422 return acc.concat(orderedModifiers.filter(function (modifier) {
1423 return modifier.phase === phase;
1424 }));
1425 }, []);
1426}
1427
1428function debounce(fn) {
1429 var pending;
1430 return function () {
1431 if (!pending) {
1432 pending = new Promise(function (resolve) {
1433 Promise.resolve().then(function () {
1434 pending = undefined;
1435 resolve(fn());
1436 });
1437 });
1438 }
1439
1440 return pending;
1441 };
1442}
1443
1444function format(str) {
1445 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1446 args[_key - 1] = arguments[_key];
1447 }
1448
1449 return [].concat(args).reduce(function (p, c) {
1450 return p.replace(/%s/, c);
1451 }, str);
1452}
1453
1454var INVALID_MODIFIER_ERROR = 'Popper: modifier "%s" provided an invalid %s property, expected %s but got %s';
1455var MISSING_DEPENDENCY_ERROR = 'Popper: modifier "%s" requires "%s", but "%s" modifier is not available';
1456var VALID_PROPERTIES = ['name', 'enabled', 'phase', 'fn', 'effect', 'requires', 'options'];
1457function validateModifiers(modifiers) {
1458 modifiers.forEach(function (modifier) {
1459 Object.keys(modifier).forEach(function (key) {
1460 switch (key) {
1461 case 'name':
1462 if (typeof modifier.name !== 'string') {
1463 console.error(format(INVALID_MODIFIER_ERROR, String(modifier.name), '"name"', '"string"', "\"" + String(modifier.name) + "\""));
1464 }
1465
1466 break;
1467
1468 case 'enabled':
1469 if (typeof modifier.enabled !== 'boolean') {
1470 console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"enabled"', '"boolean"', "\"" + String(modifier.enabled) + "\""));
1471 }
1472
1473 case 'phase':
1474 if (modifierPhases.indexOf(modifier.phase) < 0) {
1475 console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"phase"', "either " + modifierPhases.join(', '), "\"" + String(modifier.phase) + "\""));
1476 }
1477
1478 break;
1479
1480 case 'fn':
1481 if (typeof modifier.fn !== 'function') {
1482 console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"fn"', '"function"', "\"" + String(modifier.fn) + "\""));
1483 }
1484
1485 break;
1486
1487 case 'effect':
1488 if (typeof modifier.effect !== 'function') {
1489 console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"effect"', '"function"', "\"" + String(modifier.fn) + "\""));
1490 }
1491
1492 break;
1493
1494 case 'requires':
1495 if (!Array.isArray(modifier.requires)) {
1496 console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requires"', '"array"', "\"" + String(modifier.requires) + "\""));
1497 }
1498
1499 break;
1500
1501 case 'requiresIfExists':
1502 if (!Array.isArray(modifier.requiresIfExists)) {
1503 console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requiresIfExists"', '"array"', "\"" + String(modifier.requiresIfExists) + "\""));
1504 }
1505
1506 break;
1507
1508 case 'options':
1509 case 'data':
1510 break;
1511
1512 default:
1513 console.error("PopperJS: an invalid property has been provided to the \"" + modifier.name + "\" modifier, valid properties are " + VALID_PROPERTIES.map(function (s) {
1514 return "\"" + s + "\"";
1515 }).join(', ') + "; but \"" + key + "\" was provided.");
1516 }
1517
1518 modifier.requires && modifier.requires.forEach(function (requirement) {
1519 if (modifiers.find(function (mod) {
1520 return mod.name === requirement;
1521 }) == null) {
1522 console.error(format(MISSING_DEPENDENCY_ERROR, String(modifier.name), requirement, requirement));
1523 }
1524 });
1525 });
1526 });
1527}
1528
1529function uniqueBy(arr, fn) {
1530 var identifiers = new Set();
1531 return arr.filter(function (item) {
1532 var identifier = fn(item);
1533
1534 if (!identifiers.has(identifier)) {
1535 identifiers.add(identifier);
1536 return true;
1537 }
1538 });
1539}
1540
1541function mergeByName(modifiers) {
1542 var merged = modifiers.reduce(function (merged, current) {
1543 var existing = merged[current.name];
1544 merged[current.name] = existing ? Object.assign({}, existing, current, {
1545 options: Object.assign({}, existing.options, current.options),
1546 data: Object.assign({}, existing.data, current.data)
1547 }) : current;
1548 return merged;
1549 }, {}); // IE11 does not support Object.values
1550
1551 return Object.keys(merged).map(function (key) {
1552 return merged[key];
1553 });
1554}
1555
1556var INVALID_ELEMENT_ERROR = 'Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element.';
1557var INFINITE_LOOP_ERROR = 'Popper: An infinite loop in the modifiers cycle has been detected! The cycle has been interrupted to prevent a browser crash.';
1558var DEFAULT_OPTIONS = {
1559 placement: 'bottom',
1560 modifiers: [],
1561 strategy: 'absolute'
1562};
1563
1564function areValidElements() {
1565 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
1566 args[_key] = arguments[_key];
1567 }
1568
1569 return !args.some(function (element) {
1570 return !(element && typeof element.getBoundingClientRect === 'function');
1571 });
1572}
1573
1574function popperGenerator(generatorOptions) {
1575 if (generatorOptions === void 0) {
1576 generatorOptions = {};
1577 }
1578
1579 var _generatorOptions = generatorOptions,
1580 _generatorOptions$def = _generatorOptions.defaultModifiers,
1581 defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def,
1582 _generatorOptions$def2 = _generatorOptions.defaultOptions,
1583 defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;
1584 return function createPopper(reference, popper, options) {
1585 if (options === void 0) {
1586 options = defaultOptions;
1587 }
1588
1589 var state = {
1590 placement: 'bottom',
1591 orderedModifiers: [],
1592 options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),
1593 modifiersData: {},
1594 elements: {
1595 reference: reference,
1596 popper: popper
1597 },
1598 attributes: {},
1599 styles: {}
1600 };
1601 var effectCleanupFns = [];
1602 var isDestroyed = false;
1603 var instance = {
1604 state: state,
1605 setOptions: function setOptions(options) {
1606 cleanupModifierEffects();
1607 state.options = Object.assign({}, defaultOptions, state.options, options);
1608 state.scrollParents = {
1609 reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [],
1610 popper: listScrollParents(popper)
1611 }; // Orders the modifiers based on their dependencies and `phase`
1612 // properties
1613
1614 var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers
1615
1616 state.orderedModifiers = orderedModifiers.filter(function (m) {
1617 return m.enabled;
1618 }); // Validate the provided modifiers so that the consumer will get warned
1619 // if one of the modifiers is invalid for any reason
1620
1621 if (process.env.NODE_ENV !== "production") {
1622 var modifiers = uniqueBy([].concat(orderedModifiers, state.options.modifiers), function (_ref) {
1623 var name = _ref.name;
1624 return name;
1625 });
1626 validateModifiers(modifiers);
1627
1628 if (getBasePlacement(state.options.placement) === auto) {
1629 var flipModifier = state.orderedModifiers.find(function (_ref2) {
1630 var name = _ref2.name;
1631 return name === 'flip';
1632 });
1633
1634 if (!flipModifier) {
1635 console.error(['Popper: "auto" placements require the "flip" modifier be', 'present and enabled to work.'].join(' '));
1636 }
1637 }
1638
1639 var _getComputedStyle = getComputedStyle(popper),
1640 marginTop = _getComputedStyle.marginTop,
1641 marginRight = _getComputedStyle.marginRight,
1642 marginBottom = _getComputedStyle.marginBottom,
1643 marginLeft = _getComputedStyle.marginLeft; // We no longer take into account `margins` on the popper, and it can
1644 // cause bugs with positioning, so we'll warn the consumer
1645
1646
1647 if ([marginTop, marginRight, marginBottom, marginLeft].some(function (margin) {
1648 return parseFloat(margin);
1649 })) {
1650 console.warn(['Popper: CSS "margin" styles cannot be used to apply padding', 'between the popper and its reference element or boundary.', 'To replicate margin, use the `offset` modifier, as well as', 'the `padding` option in the `preventOverflow` and `flip`', 'modifiers.'].join(' '));
1651 }
1652 }
1653
1654 runModifierEffects();
1655 return instance.update();
1656 },
1657 // Sync update – it will always be executed, even if not necessary. This
1658 // is useful for low frequency updates where sync behavior simplifies the
1659 // logic.
1660 // For high frequency updates (e.g. `resize` and `scroll` events), always
1661 // prefer the async Popper#update method
1662 forceUpdate: function forceUpdate() {
1663 if (isDestroyed) {
1664 return;
1665 }
1666
1667 var _state$elements = state.elements,
1668 reference = _state$elements.reference,
1669 popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements
1670 // anymore
1671
1672 if (!areValidElements(reference, popper)) {
1673 if (process.env.NODE_ENV !== "production") {
1674 console.error(INVALID_ELEMENT_ERROR);
1675 }
1676
1677 return;
1678 } // Store the reference and popper rects to be read by modifiers
1679
1680
1681 state.rects = {
1682 reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'),
1683 popper: getLayoutRect(popper)
1684 }; // Modifiers have the ability to reset the current update cycle. The
1685 // most common use case for this is the `flip` modifier changing the
1686 // placement, which then needs to re-run all the modifiers, because the
1687 // logic was previously ran for the previous placement and is therefore
1688 // stale/incorrect
1689
1690 state.reset = false;
1691 state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier
1692 // is filled with the initial data specified by the modifier. This means
1693 // it doesn't persist and is fresh on each update.
1694 // To ensure persistent data, use `${name}#persistent`
1695
1696 state.orderedModifiers.forEach(function (modifier) {
1697 return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);
1698 });
1699 var __debug_loops__ = 0;
1700
1701 for (var index = 0; index < state.orderedModifiers.length; index++) {
1702 if (process.env.NODE_ENV !== "production") {
1703 __debug_loops__ += 1;
1704
1705 if (__debug_loops__ > 100) {
1706 console.error(INFINITE_LOOP_ERROR);
1707 break;
1708 }
1709 }
1710
1711 if (state.reset === true) {
1712 state.reset = false;
1713 index = -1;
1714 continue;
1715 }
1716
1717 var _state$orderedModifie = state.orderedModifiers[index],
1718 fn = _state$orderedModifie.fn,
1719 _state$orderedModifie2 = _state$orderedModifie.options,
1720 _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2,
1721 name = _state$orderedModifie.name;
1722
1723 if (typeof fn === 'function') {
1724 state = fn({
1725 state: state,
1726 options: _options,
1727 name: name,
1728 instance: instance
1729 }) || state;
1730 }
1731 }
1732 },
1733 // Async and optimistically optimized update – it will not be executed if
1734 // not necessary (debounced to run at most once-per-tick)
1735 update: debounce(function () {
1736 return new Promise(function (resolve) {
1737 instance.forceUpdate();
1738 resolve(state);
1739 });
1740 }),
1741 destroy: function destroy() {
1742 cleanupModifierEffects();
1743 isDestroyed = true;
1744 }
1745 };
1746
1747 if (!areValidElements(reference, popper)) {
1748 if (process.env.NODE_ENV !== "production") {
1749 console.error(INVALID_ELEMENT_ERROR);
1750 }
1751
1752 return instance;
1753 }
1754
1755 instance.setOptions(options).then(function (state) {
1756 if (!isDestroyed && options.onFirstUpdate) {
1757 options.onFirstUpdate(state);
1758 }
1759 }); // Modifiers have the ability to execute arbitrary code before the first
1760 // update cycle runs. They will be executed in the same order as the update
1761 // cycle. This is useful when a modifier adds some persistent data that
1762 // other modifiers need to use, but the modifier is run after the dependent
1763 // one.
1764
1765 function runModifierEffects() {
1766 state.orderedModifiers.forEach(function (_ref3) {
1767 var name = _ref3.name,
1768 _ref3$options = _ref3.options,
1769 options = _ref3$options === void 0 ? {} : _ref3$options,
1770 effect = _ref3.effect;
1771
1772 if (typeof effect === 'function') {
1773 var cleanupFn = effect({
1774 state: state,
1775 name: name,
1776 instance: instance,
1777 options: options
1778 });
1779
1780 var noopFn = function noopFn() {};
1781
1782 effectCleanupFns.push(cleanupFn || noopFn);
1783 }
1784 });
1785 }
1786
1787 function cleanupModifierEffects() {
1788 effectCleanupFns.forEach(function (fn) {
1789 return fn();
1790 });
1791 effectCleanupFns = [];
1792 }
1793
1794 return instance;
1795 };
1796}
1797
1798// For the common JS build we will turn this file into a bundle with no imports.
1799// This is b/c the Popper lib is all esm files, and would break in a common js only environment
1800const createPopper = popperGenerator({
1801 defaultModifiers: [
1802 hide$1,
1803 popperOffsets$1,
1804 computeStyles$1,
1805 eventListeners,
1806 offset$1,
1807 flip$1,
1808 preventOverflow$1,
1809 arrow$1,
1810 ],
1811});
1812
1813exports.createPopper = createPopper;
1814exports.placements = placements;