react-tooltip 5.7.3 → 5.7.4-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,21 +1,21 @@
1
1
  import require$$0, { createContext, useState, useCallback, useMemo, useContext, useRef, useEffect } from 'react';
2
2
 
3
- function getSide(placement) {
4
- return placement.split('-')[0];
5
- }
6
-
7
3
  function getAlignment(placement) {
8
4
  return placement.split('-')[1];
9
5
  }
10
6
 
11
- function getMainAxisFromPlacement(placement) {
12
- return ['top', 'bottom'].includes(getSide(placement)) ? 'x' : 'y';
13
- }
14
-
15
7
  function getLengthFromAxis(axis) {
16
8
  return axis === 'y' ? 'height' : 'width';
17
9
  }
18
10
 
11
+ function getSide(placement) {
12
+ return placement.split('-')[0];
13
+ }
14
+
15
+ function getMainAxisFromPlacement(placement) {
16
+ return ['top', 'bottom'].includes(getSide(placement)) ? 'x' : 'y';
17
+ }
18
+
19
19
  function computeCoordsFromPlacement(_ref, placement, rtl) {
20
20
  let {
21
21
  reference,
@@ -29,7 +29,6 @@ function computeCoordsFromPlacement(_ref, placement, rtl) {
29
29
  const side = getSide(placement);
30
30
  const isVertical = mainAxis === 'x';
31
31
  let coords;
32
-
33
32
  switch (side) {
34
33
  case 'top':
35
34
  coords = {
@@ -37,45 +36,38 @@ function computeCoordsFromPlacement(_ref, placement, rtl) {
37
36
  y: reference.y - floating.height
38
37
  };
39
38
  break;
40
-
41
39
  case 'bottom':
42
40
  coords = {
43
41
  x: commonX,
44
42
  y: reference.y + reference.height
45
43
  };
46
44
  break;
47
-
48
45
  case 'right':
49
46
  coords = {
50
47
  x: reference.x + reference.width,
51
48
  y: commonY
52
49
  };
53
50
  break;
54
-
55
51
  case 'left':
56
52
  coords = {
57
53
  x: reference.x - floating.width,
58
54
  y: commonY
59
55
  };
60
56
  break;
61
-
62
57
  default:
63
58
  coords = {
64
59
  x: reference.x,
65
60
  y: reference.y
66
61
  };
67
62
  }
68
-
69
63
  switch (getAlignment(placement)) {
70
64
  case 'start':
71
65
  coords[mainAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);
72
66
  break;
73
-
74
67
  case 'end':
75
68
  coords[mainAxis] += commonAlign * (rtl && isVertical ? -1 : 1);
76
69
  break;
77
70
  }
78
-
79
71
  return coords;
80
72
  }
81
73
 
@@ -86,7 +78,6 @@ function computeCoordsFromPlacement(_ref, placement, rtl) {
86
78
  * This export does not have any `platform` interface logic. You will need to
87
79
  * write one for the platform you are using Floating UI with.
88
80
  */
89
-
90
81
  const computePosition$1 = async (reference, floating, config) => {
91
82
  const {
92
83
  placement = 'bottom',
@@ -96,12 +87,10 @@ const computePosition$1 = async (reference, floating, config) => {
96
87
  } = config;
97
88
  const validMiddleware = middleware.filter(Boolean);
98
89
  const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(floating));
99
-
100
90
  {
101
91
  if (platform == null) {
102
92
  console.error(['Floating UI: `platform` property was not passed to config. If you', 'want to use Floating UI on the web, install @floating-ui/dom', 'instead of the /core package. Otherwise, you can create your own', '`platform`: https://floating-ui.com/docs/platform'].join(' '));
103
93
  }
104
-
105
94
  if (validMiddleware.filter(_ref => {
106
95
  let {
107
96
  name
@@ -110,12 +99,10 @@ const computePosition$1 = async (reference, floating, config) => {
110
99
  }).length > 1) {
111
100
  throw new Error(['Floating UI: duplicate `flip` and/or `autoPlacement` middleware', 'detected. This will lead to an infinite loop. Ensure only one of', 'either has been passed to the `middleware` array.'].join(' '));
112
101
  }
113
-
114
102
  if (!reference || !floating) {
115
103
  console.error(['Floating UI: The reference and/or floating element was not defined', 'when `computePosition()` was called. Ensure that both elements have', 'been created and can be measured.'].join(' '));
116
104
  }
117
105
  }
118
-
119
106
  let rects = await platform.getElementRects({
120
107
  reference,
121
108
  floating,
@@ -128,7 +115,6 @@ const computePosition$1 = async (reference, floating, config) => {
128
115
  let statefulPlacement = placement;
129
116
  let middlewareData = {};
130
117
  let resetCount = 0;
131
-
132
118
  for (let i = 0; i < validMiddleware.length; i++) {
133
119
  const {
134
120
  name,
@@ -155,26 +141,24 @@ const computePosition$1 = async (reference, floating, config) => {
155
141
  });
156
142
  x = nextX != null ? nextX : x;
157
143
  y = nextY != null ? nextY : y;
158
- middlewareData = { ...middlewareData,
159
- [name]: { ...middlewareData[name],
144
+ middlewareData = {
145
+ ...middlewareData,
146
+ [name]: {
147
+ ...middlewareData[name],
160
148
  ...data
161
149
  }
162
150
  };
163
-
164
151
  {
165
152
  if (resetCount > 50) {
166
153
  console.warn(['Floating UI: The middleware lifecycle appears to be running in an', 'infinite loop. This is usually caused by a `reset` continually', 'being returned without a break condition.'].join(' '));
167
154
  }
168
155
  }
169
-
170
156
  if (reset && resetCount <= 50) {
171
157
  resetCount++;
172
-
173
158
  if (typeof reset === 'object') {
174
159
  if (reset.placement) {
175
160
  statefulPlacement = reset.placement;
176
161
  }
177
-
178
162
  if (reset.rects) {
179
163
  rects = reset.rects === true ? await platform.getElementRects({
180
164
  reference,
@@ -182,18 +166,15 @@ const computePosition$1 = async (reference, floating, config) => {
182
166
  strategy
183
167
  }) : reset.rects;
184
168
  }
185
-
186
169
  ({
187
170
  x,
188
171
  y
189
172
  } = computeCoordsFromPlacement(rects, statefulPlacement, rtl));
190
173
  }
191
-
192
174
  i = -1;
193
175
  continue;
194
176
  }
195
177
  }
196
-
197
178
  return {
198
179
  x,
199
180
  y,
@@ -223,7 +204,8 @@ function getSideObjectFromPadding(padding) {
223
204
  }
224
205
 
225
206
  function rectToClientRect(rect) {
226
- return { ...rect,
207
+ return {
208
+ ...rect,
227
209
  top: rect.y,
228
210
  left: rect.x,
229
211
  right: rect.x + rect.width,
@@ -241,11 +223,9 @@ function rectToClientRect(rect) {
241
223
  */
242
224
  async function detectOverflow(middlewareArguments, options) {
243
225
  var _await$platform$isEle;
244
-
245
226
  if (options === void 0) {
246
227
  options = {};
247
228
  }
248
-
249
229
  const {
250
230
  x,
251
231
  y,
@@ -270,19 +250,29 @@ async function detectOverflow(middlewareArguments, options) {
270
250
  rootBoundary,
271
251
  strategy
272
252
  }));
253
+ const rect = elementContext === 'floating' ? {
254
+ ...rects.floating,
255
+ x,
256
+ y
257
+ } : rects.reference;
258
+ const offsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating));
259
+ const offsetScale = (await (platform.isElement == null ? void 0 : platform.isElement(offsetParent))) ? (await (platform.getScale == null ? void 0 : platform.getScale(offsetParent))) || {
260
+ x: 1,
261
+ y: 1
262
+ } : {
263
+ x: 1,
264
+ y: 1
265
+ };
273
266
  const elementClientRect = rectToClientRect(platform.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform.convertOffsetParentRelativeRectToViewportRelativeRect({
274
- rect: elementContext === 'floating' ? { ...rects.floating,
275
- x,
276
- y
277
- } : rects.reference,
278
- offsetParent: await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating)),
267
+ rect,
268
+ offsetParent,
279
269
  strategy
280
- }) : rects[elementContext]);
270
+ }) : rect);
281
271
  return {
282
- top: clippingClientRect.top - elementClientRect.top + paddingObject.top,
283
- bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,
284
- left: clippingClientRect.left - elementClientRect.left + paddingObject.left,
285
- right: elementClientRect.right - clippingClientRect.right + paddingObject.right
272
+ top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
273
+ bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
274
+ left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
275
+ right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
286
276
  };
287
277
  }
288
278
 
@@ -301,13 +291,12 @@ function within(min$1$1, value, max$1$1) {
301
291
  const arrow = options => ({
302
292
  name: 'arrow',
303
293
  options,
304
-
305
294
  async fn(middlewareArguments) {
306
- // Since `element` is required, we don't Partial<> the type
295
+ // Since `element` is required, we don't Partial<> the type.
307
296
  const {
308
297
  element,
309
298
  padding = 0
310
- } = options != null ? options : {};
299
+ } = options || {};
311
300
  const {
312
301
  x,
313
302
  y,
@@ -315,22 +304,18 @@ const arrow = options => ({
315
304
  rects,
316
305
  platform
317
306
  } = middlewareArguments;
318
-
319
307
  if (element == null) {
320
308
  {
321
309
  console.warn('Floating UI: No `element` was passed to the `arrow` middleware.');
322
310
  }
323
-
324
311
  return {};
325
312
  }
326
-
327
313
  const paddingObject = getSideObjectFromPadding(padding);
328
314
  const coords = {
329
315
  x,
330
316
  y
331
317
  };
332
318
  const axis = getMainAxisFromPlacement(placement);
333
- const alignment = getAlignment(placement);
334
319
  const length = getLengthFromAxis(axis);
335
320
  const arrowDimensions = await platform.getDimensions(element);
336
321
  const minProp = axis === 'y' ? 'top' : 'left';
@@ -339,21 +324,23 @@ const arrow = options => ({
339
324
  const startDiff = coords[axis] - rects.reference[axis];
340
325
  const arrowOffsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(element));
341
326
  let clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;
342
-
343
327
  if (clientSize === 0) {
344
328
  clientSize = rects.floating[length];
345
329
  }
330
+ const centerToReference = endDiff / 2 - startDiff / 2;
346
331
 
347
- const centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the floating element if the center
348
- // point is outside the floating element's bounds
349
-
332
+ // Make sure the arrow doesn't overflow the floating element if the center
333
+ // point is outside the floating element's bounds.
350
334
  const min = paddingObject[minProp];
351
335
  const max = clientSize - arrowDimensions[length] - paddingObject[maxProp];
352
336
  const center = clientSize / 2 - arrowDimensions[length] / 2 + centerToReference;
353
- const offset = within(min, center, max); // Make sure that arrow points at the reference
337
+ const offset = within(min, center, max);
354
338
 
355
- const alignmentPadding = alignment === 'start' ? paddingObject[minProp] : paddingObject[maxProp];
356
- const shouldAddOffset = alignmentPadding > 0 && center !== offset && rects.reference[length] <= rects.floating[length];
339
+ // If the reference is small enough that the arrow's padding causes it to
340
+ // to point to nothing for an aligned placement, adjust the offset of the
341
+ // floating element itself. This stops `shift()` from taking action, but can
342
+ // be worked around by calling it again after the `arrow()` if desired.
343
+ const shouldAddOffset = getAlignment(placement) != null && center != offset && rects.reference[length] / 2 - (center < min ? paddingObject[minProp] : paddingObject[maxProp]) - arrowDimensions[length] / 2 < 0;
357
344
  const alignmentOffset = shouldAddOffset ? center < min ? min - center : max - center : 0;
358
345
  return {
359
346
  [axis]: coords[axis] - alignmentOffset,
@@ -363,61 +350,55 @@ const arrow = options => ({
363
350
  }
364
351
  };
365
352
  }
366
-
367
353
  });
368
354
 
369
- const hash$1 = {
355
+ const sides = ['top', 'right', 'bottom', 'left'];
356
+ const allPlacements = /*#__PURE__*/sides.reduce((acc, side) => acc.concat(side, side + "-start", side + "-end"), []);
357
+
358
+ const oppositeSideMap = {
370
359
  left: 'right',
371
360
  right: 'left',
372
361
  bottom: 'top',
373
362
  top: 'bottom'
374
363
  };
375
364
  function getOppositePlacement(placement) {
376
- return placement.replace(/left|right|bottom|top/g, matched => hash$1[matched]);
365
+ return placement.replace(/left|right|bottom|top/g, side => oppositeSideMap[side]);
377
366
  }
378
367
 
379
368
  function getAlignmentSides(placement, rects, rtl) {
380
369
  if (rtl === void 0) {
381
370
  rtl = false;
382
371
  }
383
-
384
372
  const alignment = getAlignment(placement);
385
373
  const mainAxis = getMainAxisFromPlacement(placement);
386
374
  const length = getLengthFromAxis(mainAxis);
387
375
  let mainAlignmentSide = mainAxis === 'x' ? alignment === (rtl ? 'end' : 'start') ? 'right' : 'left' : alignment === 'start' ? 'bottom' : 'top';
388
-
389
376
  if (rects.reference[length] > rects.floating[length]) {
390
377
  mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
391
378
  }
392
-
393
379
  return {
394
380
  main: mainAlignmentSide,
395
381
  cross: getOppositePlacement(mainAlignmentSide)
396
382
  };
397
383
  }
398
384
 
399
- const hash = {
385
+ const oppositeAlignmentMap = {
400
386
  start: 'end',
401
387
  end: 'start'
402
388
  };
403
389
  function getOppositeAlignmentPlacement(placement) {
404
- return placement.replace(/start|end/g, matched => hash[matched]);
390
+ return placement.replace(/start|end/g, alignment => oppositeAlignmentMap[alignment]);
405
391
  }
406
392
 
407
- const sides = ['top', 'right', 'bottom', 'left'];
408
- const allPlacements = /*#__PURE__*/sides.reduce((acc, side) => acc.concat(side, side + "-start", side + "-end"), []);
409
-
410
393
  function getPlacementList(alignment, autoAlignment, allowedPlacements) {
411
394
  const allowedPlacementsSortedByAlignment = alignment ? [...allowedPlacements.filter(placement => getAlignment(placement) === alignment), ...allowedPlacements.filter(placement => getAlignment(placement) !== alignment)] : allowedPlacements.filter(placement => getSide(placement) === placement);
412
395
  return allowedPlacementsSortedByAlignment.filter(placement => {
413
396
  if (alignment) {
414
397
  return getAlignment(placement) === alignment || (autoAlignment ? getOppositeAlignmentPlacement(placement) !== placement : false);
415
398
  }
416
-
417
399
  return true;
418
400
  });
419
401
  }
420
-
421
402
  /**
422
403
  * Automatically chooses the `placement` which has the most space available.
423
404
  * @see https://floating-ui.com/docs/autoPlacement
@@ -426,17 +407,12 @@ const autoPlacement = function (options) {
426
407
  if (options === void 0) {
427
408
  options = {};
428
409
  }
429
-
430
410
  return {
431
411
  name: 'autoPlacement',
432
412
  options,
433
-
434
413
  async fn(middlewareArguments) {
435
- var _middlewareData$autoP, _middlewareData$autoP2, _middlewareData$autoP3, _middlewareData$autoP4, _placementsSortedByLe;
436
-
414
+ var _middlewareData$autoP, _middlewareData$autoP2, _placementsSortedByLe;
437
415
  const {
438
- x,
439
- y,
440
416
  rects,
441
417
  middlewareData,
442
418
  placement,
@@ -444,42 +420,39 @@ const autoPlacement = function (options) {
444
420
  elements
445
421
  } = middlewareArguments;
446
422
  const {
447
- alignment = null,
423
+ alignment,
448
424
  allowedPlacements = allPlacements,
449
425
  autoAlignment = true,
450
426
  ...detectOverflowOptions
451
427
  } = options;
452
- const placements = getPlacementList(alignment, autoAlignment, allowedPlacements);
428
+ const placements = alignment !== undefined || allowedPlacements === allPlacements ? getPlacementList(alignment || null, autoAlignment, allowedPlacements) : allowedPlacements;
453
429
  const overflow = await detectOverflow(middlewareArguments, detectOverflowOptions);
454
- const currentIndex = (_middlewareData$autoP = (_middlewareData$autoP2 = middlewareData.autoPlacement) == null ? void 0 : _middlewareData$autoP2.index) != null ? _middlewareData$autoP : 0;
430
+ const currentIndex = ((_middlewareData$autoP = middlewareData.autoPlacement) == null ? void 0 : _middlewareData$autoP.index) || 0;
455
431
  const currentPlacement = placements[currentIndex];
456
-
457
432
  if (currentPlacement == null) {
458
433
  return {};
459
434
  }
460
-
461
435
  const {
462
436
  main,
463
437
  cross
464
- } = getAlignmentSides(currentPlacement, rects, await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating))); // Make `computeCoords` start from the right place
438
+ } = getAlignmentSides(currentPlacement, rects, await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating)));
465
439
 
440
+ // Make `computeCoords` start from the right place.
466
441
  if (placement !== currentPlacement) {
467
442
  return {
468
- x,
469
- y,
470
443
  reset: {
471
444
  placement: placements[0]
472
445
  }
473
446
  };
474
447
  }
475
-
476
448
  const currentOverflows = [overflow[getSide(currentPlacement)], overflow[main], overflow[cross]];
477
- const allOverflows = [...((_middlewareData$autoP3 = (_middlewareData$autoP4 = middlewareData.autoPlacement) == null ? void 0 : _middlewareData$autoP4.overflows) != null ? _middlewareData$autoP3 : []), {
449
+ const allOverflows = [...(((_middlewareData$autoP2 = middlewareData.autoPlacement) == null ? void 0 : _middlewareData$autoP2.overflows) || []), {
478
450
  placement: currentPlacement,
479
451
  overflows: currentOverflows
480
452
  }];
481
- const nextPlacement = placements[currentIndex + 1]; // There are more placements to check
453
+ const nextPlacement = placements[currentIndex + 1];
482
454
 
455
+ // There are more placements to check.
483
456
  if (nextPlacement) {
484
457
  return {
485
458
  data: {
@@ -491,7 +464,6 @@ const autoPlacement = function (options) {
491
464
  }
492
465
  };
493
466
  }
494
-
495
467
  const placementsSortedByLeastOverflow = allOverflows.slice().sort((a, b) => a.overflows[0] - b.overflows[0]);
496
468
  const placementThatFitsOnAllSides = (_placementsSortedByLe = placementsSortedByLeastOverflow.find(_ref => {
497
469
  let {
@@ -499,8 +471,7 @@ const autoPlacement = function (options) {
499
471
  } = _ref;
500
472
  return overflows.every(overflow => overflow <= 0);
501
473
  })) == null ? void 0 : _placementsSortedByLe.placement;
502
- const resetPlacement = placementThatFitsOnAllSides != null ? placementThatFitsOnAllSides : placementsSortedByLeastOverflow[0].placement;
503
-
474
+ const resetPlacement = placementThatFitsOnAllSides || placementsSortedByLeastOverflow[0].placement;
504
475
  if (resetPlacement !== placement) {
505
476
  return {
506
477
  data: {
@@ -512,10 +483,8 @@ const autoPlacement = function (options) {
512
483
  }
513
484
  };
514
485
  }
515
-
516
486
  return {};
517
487
  }
518
-
519
488
  };
520
489
  };
521
490
 
@@ -524,6 +493,35 @@ function getExpandedPlacements(placement) {
524
493
  return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
525
494
  }
526
495
 
496
+ function getSideList(side, isStart, rtl) {
497
+ const lr = ['left', 'right'];
498
+ const rl = ['right', 'left'];
499
+ const tb = ['top', 'bottom'];
500
+ const bt = ['bottom', 'top'];
501
+ switch (side) {
502
+ case 'top':
503
+ case 'bottom':
504
+ if (rtl) return isStart ? rl : lr;
505
+ return isStart ? lr : rl;
506
+ case 'left':
507
+ case 'right':
508
+ return isStart ? tb : bt;
509
+ default:
510
+ return [];
511
+ }
512
+ }
513
+ function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
514
+ const alignment = getAlignment(placement);
515
+ let list = getSideList(getSide(placement), direction === 'start', rtl);
516
+ if (alignment) {
517
+ list = list.map(side => side + "-" + alignment);
518
+ if (flipAlignment) {
519
+ list = list.concat(list.map(getOppositeAlignmentPlacement));
520
+ }
521
+ }
522
+ return list;
523
+ }
524
+
527
525
  /**
528
526
  * Changes the placement of the floating element to one that will fit if the
529
527
  * initially specified `placement` does not.
@@ -533,14 +531,11 @@ const flip = function (options) {
533
531
  if (options === void 0) {
534
532
  options = {};
535
533
  }
536
-
537
534
  return {
538
535
  name: 'flip',
539
536
  options,
540
-
541
537
  async fn(middlewareArguments) {
542
538
  var _middlewareData$flip;
543
-
544
539
  const {
545
540
  placement,
546
541
  middlewareData,
@@ -554,42 +549,43 @@ const flip = function (options) {
554
549
  crossAxis: checkCrossAxis = true,
555
550
  fallbackPlacements: specifiedFallbackPlacements,
556
551
  fallbackStrategy = 'bestFit',
552
+ fallbackAxisSideDirection = 'none',
557
553
  flipAlignment = true,
558
554
  ...detectOverflowOptions
559
555
  } = options;
560
556
  const side = getSide(placement);
561
- const isBasePlacement = side === initialPlacement;
557
+ const isBasePlacement = getSide(initialPlacement) === initialPlacement;
558
+ const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating));
562
559
  const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement));
560
+ if (!specifiedFallbackPlacements && fallbackAxisSideDirection !== 'none') {
561
+ fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));
562
+ }
563
563
  const placements = [initialPlacement, ...fallbackPlacements];
564
564
  const overflow = await detectOverflow(middlewareArguments, detectOverflowOptions);
565
565
  const overflows = [];
566
566
  let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
567
-
568
567
  if (checkMainAxis) {
569
568
  overflows.push(overflow[side]);
570
569
  }
571
-
572
570
  if (checkCrossAxis) {
573
571
  const {
574
572
  main,
575
573
  cross
576
- } = getAlignmentSides(placement, rects, await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating)));
574
+ } = getAlignmentSides(placement, rects, rtl);
577
575
  overflows.push(overflow[main], overflow[cross]);
578
576
  }
579
-
580
577
  overflowsData = [...overflowsData, {
581
578
  placement,
582
579
  overflows
583
- }]; // One or more sides is overflowing
580
+ }];
584
581
 
582
+ // One or more sides is overflowing.
585
583
  if (!overflows.every(side => side <= 0)) {
586
- var _middlewareData$flip$, _middlewareData$flip2;
587
-
588
- const nextIndex = ((_middlewareData$flip$ = (_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) != null ? _middlewareData$flip$ : 0) + 1;
584
+ var _middlewareData$flip2, _overflowsData$find;
585
+ const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;
589
586
  const nextPlacement = placements[nextIndex];
590
-
591
587
  if (nextPlacement) {
592
- // Try next placement and re-run the lifecycle
588
+ // Try next placement and re-run the lifecycle.
593
589
  return {
594
590
  data: {
595
591
  index: nextIndex,
@@ -601,27 +597,26 @@ const flip = function (options) {
601
597
  };
602
598
  }
603
599
 
604
- let resetPlacement = 'bottom';
605
-
606
- switch (fallbackStrategy) {
607
- case 'bestFit':
608
- {
609
- var _overflowsData$map$so;
610
-
611
- const placement = (_overflowsData$map$so = overflowsData.map(d => [d, d.overflows.filter(overflow => overflow > 0).reduce((acc, overflow) => acc + overflow, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$map$so[0].placement;
612
-
613
- if (placement) {
614
- resetPlacement = placement;
600
+ // First, try to use the one that fits on mainAxis side of overflow.
601
+ let resetPlacement = (_overflowsData$find = overflowsData.find(d => d.overflows[0] <= 0)) == null ? void 0 : _overflowsData$find.placement;
602
+
603
+ // Otherwise fallback.
604
+ if (!resetPlacement) {
605
+ switch (fallbackStrategy) {
606
+ case 'bestFit':
607
+ {
608
+ var _overflowsData$map$so;
609
+ const placement = (_overflowsData$map$so = overflowsData.map(d => [d.placement, d.overflows.filter(overflow => overflow > 0).reduce((acc, overflow) => acc + overflow, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$map$so[0];
610
+ if (placement) {
611
+ resetPlacement = placement;
612
+ }
613
+ break;
615
614
  }
616
-
615
+ case 'initialPlacement':
616
+ resetPlacement = initialPlacement;
617
617
  break;
618
- }
619
-
620
- case 'initialPlacement':
621
- resetPlacement = initialPlacement;
622
- break;
618
+ }
623
619
  }
624
-
625
620
  if (placement !== resetPlacement) {
626
621
  return {
627
622
  reset: {
@@ -630,10 +625,115 @@ const flip = function (options) {
630
625
  };
631
626
  }
632
627
  }
633
-
634
628
  return {};
635
629
  }
630
+ };
631
+ };
632
+
633
+ /**
634
+ * Provides improved positioning for inline reference elements that can span
635
+ * over multiple lines, such as hyperlinks or range selections.
636
+ * @see https://floating-ui.com/docs/inline
637
+ */
638
+ const inline = function (options) {
639
+ if (options === void 0) {
640
+ options = {};
641
+ }
642
+ return {
643
+ name: 'inline',
644
+ options,
645
+ async fn(middlewareArguments) {
646
+ const {
647
+ placement,
648
+ elements,
649
+ rects,
650
+ platform,
651
+ strategy
652
+ } = middlewareArguments;
653
+ // A MouseEvent's client{X,Y} coords can be up to 2 pixels off a
654
+ // ClientRect's bounds, despite the event listener being triggered. A
655
+ // padding of 2 seems to handle this issue.
656
+ const {
657
+ padding = 2,
658
+ x,
659
+ y
660
+ } = options;
661
+ const fallback = rectToClientRect(platform.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform.convertOffsetParentRelativeRectToViewportRelativeRect({
662
+ rect: rects.reference,
663
+ offsetParent: await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating)),
664
+ strategy
665
+ }) : rects.reference);
666
+ const clientRects = (await (platform.getClientRects == null ? void 0 : platform.getClientRects(elements.reference))) || [];
667
+ const paddingObject = getSideObjectFromPadding(padding);
668
+ function getBoundingClientRect() {
669
+ // There are two rects and they are disjoined.
670
+ if (clientRects.length === 2 && clientRects[0].left > clientRects[1].right && x != null && y != null) {
671
+ // Find the first rect in which the point is fully inside.
672
+ return clientRects.find(rect => x > rect.left - paddingObject.left && x < rect.right + paddingObject.right && y > rect.top - paddingObject.top && y < rect.bottom + paddingObject.bottom) || fallback;
673
+ }
636
674
 
675
+ // There are 2 or more connected rects.
676
+ if (clientRects.length >= 2) {
677
+ if (getMainAxisFromPlacement(placement) === 'x') {
678
+ const firstRect = clientRects[0];
679
+ const lastRect = clientRects[clientRects.length - 1];
680
+ const isTop = getSide(placement) === 'top';
681
+ const top = firstRect.top;
682
+ const bottom = lastRect.bottom;
683
+ const left = isTop ? firstRect.left : lastRect.left;
684
+ const right = isTop ? firstRect.right : lastRect.right;
685
+ const width = right - left;
686
+ const height = bottom - top;
687
+ return {
688
+ top,
689
+ bottom,
690
+ left,
691
+ right,
692
+ width,
693
+ height,
694
+ x: left,
695
+ y: top
696
+ };
697
+ }
698
+ const isLeftSide = getSide(placement) === 'left';
699
+ const maxRight = max$1(...clientRects.map(rect => rect.right));
700
+ const minLeft = min$1(...clientRects.map(rect => rect.left));
701
+ const measureRects = clientRects.filter(rect => isLeftSide ? rect.left === minLeft : rect.right === maxRight);
702
+ const top = measureRects[0].top;
703
+ const bottom = measureRects[measureRects.length - 1].bottom;
704
+ const left = minLeft;
705
+ const right = maxRight;
706
+ const width = right - left;
707
+ const height = bottom - top;
708
+ return {
709
+ top,
710
+ bottom,
711
+ left,
712
+ right,
713
+ width,
714
+ height,
715
+ x: left,
716
+ y: top
717
+ };
718
+ }
719
+ return fallback;
720
+ }
721
+ const resetRects = await platform.getElementRects({
722
+ reference: {
723
+ getBoundingClientRect
724
+ },
725
+ floating: elements.floating,
726
+ strategy
727
+ });
728
+ if (rects.reference.x !== resetRects.reference.x || rects.reference.y !== resetRects.reference.y || rects.reference.width !== resetRects.reference.width || rects.reference.height !== resetRects.reference.height) {
729
+ return {
730
+ reset: {
731
+ rects: resetRects
732
+ }
733
+ };
734
+ }
735
+ return {};
736
+ }
637
737
  };
638
738
  };
639
739
 
@@ -649,8 +749,9 @@ async function convertValueToCoords(middlewareArguments, value) {
649
749
  const isVertical = getMainAxisFromPlacement(placement) === 'x';
650
750
  const mainAxisMulti = ['left', 'top'].includes(side) ? -1 : 1;
651
751
  const crossAxisMulti = rtl && isVertical ? -1 : 1;
652
- const rawValue = typeof value === 'function' ? value(middlewareArguments) : value; // eslint-disable-next-line prefer-const
752
+ const rawValue = typeof value === 'function' ? value(middlewareArguments) : value;
653
753
 
754
+ // eslint-disable-next-line prefer-const
654
755
  let {
655
756
  mainAxis,
656
757
  crossAxis,
@@ -665,11 +766,9 @@ async function convertValueToCoords(middlewareArguments, value) {
665
766
  alignmentAxis: null,
666
767
  ...rawValue
667
768
  };
668
-
669
769
  if (alignment && typeof alignmentAxis === 'number') {
670
770
  crossAxis = alignment === 'end' ? alignmentAxis * -1 : alignmentAxis;
671
771
  }
672
-
673
772
  return isVertical ? {
674
773
  x: crossAxis * crossAxisMulti,
675
774
  y: mainAxis * mainAxisMulti
@@ -678,20 +777,18 @@ async function convertValueToCoords(middlewareArguments, value) {
678
777
  y: crossAxis * crossAxisMulti
679
778
  };
680
779
  }
780
+
681
781
  /**
682
782
  * Displaces the floating element from its reference element.
683
783
  * @see https://floating-ui.com/docs/offset
684
784
  */
685
-
686
785
  const offset = function (value) {
687
786
  if (value === void 0) {
688
787
  value = 0;
689
788
  }
690
-
691
789
  return {
692
790
  name: 'offset',
693
791
  options: value,
694
-
695
792
  async fn(middlewareArguments) {
696
793
  const {
697
794
  x,
@@ -704,7 +801,6 @@ const offset = function (value) {
704
801
  data: diffCoords
705
802
  };
706
803
  }
707
-
708
804
  };
709
805
  };
710
806
 
@@ -721,11 +817,9 @@ const shift = function (options) {
721
817
  if (options === void 0) {
722
818
  options = {};
723
819
  }
724
-
725
820
  return {
726
821
  name: 'shift',
727
822
  options,
728
-
729
823
  async fn(middlewareArguments) {
730
824
  const {
731
825
  x,
@@ -758,7 +852,6 @@ const shift = function (options) {
758
852
  const crossAxis = getCrossAxis(mainAxis);
759
853
  let mainAxisCoord = coords[mainAxis];
760
854
  let crossAxisCoord = coords[crossAxis];
761
-
762
855
  if (checkMainAxis) {
763
856
  const minSide = mainAxis === 'y' ? 'top' : 'left';
764
857
  const maxSide = mainAxis === 'y' ? 'bottom' : 'right';
@@ -766,7 +859,6 @@ const shift = function (options) {
766
859
  const max = mainAxisCoord - overflow[maxSide];
767
860
  mainAxisCoord = within(min, mainAxisCoord, max);
768
861
  }
769
-
770
862
  if (checkCrossAxis) {
771
863
  const minSide = crossAxis === 'y' ? 'top' : 'left';
772
864
  const maxSide = crossAxis === 'y' ? 'bottom' : 'right';
@@ -774,19 +866,19 @@ const shift = function (options) {
774
866
  const max = crossAxisCoord - overflow[maxSide];
775
867
  crossAxisCoord = within(min, crossAxisCoord, max);
776
868
  }
777
-
778
- const limitedCoords = limiter.fn({ ...middlewareArguments,
869
+ const limitedCoords = limiter.fn({
870
+ ...middlewareArguments,
779
871
  [mainAxis]: mainAxisCoord,
780
872
  [crossAxis]: crossAxisCoord
781
873
  });
782
- return { ...limitedCoords,
874
+ return {
875
+ ...limitedCoords,
783
876
  data: {
784
877
  x: limitedCoords.x - x,
785
878
  y: limitedCoords.y - y
786
879
  }
787
880
  };
788
881
  }
789
-
790
882
  };
791
883
  };
792
884
 
@@ -800,11 +892,9 @@ const size = function (options) {
800
892
  if (options === void 0) {
801
893
  options = {};
802
894
  }
803
-
804
895
  return {
805
896
  name: 'size',
806
897
  options,
807
-
808
898
  async fn(middlewareArguments) {
809
899
  const {
810
900
  placement,
@@ -821,7 +911,6 @@ const size = function (options) {
821
911
  const alignment = getAlignment(placement);
822
912
  let heightSide;
823
913
  let widthSide;
824
-
825
914
  if (side === 'top' || side === 'bottom') {
826
915
  heightSide = side;
827
916
  widthSide = alignment === ((await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating))) ? 'start' : 'end') ? 'left' : 'right';
@@ -829,7 +918,6 @@ const size = function (options) {
829
918
  widthSide = side;
830
919
  heightSide = alignment === 'end' ? 'top' : 'bottom';
831
920
  }
832
-
833
921
  const xMin = max$1(overflow.left, 0);
834
922
  const xMax = max$1(overflow.right, 0);
835
923
  const yMin = max$1(overflow.top, 0);
@@ -838,11 +926,11 @@ const size = function (options) {
838
926
  availableHeight: rects.floating.height - (['left', 'right'].includes(placement) ? 2 * (yMin !== 0 || yMax !== 0 ? yMin + yMax : max$1(overflow.top, overflow.bottom)) : overflow[heightSide]),
839
927
  availableWidth: rects.floating.width - (['top', 'bottom'].includes(placement) ? 2 * (xMin !== 0 || xMax !== 0 ? xMin + xMax : max$1(overflow.left, overflow.right)) : overflow[widthSide])
840
928
  };
841
- await apply({ ...middlewareArguments,
929
+ await apply({
930
+ ...middlewareArguments,
842
931
  ...dimensions
843
932
  });
844
933
  const nextDimensions = await platform.getDimensions(elements.floating);
845
-
846
934
  if (rects.floating.width !== nextDimensions.width || rects.floating.height !== nextDimensions.height) {
847
935
  return {
848
936
  reset: {
@@ -850,164 +938,56 @@ const size = function (options) {
850
938
  }
851
939
  };
852
940
  }
853
-
854
941
  return {};
855
942
  }
856
-
857
943
  };
858
944
  };
859
945
 
860
- /**
861
- * Provides improved positioning for inline reference elements that can span
862
- * over multiple lines, such as hyperlinks or range selections.
863
- * @see https://floating-ui.com/docs/inline
864
- */
865
- const inline = function (options) {
866
- if (options === void 0) {
867
- options = {};
868
- }
946
+ function getWindow(node) {
947
+ var _node$ownerDocument;
948
+ return ((_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
949
+ }
869
950
 
870
- return {
871
- name: 'inline',
872
- options,
951
+ function getComputedStyle$1(element) {
952
+ return getWindow(element).getComputedStyle(element);
953
+ }
873
954
 
874
- async fn(middlewareArguments) {
875
- var _await$platform$getCl;
955
+ const min = Math.min;
956
+ const max = Math.max;
957
+ const round = Math.round;
876
958
 
877
- const {
878
- placement,
879
- elements,
880
- rects,
881
- platform,
882
- strategy
883
- } = middlewareArguments; // A MouseEvent's client{X,Y} coords can be up to 2 pixels off a
884
- // ClientRect's bounds, despite the event listener being triggered. A
885
- // padding of 2 seems to handle this issue.
886
-
887
- const {
888
- padding = 2,
889
- x,
890
- y
891
- } = options;
892
- const fallback = rectToClientRect(platform.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform.convertOffsetParentRelativeRectToViewportRelativeRect({
893
- rect: rects.reference,
894
- offsetParent: await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating)),
895
- strategy
896
- }) : rects.reference);
897
- const clientRects = (_await$platform$getCl = await (platform.getClientRects == null ? void 0 : platform.getClientRects(elements.reference))) != null ? _await$platform$getCl : [];
898
- const paddingObject = getSideObjectFromPadding(padding);
899
-
900
- function getBoundingClientRect() {
901
- // There are two rects and they are disjoined
902
- if (clientRects.length === 2 && clientRects[0].left > clientRects[1].right && x != null && y != null) {
903
- var _clientRects$find;
904
-
905
- // Find the first rect in which the point is fully inside
906
- return (_clientRects$find = clientRects.find(rect => x > rect.left - paddingObject.left && x < rect.right + paddingObject.right && y > rect.top - paddingObject.top && y < rect.bottom + paddingObject.bottom)) != null ? _clientRects$find : fallback;
907
- } // There are 2 or more connected rects
908
-
909
-
910
- if (clientRects.length >= 2) {
911
- if (getMainAxisFromPlacement(placement) === 'x') {
912
- const firstRect = clientRects[0];
913
- const lastRect = clientRects[clientRects.length - 1];
914
- const isTop = getSide(placement) === 'top';
915
- const top = firstRect.top;
916
- const bottom = lastRect.bottom;
917
- const left = isTop ? firstRect.left : lastRect.left;
918
- const right = isTop ? firstRect.right : lastRect.right;
919
- const width = right - left;
920
- const height = bottom - top;
921
- return {
922
- top,
923
- bottom,
924
- left,
925
- right,
926
- width,
927
- height,
928
- x: left,
929
- y: top
930
- };
931
- }
932
-
933
- const isLeftSide = getSide(placement) === 'left';
934
- const maxRight = max$1(...clientRects.map(rect => rect.right));
935
- const minLeft = min$1(...clientRects.map(rect => rect.left));
936
- const measureRects = clientRects.filter(rect => isLeftSide ? rect.left === minLeft : rect.right === maxRight);
937
- const top = measureRects[0].top;
938
- const bottom = measureRects[measureRects.length - 1].bottom;
939
- const left = minLeft;
940
- const right = maxRight;
941
- const width = right - left;
942
- const height = bottom - top;
943
- return {
944
- top,
945
- bottom,
946
- left,
947
- right,
948
- width,
949
- height,
950
- x: left,
951
- y: top
952
- };
953
- }
954
-
955
- return fallback;
956
- }
957
-
958
- const resetRects = await platform.getElementRects({
959
- reference: {
960
- getBoundingClientRect
961
- },
962
- floating: elements.floating,
963
- strategy
964
- });
965
-
966
- if (rects.reference.x !== resetRects.reference.x || rects.reference.y !== resetRects.reference.y || rects.reference.width !== resetRects.reference.width || rects.reference.height !== resetRects.reference.height) {
967
- return {
968
- reset: {
969
- rects: resetRects
970
- }
971
- };
972
- }
973
-
974
- return {};
975
- }
976
-
977
- };
978
- };
979
-
980
- function isWindow(value) {
981
- return value && value.document && value.location && value.alert && value.setInterval;
982
- }
983
- function getWindow(node) {
984
- if (node == null) {
985
- return window;
959
+ function getCssDimensions(element) {
960
+ const css = getComputedStyle$1(element);
961
+ let width = parseFloat(css.width);
962
+ let height = parseFloat(css.height);
963
+ const offsetWidth = element.offsetWidth;
964
+ const offsetHeight = element.offsetHeight;
965
+ const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
966
+ if (shouldFallback) {
967
+ width = offsetWidth;
968
+ height = offsetHeight;
986
969
  }
987
-
988
- if (!isWindow(node)) {
989
- const ownerDocument = node.ownerDocument;
990
- return ownerDocument ? ownerDocument.defaultView || window : window;
991
- }
992
-
993
- return node;
994
- }
995
-
996
- function getComputedStyle(element) {
997
- return getWindow(element).getComputedStyle(element);
970
+ return {
971
+ width,
972
+ height,
973
+ fallback: shouldFallback
974
+ };
998
975
  }
999
976
 
1000
977
  function getNodeName(node) {
1001
- return isWindow(node) ? '' : node ? (node.nodeName || '').toLowerCase() : '';
978
+ return isNode(node) ? (node.nodeName || '').toLowerCase() : '';
1002
979
  }
1003
980
 
981
+ let uaString;
1004
982
  function getUAString() {
983
+ if (uaString) {
984
+ return uaString;
985
+ }
1005
986
  const uaData = navigator.userAgentData;
1006
-
1007
- if (uaData != null && uaData.brands) {
1008
- return uaData.brands.map(item => item.brand + "/" + item.version).join(' ');
987
+ if (uaData && Array.isArray(uaData.brands)) {
988
+ uaString = uaData.brands.map(item => item.brand + "/" + item.version).join(' ');
989
+ return uaString;
1009
990
  }
1010
-
1011
991
  return navigator.userAgent;
1012
992
  }
1013
993
 
@@ -1021,83 +1001,135 @@ function isNode(value) {
1021
1001
  return value instanceof getWindow(value).Node;
1022
1002
  }
1023
1003
  function isShadowRoot(node) {
1024
- // Browsers without `ShadowRoot` support
1004
+ // Browsers without `ShadowRoot` support.
1025
1005
  if (typeof ShadowRoot === 'undefined') {
1026
1006
  return false;
1027
1007
  }
1028
-
1029
1008
  const OwnElement = getWindow(node).ShadowRoot;
1030
1009
  return node instanceof OwnElement || node instanceof ShadowRoot;
1031
1010
  }
1032
1011
  function isOverflowElement(element) {
1033
- // Firefox wants us to check `-x` and `-y` variations as well
1034
1012
  const {
1035
1013
  overflow,
1036
1014
  overflowX,
1037
1015
  overflowY,
1038
1016
  display
1039
- } = getComputedStyle(element);
1040
- return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX) && !['inline', 'contents'].includes(display);
1017
+ } = getComputedStyle$1(element);
1018
+ return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !['inline', 'contents'].includes(display);
1041
1019
  }
1042
1020
  function isTableElement(element) {
1043
1021
  return ['table', 'td', 'th'].includes(getNodeName(element));
1044
1022
  }
1045
1023
  function isContainingBlock(element) {
1046
- // TODO: Try and use feature detection here instead
1024
+ // TODO: Try to use feature detection here instead.
1047
1025
  const isFirefox = /firefox/i.test(getUAString());
1048
- const css = getComputedStyle(element);
1049
- const backdropFilter = css.backdropFilter || css.WebkitBackdropFilter; // This is non-exhaustive but covers the most common CSS properties that
1026
+ const css = getComputedStyle$1(element);
1027
+ const backdropFilter = css.backdropFilter || css.WebkitBackdropFilter;
1028
+
1029
+ // This is non-exhaustive but covers the most common CSS properties that
1050
1030
  // create a containing block.
1051
1031
  // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
1052
-
1053
- return css.transform !== 'none' || css.perspective !== 'none' || (backdropFilter ? backdropFilter !== 'none' : false) || isFirefox && css.willChange === 'filter' || isFirefox && (css.filter ? css.filter !== 'none' : false) || ['transform', 'perspective'].some(value => css.willChange.includes(value)) || ['paint', 'layout', 'strict', 'content'].some( // TS 4.1 compat
1054
- value => {
1032
+ return css.transform !== 'none' || css.perspective !== 'none' || (backdropFilter ? backdropFilter !== 'none' : false) || isFirefox && css.willChange === 'filter' || isFirefox && (css.filter ? css.filter !== 'none' : false) || ['transform', 'perspective'].some(value => css.willChange.includes(value)) || ['paint', 'layout', 'strict', 'content'].some(value => {
1033
+ // Add type check for old browsers.
1055
1034
  const contain = css.contain;
1056
1035
  return contain != null ? contain.includes(value) : false;
1057
1036
  });
1058
1037
  }
1059
1038
  function isLayoutViewport() {
1060
- // Not Safari
1061
- return !/^((?!chrome|android).)*safari/i.test(getUAString()); // Feature detection for this fails in various ways
1039
+ // TODO: Try to use feature detection here instead. Feature detection for
1040
+ // this can fail in various ways, making the userAgent check the most:
1041
+ // reliable:
1062
1042
  // • Always-visible scrollbar or not
1063
- // • Width of <html>, etc.
1064
- // const vV = win.visualViewport;
1065
- // return vV ? Math.abs(win.innerWidth / vV.scale - vV.width) < 0.5 : true;
1043
+ // • Width of <html>
1044
+
1045
+ // Not Safari.
1046
+ return !/^((?!chrome|android).)*safari/i.test(getUAString());
1066
1047
  }
1067
1048
  function isLastTraversableNode(node) {
1068
1049
  return ['html', 'body', '#document'].includes(getNodeName(node));
1069
1050
  }
1070
1051
 
1071
- const min = Math.min;
1072
- const max = Math.max;
1073
- const round = Math.round;
1052
+ function unwrapElement(element) {
1053
+ return !isElement(element) ? element.contextElement : element;
1054
+ }
1074
1055
 
1075
- function getBoundingClientRect(element, includeScale, isFixedStrategy) {
1076
- var _win$visualViewport$o, _win$visualViewport, _win$visualViewport$o2, _win$visualViewport2;
1056
+ const FALLBACK_SCALE = {
1057
+ x: 1,
1058
+ y: 1
1059
+ };
1060
+ function getScale(element) {
1061
+ const domElement = unwrapElement(element);
1062
+ if (!isHTMLElement(domElement)) {
1063
+ return FALLBACK_SCALE;
1064
+ }
1065
+ const rect = domElement.getBoundingClientRect();
1066
+ const {
1067
+ width,
1068
+ height,
1069
+ fallback
1070
+ } = getCssDimensions(domElement);
1071
+ let x = (fallback ? round(rect.width) : rect.width) / width;
1072
+ let y = (fallback ? round(rect.height) : rect.height) / height;
1077
1073
 
1074
+ // 0, NaN, or Infinity should always fallback to 1.
1075
+
1076
+ if (!x || !Number.isFinite(x)) {
1077
+ x = 1;
1078
+ }
1079
+ if (!y || !Number.isFinite(y)) {
1080
+ y = 1;
1081
+ }
1082
+ return {
1083
+ x,
1084
+ y
1085
+ };
1086
+ }
1087
+
1088
+ function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
1089
+ var _win$visualViewport, _win$visualViewport2;
1078
1090
  if (includeScale === void 0) {
1079
1091
  includeScale = false;
1080
1092
  }
1081
-
1082
1093
  if (isFixedStrategy === void 0) {
1083
1094
  isFixedStrategy = false;
1084
1095
  }
1085
-
1086
1096
  const clientRect = element.getBoundingClientRect();
1087
- let scaleX = 1;
1088
- let scaleY = 1;
1089
-
1090
- if (includeScale && isHTMLElement(element)) {
1091
- scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;
1092
- scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;
1097
+ const domElement = unwrapElement(element);
1098
+ let scale = FALLBACK_SCALE;
1099
+ if (includeScale) {
1100
+ if (offsetParent) {
1101
+ if (isElement(offsetParent)) {
1102
+ scale = getScale(offsetParent);
1103
+ }
1104
+ } else {
1105
+ scale = getScale(element);
1106
+ }
1093
1107
  }
1094
-
1095
- const win = isElement(element) ? getWindow(element) : window;
1108
+ const win = domElement ? getWindow(domElement) : window;
1096
1109
  const addVisualOffsets = !isLayoutViewport() && isFixedStrategy;
1097
- const x = (clientRect.left + (addVisualOffsets ? (_win$visualViewport$o = (_win$visualViewport = win.visualViewport) == null ? void 0 : _win$visualViewport.offsetLeft) != null ? _win$visualViewport$o : 0 : 0)) / scaleX;
1098
- const y = (clientRect.top + (addVisualOffsets ? (_win$visualViewport$o2 = (_win$visualViewport2 = win.visualViewport) == null ? void 0 : _win$visualViewport2.offsetTop) != null ? _win$visualViewport$o2 : 0 : 0)) / scaleY;
1099
- const width = clientRect.width / scaleX;
1100
- const height = clientRect.height / scaleY;
1110
+ let x = (clientRect.left + (addVisualOffsets ? ((_win$visualViewport = win.visualViewport) == null ? void 0 : _win$visualViewport.offsetLeft) || 0 : 0)) / scale.x;
1111
+ let y = (clientRect.top + (addVisualOffsets ? ((_win$visualViewport2 = win.visualViewport) == null ? void 0 : _win$visualViewport2.offsetTop) || 0 : 0)) / scale.y;
1112
+ let width = clientRect.width / scale.x;
1113
+ let height = clientRect.height / scale.y;
1114
+ if (domElement) {
1115
+ const win = getWindow(domElement);
1116
+ const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
1117
+ let currentIFrame = win.frameElement;
1118
+ while (currentIFrame && offsetParent && offsetWin !== win) {
1119
+ const iframeScale = getScale(currentIFrame);
1120
+ const iframeRect = currentIFrame.getBoundingClientRect();
1121
+ const css = getComputedStyle(currentIFrame);
1122
+ iframeRect.x += (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
1123
+ iframeRect.y += (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
1124
+ x *= iframeScale.x;
1125
+ y *= iframeScale.y;
1126
+ width *= iframeScale.x;
1127
+ height *= iframeScale.y;
1128
+ x += iframeRect.x;
1129
+ y += iframeRect.y;
1130
+ currentIFrame = getWindow(currentIFrame).frameElement;
1131
+ }
1132
+ }
1101
1133
  return {
1102
1134
  width,
1103
1135
  height,
@@ -1121,127 +1153,12 @@ function getNodeScroll(element) {
1121
1153
  scrollTop: element.scrollTop
1122
1154
  };
1123
1155
  }
1124
-
1125
1156
  return {
1126
1157
  scrollLeft: element.pageXOffset,
1127
1158
  scrollTop: element.pageYOffset
1128
1159
  };
1129
1160
  }
1130
1161
 
1131
- function getWindowScrollBarX(element) {
1132
- // If <html> has a CSS width greater than the viewport, then this will be
1133
- // incorrect for RTL.
1134
- return getBoundingClientRect(getDocumentElement(element)).left + getNodeScroll(element).scrollLeft;
1135
- }
1136
-
1137
- function isScaled(element) {
1138
- const rect = getBoundingClientRect(element);
1139
- return round(rect.width) !== element.offsetWidth || round(rect.height) !== element.offsetHeight;
1140
- }
1141
-
1142
- function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
1143
- const isOffsetParentAnElement = isHTMLElement(offsetParent);
1144
- const documentElement = getDocumentElement(offsetParent);
1145
- const rect = getBoundingClientRect(element, // @ts-ignore - checked above (TS 4.1 compat)
1146
- isOffsetParentAnElement && isScaled(offsetParent), strategy === 'fixed');
1147
- let scroll = {
1148
- scrollLeft: 0,
1149
- scrollTop: 0
1150
- };
1151
- const offsets = {
1152
- x: 0,
1153
- y: 0
1154
- };
1155
-
1156
- if (isOffsetParentAnElement || !isOffsetParentAnElement && strategy !== 'fixed') {
1157
- if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
1158
- scroll = getNodeScroll(offsetParent);
1159
- }
1160
-
1161
- if (isHTMLElement(offsetParent)) {
1162
- const offsetRect = getBoundingClientRect(offsetParent, true);
1163
- offsets.x = offsetRect.x + offsetParent.clientLeft;
1164
- offsets.y = offsetRect.y + offsetParent.clientTop;
1165
- } else if (documentElement) {
1166
- offsets.x = getWindowScrollBarX(documentElement);
1167
- }
1168
- }
1169
-
1170
- return {
1171
- x: rect.left + scroll.scrollLeft - offsets.x,
1172
- y: rect.top + scroll.scrollTop - offsets.y,
1173
- width: rect.width,
1174
- height: rect.height
1175
- };
1176
- }
1177
-
1178
- function getParentNode(node) {
1179
- if (getNodeName(node) === 'html') {
1180
- return node;
1181
- }
1182
-
1183
- const result = // Step into the shadow DOM of the parent of a slotted node
1184
- node.assignedSlot || // DOM Element detected
1185
- node.parentNode || ( // ShadowRoot detected
1186
- isShadowRoot(node) ? node.host : null) || // Fallback
1187
- getDocumentElement(node);
1188
- return isShadowRoot(result) ? result.host : result;
1189
- }
1190
-
1191
- function getTrueOffsetParent(element) {
1192
- if (!isHTMLElement(element) || getComputedStyle(element).position === 'fixed') {
1193
- return null;
1194
- }
1195
-
1196
- return element.offsetParent;
1197
- }
1198
-
1199
- function getContainingBlock(element) {
1200
- let currentNode = getParentNode(element);
1201
-
1202
- while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
1203
- if (isContainingBlock(currentNode)) {
1204
- return currentNode;
1205
- } else {
1206
- currentNode = getParentNode(currentNode);
1207
- }
1208
- }
1209
-
1210
- return null;
1211
- } // Gets the closest ancestor positioned element. Handles some edge cases,
1212
- // such as table ancestors and cross browser bugs.
1213
-
1214
-
1215
- function getOffsetParent(element) {
1216
- const window = getWindow(element);
1217
- let offsetParent = getTrueOffsetParent(element);
1218
-
1219
- while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') {
1220
- offsetParent = getTrueOffsetParent(offsetParent);
1221
- }
1222
-
1223
- if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static' && !isContainingBlock(offsetParent))) {
1224
- return window;
1225
- }
1226
-
1227
- return offsetParent || getContainingBlock(element) || window;
1228
- }
1229
-
1230
- function getDimensions(element) {
1231
- if (isHTMLElement(element)) {
1232
- return {
1233
- width: element.offsetWidth,
1234
- height: element.offsetHeight
1235
- };
1236
- }
1237
-
1238
- const rect = getBoundingClientRect(element);
1239
- return {
1240
- width: rect.width,
1241
- height: rect.height
1242
- };
1243
- }
1244
-
1245
1162
  function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
1246
1163
  let {
1247
1164
  rect,
@@ -1250,87 +1167,59 @@ function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
1250
1167
  } = _ref;
1251
1168
  const isOffsetParentAnElement = isHTMLElement(offsetParent);
1252
1169
  const documentElement = getDocumentElement(offsetParent);
1253
-
1254
1170
  if (offsetParent === documentElement) {
1255
1171
  return rect;
1256
1172
  }
1257
-
1258
1173
  let scroll = {
1259
1174
  scrollLeft: 0,
1260
1175
  scrollTop: 0
1261
1176
  };
1177
+ let scale = {
1178
+ x: 1,
1179
+ y: 1
1180
+ };
1262
1181
  const offsets = {
1263
1182
  x: 0,
1264
1183
  y: 0
1265
1184
  };
1266
-
1267
1185
  if (isOffsetParentAnElement || !isOffsetParentAnElement && strategy !== 'fixed') {
1268
1186
  if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
1269
1187
  scroll = getNodeScroll(offsetParent);
1270
1188
  }
1271
-
1272
1189
  if (isHTMLElement(offsetParent)) {
1273
- const offsetRect = getBoundingClientRect(offsetParent, true);
1190
+ const offsetRect = getBoundingClientRect(offsetParent);
1191
+ scale = getScale(offsetParent);
1274
1192
  offsets.x = offsetRect.x + offsetParent.clientLeft;
1275
1193
  offsets.y = offsetRect.y + offsetParent.clientTop;
1276
- } // This doesn't appear to be need to be negated.
1277
- // else if (documentElement) {
1278
- // offsets.x = getWindowScrollBarX(documentElement);
1279
- // }
1280
-
1281
- }
1282
-
1283
- return { ...rect,
1284
- x: rect.x - scroll.scrollLeft + offsets.x,
1285
- y: rect.y - scroll.scrollTop + offsets.y
1286
- };
1287
- }
1288
-
1289
- function getViewportRect(element, strategy) {
1290
- const win = getWindow(element);
1291
- const html = getDocumentElement(element);
1292
- const visualViewport = win.visualViewport;
1293
- let width = html.clientWidth;
1294
- let height = html.clientHeight;
1295
- let x = 0;
1296
- let y = 0;
1297
-
1298
- if (visualViewport) {
1299
- width = visualViewport.width;
1300
- height = visualViewport.height;
1301
- const layoutViewport = isLayoutViewport();
1302
-
1303
- if (layoutViewport || !layoutViewport && strategy === 'fixed') {
1304
- x = visualViewport.offsetLeft;
1305
- y = visualViewport.offsetTop;
1306
1194
  }
1307
1195
  }
1308
-
1309
1196
  return {
1310
- width,
1311
- height,
1312
- x,
1313
- y
1197
+ width: rect.width * scale.x,
1198
+ height: rect.height * scale.y,
1199
+ x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x,
1200
+ y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y
1314
1201
  };
1315
1202
  }
1316
1203
 
1317
- // of the `<html>` and `<body>` rect bounds if horizontally scrollable
1204
+ function getWindowScrollBarX(element) {
1205
+ // If <html> has a CSS width greater than the viewport, then this will be
1206
+ // incorrect for RTL.
1207
+ return getBoundingClientRect(getDocumentElement(element)).left + getNodeScroll(element).scrollLeft;
1208
+ }
1318
1209
 
1210
+ // Gets the entire size of the scrollable document area, even extending outside
1211
+ // of the `<html>` and `<body>` rect bounds if horizontally scrollable.
1319
1212
  function getDocumentRect(element) {
1320
- var _element$ownerDocumen;
1321
-
1322
1213
  const html = getDocumentElement(element);
1323
1214
  const scroll = getNodeScroll(element);
1324
- const body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;
1325
- const width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);
1326
- const height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);
1215
+ const body = element.ownerDocument.body;
1216
+ const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
1217
+ const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
1327
1218
  let x = -scroll.scrollLeft + getWindowScrollBarX(element);
1328
1219
  const y = -scroll.scrollTop;
1329
-
1330
- if (getComputedStyle(body || html).direction === 'rtl') {
1331
- x += max(html.clientWidth, body ? body.clientWidth : 0) - width;
1220
+ if (getComputedStyle$1(body).direction === 'rtl') {
1221
+ x += max(html.clientWidth, body.clientWidth) - width;
1332
1222
  }
1333
-
1334
1223
  return {
1335
1224
  width,
1336
1225
  height,
@@ -1339,92 +1228,137 @@ function getDocumentRect(element) {
1339
1228
  };
1340
1229
  }
1341
1230
 
1231
+ function getParentNode(node) {
1232
+ if (getNodeName(node) === 'html') {
1233
+ return node;
1234
+ }
1235
+ const result =
1236
+ // Step into the shadow DOM of the parent of a slotted node.
1237
+ node.assignedSlot ||
1238
+ // DOM Element detected.
1239
+ node.parentNode ||
1240
+ // ShadowRoot detected.
1241
+ isShadowRoot(node) && node.host ||
1242
+ // Fallback.
1243
+ getDocumentElement(node);
1244
+ return isShadowRoot(result) ? result.host : result;
1245
+ }
1246
+
1342
1247
  function getNearestOverflowAncestor(node) {
1343
1248
  const parentNode = getParentNode(node);
1344
-
1345
1249
  if (isLastTraversableNode(parentNode)) {
1346
- // @ts-ignore assume body is always available
1347
- return node.ownerDocument.body;
1250
+ // `getParentNode` will never return a `Document` due to the fallback
1251
+ // check, so it's either the <html> or <body> element.
1252
+ return parentNode.ownerDocument.body;
1348
1253
  }
1349
-
1350
1254
  if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
1351
1255
  return parentNode;
1352
1256
  }
1353
-
1354
1257
  return getNearestOverflowAncestor(parentNode);
1355
1258
  }
1356
1259
 
1357
1260
  function getOverflowAncestors(node, list) {
1358
1261
  var _node$ownerDocument;
1359
-
1360
1262
  if (list === void 0) {
1361
1263
  list = [];
1362
1264
  }
1363
-
1364
1265
  const scrollableAncestor = getNearestOverflowAncestor(node);
1365
1266
  const isBody = scrollableAncestor === ((_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.body);
1366
1267
  const win = getWindow(scrollableAncestor);
1367
- const target = isBody ? [win].concat(win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : []) : scrollableAncestor;
1368
- const updatedList = list.concat(target);
1369
- return isBody ? updatedList : // @ts-ignore: isBody tells us target will be an HTMLElement here
1370
- updatedList.concat(getOverflowAncestors(target));
1268
+ if (isBody) {
1269
+ return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : []);
1270
+ }
1271
+ return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor));
1272
+ }
1273
+
1274
+ function getViewportRect(element, strategy) {
1275
+ const win = getWindow(element);
1276
+ const html = getDocumentElement(element);
1277
+ const visualViewport = win.visualViewport;
1278
+ let width = html.clientWidth;
1279
+ let height = html.clientHeight;
1280
+ let x = 0;
1281
+ let y = 0;
1282
+ if (visualViewport) {
1283
+ width = visualViewport.width;
1284
+ height = visualViewport.height;
1285
+ const layoutViewport = isLayoutViewport();
1286
+ if (layoutViewport || !layoutViewport && strategy === 'fixed') {
1287
+ x = visualViewport.offsetLeft;
1288
+ y = visualViewport.offsetTop;
1289
+ }
1290
+ }
1291
+ return {
1292
+ width,
1293
+ height,
1294
+ x,
1295
+ y
1296
+ };
1371
1297
  }
1372
1298
 
1299
+ // Returns the inner client rect, subtracting scrollbars if present.
1373
1300
  function getInnerBoundingClientRect(element, strategy) {
1374
- const clientRect = getBoundingClientRect(element, false, strategy === 'fixed');
1301
+ const clientRect = getBoundingClientRect(element, true, strategy === 'fixed');
1375
1302
  const top = clientRect.top + element.clientTop;
1376
1303
  const left = clientRect.left + element.clientLeft;
1304
+ const scale = isHTMLElement(element) ? getScale(element) : {
1305
+ x: 1,
1306
+ y: 1
1307
+ };
1308
+ const width = element.clientWidth * scale.x;
1309
+ const height = element.clientHeight * scale.y;
1310
+ const x = left * scale.x;
1311
+ const y = top * scale.y;
1377
1312
  return {
1378
- top,
1379
- left,
1380
- x: left,
1381
- y: top,
1382
- right: left + element.clientWidth,
1383
- bottom: top + element.clientHeight,
1384
- width: element.clientWidth,
1385
- height: element.clientHeight
1313
+ width,
1314
+ height,
1315
+ x,
1316
+ y
1386
1317
  };
1387
1318
  }
1388
-
1389
1319
  function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
1390
1320
  if (clippingAncestor === 'viewport') {
1391
1321
  return rectToClientRect(getViewportRect(element, strategy));
1392
1322
  }
1393
-
1394
1323
  if (isElement(clippingAncestor)) {
1395
- return getInnerBoundingClientRect(clippingAncestor, strategy);
1324
+ return rectToClientRect(getInnerBoundingClientRect(clippingAncestor, strategy));
1396
1325
  }
1397
-
1398
1326
  return rectToClientRect(getDocumentRect(getDocumentElement(element)));
1399
- } // A "clipping ancestor" is an overflowable container with the characteristic of
1400
- // clipping (or hiding) overflowing elements with a position different from
1401
- // `initial`
1402
-
1327
+ }
1403
1328
 
1404
- function getClippingElementAncestors(element) {
1329
+ // A "clipping ancestor" is an `overflow` element with the characteristic of
1330
+ // clipping (or hiding) child elements. This returns all clipping ancestors
1331
+ // of the given element up the tree.
1332
+ function getClippingElementAncestors(element, cache) {
1333
+ const cachedResult = cache.get(element);
1334
+ if (cachedResult) {
1335
+ return cachedResult;
1336
+ }
1405
1337
  let result = getOverflowAncestors(element).filter(el => isElement(el) && getNodeName(el) !== 'body');
1406
- let currentNode = element;
1407
- let currentContainingBlockComputedStyle = null; // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
1338
+ let currentContainingBlockComputedStyle = null;
1339
+ const elementIsFixed = getComputedStyle$1(element).position === 'fixed';
1340
+ let currentNode = elementIsFixed ? getParentNode(element) : element;
1408
1341
 
1342
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
1409
1343
  while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
1410
- const computedStyle = getComputedStyle(currentNode);
1411
-
1412
- if (computedStyle.position === 'static' && currentContainingBlockComputedStyle && ['absolute', 'fixed'].includes(currentContainingBlockComputedStyle.position) && !isContainingBlock(currentNode)) {
1413
- // Drop non-containing blocks
1344
+ const computedStyle = getComputedStyle$1(currentNode);
1345
+ const containingBlock = isContainingBlock(currentNode);
1346
+ const shouldDropCurrentNode = elementIsFixed ? !containingBlock && !currentContainingBlockComputedStyle : !containingBlock && computedStyle.position === 'static' && !!currentContainingBlockComputedStyle && ['absolute', 'fixed'].includes(currentContainingBlockComputedStyle.position);
1347
+ if (shouldDropCurrentNode) {
1348
+ // Drop non-containing blocks.
1414
1349
  result = result.filter(ancestor => ancestor !== currentNode);
1415
1350
  } else {
1416
- // Record last containing block for next iteration
1351
+ // Record last containing block for next iteration.
1417
1352
  currentContainingBlockComputedStyle = computedStyle;
1418
1353
  }
1419
-
1420
1354
  currentNode = getParentNode(currentNode);
1421
1355
  }
1422
-
1356
+ cache.set(element, result);
1423
1357
  return result;
1424
- } // Gets the maximum area that the element is visible in due to any number of
1425
- // clipping ancestors
1426
-
1358
+ }
1427
1359
 
1360
+ // Gets the maximum area that the element is visible in due to any number of
1361
+ // clipping ancestors.
1428
1362
  function getClippingRect(_ref) {
1429
1363
  let {
1430
1364
  element,
@@ -1432,7 +1366,7 @@ function getClippingRect(_ref) {
1432
1366
  rootBoundary,
1433
1367
  strategy
1434
1368
  } = _ref;
1435
- const elementClippingAncestors = boundary === 'clippingAncestors' ? getClippingElementAncestors(element) : [].concat(boundary);
1369
+ const elementClippingAncestors = boundary === 'clippingAncestors' ? getClippingElementAncestors(element, this._c) : [].concat(boundary);
1436
1370
  const clippingAncestors = [...elementClippingAncestors, rootBoundary];
1437
1371
  const firstClippingAncestor = clippingAncestors[0];
1438
1372
  const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => {
@@ -1451,6 +1385,77 @@ function getClippingRect(_ref) {
1451
1385
  };
1452
1386
  }
1453
1387
 
1388
+ function getDimensions(element) {
1389
+ if (isHTMLElement(element)) {
1390
+ return getCssDimensions(element);
1391
+ }
1392
+ return element.getBoundingClientRect();
1393
+ }
1394
+
1395
+ function getTrueOffsetParent(element) {
1396
+ if (!isHTMLElement(element) || getComputedStyle$1(element).position === 'fixed') {
1397
+ return null;
1398
+ }
1399
+ return element.offsetParent;
1400
+ }
1401
+ function getContainingBlock(element) {
1402
+ let currentNode = getParentNode(element);
1403
+ while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
1404
+ if (isContainingBlock(currentNode)) {
1405
+ return currentNode;
1406
+ } else {
1407
+ currentNode = getParentNode(currentNode);
1408
+ }
1409
+ }
1410
+ return null;
1411
+ }
1412
+
1413
+ // Gets the closest ancestor positioned element. Handles some edge cases,
1414
+ // such as table ancestors and cross browser bugs.
1415
+ function getOffsetParent(element) {
1416
+ const window = getWindow(element);
1417
+ let offsetParent = getTrueOffsetParent(element);
1418
+ while (offsetParent && isTableElement(offsetParent) && getComputedStyle$1(offsetParent).position === 'static') {
1419
+ offsetParent = getTrueOffsetParent(offsetParent);
1420
+ }
1421
+ if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle$1(offsetParent).position === 'static' && !isContainingBlock(offsetParent))) {
1422
+ return window;
1423
+ }
1424
+ return offsetParent || getContainingBlock(element) || window;
1425
+ }
1426
+
1427
+ function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
1428
+ const isOffsetParentAnElement = isHTMLElement(offsetParent);
1429
+ const documentElement = getDocumentElement(offsetParent);
1430
+ const rect = getBoundingClientRect(element, true, strategy === 'fixed', offsetParent);
1431
+ let scroll = {
1432
+ scrollLeft: 0,
1433
+ scrollTop: 0
1434
+ };
1435
+ const offsets = {
1436
+ x: 0,
1437
+ y: 0
1438
+ };
1439
+ if (isOffsetParentAnElement || !isOffsetParentAnElement && strategy !== 'fixed') {
1440
+ if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
1441
+ scroll = getNodeScroll(offsetParent);
1442
+ }
1443
+ if (isHTMLElement(offsetParent)) {
1444
+ const offsetRect = getBoundingClientRect(offsetParent, true);
1445
+ offsets.x = offsetRect.x + offsetParent.clientLeft;
1446
+ offsets.y = offsetRect.y + offsetParent.clientTop;
1447
+ } else if (documentElement) {
1448
+ offsets.x = getWindowScrollBarX(documentElement);
1449
+ }
1450
+ }
1451
+ return {
1452
+ x: rect.left + scroll.scrollLeft - offsets.x,
1453
+ y: rect.top + scroll.scrollTop - offsets.y,
1454
+ width: rect.width,
1455
+ height: rect.height
1456
+ };
1457
+ }
1458
+
1454
1459
  const platform = {
1455
1460
  getClippingRect,
1456
1461
  convertOffsetParentRelativeRectToViewportRelativeRect,
@@ -1458,22 +1463,26 @@ const platform = {
1458
1463
  getDimensions,
1459
1464
  getOffsetParent,
1460
1465
  getDocumentElement,
1461
- getElementRects: _ref => {
1466
+ getScale,
1467
+ async getElementRects(_ref) {
1462
1468
  let {
1463
1469
  reference,
1464
1470
  floating,
1465
1471
  strategy
1466
1472
  } = _ref;
1473
+ const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
1474
+ const getDimensionsFn = this.getDimensions;
1467
1475
  return {
1468
- reference: getRectRelativeToOffsetParent(reference, getOffsetParent(floating), strategy),
1469
- floating: { ...getDimensions(floating),
1476
+ reference: getRectRelativeToOffsetParent(reference, await getOffsetParentFn(floating), strategy),
1477
+ floating: {
1470
1478
  x: 0,
1471
- y: 0
1479
+ y: 0,
1480
+ ...(await getDimensionsFn(floating))
1472
1481
  }
1473
1482
  };
1474
1483
  },
1475
1484
  getClientRects: element => Array.from(element.getClientRects()),
1476
- isRTL: element => getComputedStyle(element).direction === 'rtl'
1485
+ isRTL: element => getComputedStyle$1(element).direction === 'rtl'
1477
1486
  };
1478
1487
 
1479
1488
  /**
@@ -1481,11 +1490,24 @@ const platform = {
1481
1490
  * next to a reference element when it is given a certain CSS positioning
1482
1491
  * strategy.
1483
1492
  */
1484
-
1485
- const computePosition = (reference, floating, options) => computePosition$1(reference, floating, {
1486
- platform,
1487
- ...options
1488
- });
1493
+ const computePosition = (reference, floating, options) => {
1494
+ // This caches the expensive `getClippingElementAncestors` function so that
1495
+ // multiple lifecycle resets re-use the same result. It only lives for a
1496
+ // single call. If other functions become expensive, we can add them as well.
1497
+ const cache = new Map();
1498
+ const mergedOptions = {
1499
+ platform,
1500
+ ...options
1501
+ };
1502
+ const platformWithCache = {
1503
+ ...mergedOptions.platform,
1504
+ _c: cache
1505
+ };
1506
+ return computePosition$1(reference, floating, {
1507
+ ...mergedOptions,
1508
+ platform: platformWithCache
1509
+ });
1510
+ };
1489
1511
 
1490
1512
  var jsxRuntime = {exports: {}};
1491
1513
 
@@ -2636,7 +2658,7 @@ var styles = {"tooltip":"styles-module_tooltip__mnnfp","fixed":"styles-module_fi
2636
2658
 
2637
2659
  const Tooltip = ({
2638
2660
  // props
2639
- id, className, classNameArrow, variant = 'dark', anchorId, place = 'top', offset = 10, events = ['hover'], positionStrategy = 'absolute', middlewares, wrapper: WrapperElement = 'div', children = null, delayShow = 0, delayHide = 0, float = false, noArrow = false, clickable = false, closeOnEsc = false, style: externalStyles, position, afterShow, afterHide,
2661
+ id, className, classNameArrow, variant = 'dark', anchorId, place = 'top', offset = 10, events = ['hover'], positionStrategy = 'absolute', middlewares, wrapper: WrapperElement, children = null, delayShow = 0, delayHide = 0, float = false, noArrow = false, clickable = false, closeOnEsc = false, style: externalStyles, position, afterShow, afterHide,
2640
2662
  // props handled by controller
2641
2663
  content, html, isOpen, setIsOpen, }) => {
2642
2664
  const tooltipRef = useRef(null);
@@ -3008,7 +3030,7 @@ const TooltipController = ({ id, anchorId, content, html, className, classNameAr
3008
3030
  },
3009
3031
  wrapper: (value) => {
3010
3032
  var _a;
3011
- setTooltipWrapper((_a = value) !== null && _a !== void 0 ? _a : 'div');
3033
+ setTooltipWrapper((_a = value) !== null && _a !== void 0 ? _a : wrapper);
3012
3034
  },
3013
3035
  events: (value) => {
3014
3036
  const parsed = value === null || value === void 0 ? void 0 : value.split(' ');