@vonage/vivid 3.0.1 → 3.1.1

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.
Files changed (72) hide show
  1. package/README.md +2 -2
  2. package/calendar/index.js +1 -0
  3. package/custom-elements.json +6206 -0
  4. package/data-grid/index.js +1104 -0
  5. package/index.js +2 -0
  6. package/lib/data-grid/data-grid-cell.d.ts +5 -0
  7. package/lib/data-grid/data-grid-cell.template.d.ts +4 -0
  8. package/lib/data-grid/data-grid-row.d.ts +3 -0
  9. package/lib/data-grid/data-grid-row.template.d.ts +3 -0
  10. package/lib/data-grid/data-grid.d.ts +3 -0
  11. package/lib/data-grid/data-grid.options.d.ts +31 -0
  12. package/lib/data-grid/data-grid.template.d.ts +3 -0
  13. package/lib/data-grid/definition.d.ts +6 -0
  14. package/lib/data-grid/index.d.ts +1 -0
  15. package/lib/popup/definition.d.ts +0 -1
  16. package/lib/popup/popup.d.ts +2 -2
  17. package/number-field/index.js +1 -1
  18. package/package.json +28 -29
  19. package/radio-group/index.js +1 -0
  20. package/shared/aria2.js +9 -0
  21. package/shared/definition.js +1 -1
  22. package/shared/definition11.js +1 -1
  23. package/shared/definition12.js +46 -797
  24. package/shared/definition13.js +1 -1
  25. package/shared/definition14.js +1 -1
  26. package/shared/definition16.js +1 -1
  27. package/shared/definition17.js +1 -1
  28. package/shared/definition18.js +594 -843
  29. package/shared/definition19.js +1 -1
  30. package/shared/definition2.js +1 -1
  31. package/shared/definition20.js +24 -28
  32. package/shared/definition21.js +1 -1
  33. package/shared/definition22.js +1 -1
  34. package/shared/definition23.js +1 -1
  35. package/shared/definition25.js +1 -1
  36. package/shared/definition27.js +2 -2
  37. package/shared/definition29.js +1 -1
  38. package/shared/definition30.js +1 -1
  39. package/shared/definition31.js +1 -1
  40. package/shared/definition32.js +1 -1
  41. package/shared/definition33.js +1 -1
  42. package/shared/definition34.js +1 -1
  43. package/shared/definition35.js +4 -3
  44. package/shared/definition36.js +1 -1
  45. package/shared/definition37.js +7 -3
  46. package/shared/definition38.js +3 -2
  47. package/shared/definition39.js +1 -1
  48. package/shared/definition4.js +1 -1
  49. package/shared/definition40.js +1 -1
  50. package/shared/definition42.js +2 -2
  51. package/shared/definition43.js +1 -1
  52. package/shared/definition45.js +1 -1
  53. package/shared/definition5.js +1 -1
  54. package/shared/definition6.js +1 -1
  55. package/shared/definition7.js +1 -1
  56. package/shared/definition8.js +1 -1
  57. package/shared/definition9.js +1 -1
  58. package/shared/form-elements.js +1 -1
  59. package/shared/icon.js +18 -6
  60. package/shared/index.js +10 -19
  61. package/shared/key-codes.js +4 -1
  62. package/shared/patterns/form-elements/form-elements.d.ts +2 -2
  63. package/shared/repeat.js +764 -0
  64. package/shared/slotted.js +1 -1
  65. package/shared/text-field.js +1 -1
  66. package/slider/index.js +1 -0
  67. package/styles/core/all.css +1 -1
  68. package/styles/core/theme.css +1 -1
  69. package/styles/core/typography.css +1 -1
  70. package/styles/tokens/theme-dark.css +4 -4
  71. package/styles/tokens/theme-light.css +4 -4
  72. package/vivid.api.json +3695 -0
@@ -7,22 +7,22 @@ import { w as when } from './when.js';
7
7
  import { r as ref } from './ref.js';
8
8
  import { c as classNames } from './class-names.js';
9
9
 
10
- function getSide(placement) {
11
- return placement.split('-')[0];
12
- }
13
-
14
10
  function getAlignment(placement) {
15
11
  return placement.split('-')[1];
16
12
  }
17
13
 
18
- function getMainAxisFromPlacement(placement) {
19
- return ['top', 'bottom'].includes(getSide(placement)) ? 'x' : 'y';
20
- }
21
-
22
14
  function getLengthFromAxis(axis) {
23
15
  return axis === 'y' ? 'height' : 'width';
24
16
  }
25
17
 
18
+ function getSide(placement) {
19
+ return placement.split('-')[0];
20
+ }
21
+
22
+ function getMainAxisFromPlacement(placement) {
23
+ return ['top', 'bottom'].includes(getSide(placement)) ? 'x' : 'y';
24
+ }
25
+
26
26
  function computeCoordsFromPlacement(_ref, placement, rtl) {
27
27
  let {
28
28
  reference,
@@ -36,7 +36,6 @@ function computeCoordsFromPlacement(_ref, placement, rtl) {
36
36
  const side = getSide(placement);
37
37
  const isVertical = mainAxis === 'x';
38
38
  let coords;
39
-
40
39
  switch (side) {
41
40
  case 'top':
42
41
  coords = {
@@ -44,45 +43,38 @@ function computeCoordsFromPlacement(_ref, placement, rtl) {
44
43
  y: reference.y - floating.height
45
44
  };
46
45
  break;
47
-
48
46
  case 'bottom':
49
47
  coords = {
50
48
  x: commonX,
51
49
  y: reference.y + reference.height
52
50
  };
53
51
  break;
54
-
55
52
  case 'right':
56
53
  coords = {
57
54
  x: reference.x + reference.width,
58
55
  y: commonY
59
56
  };
60
57
  break;
61
-
62
58
  case 'left':
63
59
  coords = {
64
60
  x: reference.x - floating.width,
65
61
  y: commonY
66
62
  };
67
63
  break;
68
-
69
64
  default:
70
65
  coords = {
71
66
  x: reference.x,
72
67
  y: reference.y
73
68
  };
74
69
  }
75
-
76
70
  switch (getAlignment(placement)) {
77
71
  case 'start':
78
72
  coords[mainAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);
79
73
  break;
80
-
81
74
  case 'end':
82
75
  coords[mainAxis] += commonAlign * (rtl && isVertical ? -1 : 1);
83
76
  break;
84
77
  }
85
-
86
78
  return coords;
87
79
  }
88
80
 
@@ -93,7 +85,6 @@ function computeCoordsFromPlacement(_ref, placement, rtl) {
93
85
  * This export does not have any `platform` interface logic. You will need to
94
86
  * write one for the platform you are using Floating UI with.
95
87
  */
96
-
97
88
  const computePosition$1 = async (reference, floating, config) => {
98
89
  const {
99
90
  placement = 'bottom',
@@ -101,8 +92,8 @@ const computePosition$1 = async (reference, floating, config) => {
101
92
  middleware = [],
102
93
  platform
103
94
  } = config;
95
+ const validMiddleware = middleware.filter(Boolean);
104
96
  const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(floating));
105
-
106
97
  let rects = await platform.getElementRects({
107
98
  reference,
108
99
  floating,
@@ -115,12 +106,11 @@ const computePosition$1 = async (reference, floating, config) => {
115
106
  let statefulPlacement = placement;
116
107
  let middlewareData = {};
117
108
  let resetCount = 0;
118
-
119
- for (let i = 0; i < middleware.length; i++) {
109
+ for (let i = 0; i < validMiddleware.length; i++) {
120
110
  const {
121
111
  name,
122
112
  fn
123
- } = middleware[i];
113
+ } = validMiddleware[i];
124
114
  const {
125
115
  x: nextX,
126
116
  y: nextY,
@@ -142,20 +132,19 @@ const computePosition$1 = async (reference, floating, config) => {
142
132
  });
143
133
  x = nextX != null ? nextX : x;
144
134
  y = nextY != null ? nextY : y;
145
- middlewareData = { ...middlewareData,
146
- [name]: { ...middlewareData[name],
135
+ middlewareData = {
136
+ ...middlewareData,
137
+ [name]: {
138
+ ...middlewareData[name],
147
139
  ...data
148
140
  }
149
141
  };
150
-
151
142
  if (reset && resetCount <= 50) {
152
143
  resetCount++;
153
-
154
144
  if (typeof reset === 'object') {
155
145
  if (reset.placement) {
156
146
  statefulPlacement = reset.placement;
157
147
  }
158
-
159
148
  if (reset.rects) {
160
149
  rects = reset.rects === true ? await platform.getElementRects({
161
150
  reference,
@@ -163,18 +152,15 @@ const computePosition$1 = async (reference, floating, config) => {
163
152
  strategy
164
153
  }) : reset.rects;
165
154
  }
166
-
167
155
  ({
168
156
  x,
169
157
  y
170
158
  } = computeCoordsFromPlacement(rects, statefulPlacement, rtl));
171
159
  }
172
-
173
160
  i = -1;
174
161
  continue;
175
162
  }
176
163
  }
177
-
178
164
  return {
179
165
  x,
180
166
  y,
@@ -204,7 +190,8 @@ function getSideObjectFromPadding(padding) {
204
190
  }
205
191
 
206
192
  function rectToClientRect(rect) {
207
- return { ...rect,
193
+ return {
194
+ ...rect,
208
195
  top: rect.y,
209
196
  left: rect.x,
210
197
  right: rect.x + rect.width,
@@ -222,11 +209,9 @@ function rectToClientRect(rect) {
222
209
  */
223
210
  async function detectOverflow(middlewareArguments, options) {
224
211
  var _await$platform$isEle;
225
-
226
212
  if (options === void 0) {
227
213
  options = {};
228
214
  }
229
-
230
215
  const {
231
216
  x,
232
217
  y,
@@ -251,19 +236,29 @@ async function detectOverflow(middlewareArguments, options) {
251
236
  rootBoundary,
252
237
  strategy
253
238
  }));
239
+ const rect = elementContext === 'floating' ? {
240
+ ...rects.floating,
241
+ x,
242
+ y
243
+ } : rects.reference;
244
+ const offsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating));
245
+ const offsetScale = (await (platform.isElement == null ? void 0 : platform.isElement(offsetParent))) ? (await (platform.getScale == null ? void 0 : platform.getScale(offsetParent))) || {
246
+ x: 1,
247
+ y: 1
248
+ } : {
249
+ x: 1,
250
+ y: 1
251
+ };
254
252
  const elementClientRect = rectToClientRect(platform.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform.convertOffsetParentRelativeRectToViewportRelativeRect({
255
- rect: elementContext === 'floating' ? { ...rects.floating,
256
- x,
257
- y
258
- } : rects.reference,
259
- offsetParent: await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating)),
253
+ rect,
254
+ offsetParent,
260
255
  strategy
261
- }) : rects[elementContext]);
256
+ }) : rect);
262
257
  return {
263
- top: clippingClientRect.top - elementClientRect.top + paddingObject.top,
264
- bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,
265
- left: clippingClientRect.left - elementClientRect.left + paddingObject.left,
266
- right: elementClientRect.right - clippingClientRect.right + paddingObject.right
258
+ top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
259
+ bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
260
+ left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
261
+ right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
267
262
  };
268
263
  }
269
264
 
@@ -275,20 +270,20 @@ function within(min$1$1, value, max$1$1) {
275
270
  }
276
271
 
277
272
  /**
278
- * Positions an inner element of the floating element such that it is centered
279
- * to the reference element.
273
+ * A data provider that provides data to position an inner element of the
274
+ * floating element (usually a triangle or caret) so that it is centered to the
275
+ * reference element.
280
276
  * @see https://floating-ui.com/docs/arrow
281
277
  */
282
278
  const arrow = options => ({
283
279
  name: 'arrow',
284
280
  options,
285
-
286
281
  async fn(middlewareArguments) {
287
- // Since `element` is required, we don't Partial<> the type
282
+ // Since `element` is required, we don't Partial<> the type.
288
283
  const {
289
284
  element,
290
285
  padding = 0
291
- } = options != null ? options : {};
286
+ } = options || {};
292
287
  const {
293
288
  x,
294
289
  y,
@@ -296,19 +291,15 @@ const arrow = options => ({
296
291
  rects,
297
292
  platform
298
293
  } = middlewareArguments;
299
-
300
294
  if (element == null) {
301
-
302
295
  return {};
303
296
  }
304
-
305
297
  const paddingObject = getSideObjectFromPadding(padding);
306
298
  const coords = {
307
299
  x,
308
300
  y
309
301
  };
310
302
  const axis = getMainAxisFromPlacement(placement);
311
- const alignment = getAlignment(placement);
312
303
  const length = getLengthFromAxis(axis);
313
304
  const arrowDimensions = await platform.getDimensions(element);
314
305
  const minProp = axis === 'y' ? 'top' : 'left';
@@ -317,21 +308,23 @@ const arrow = options => ({
317
308
  const startDiff = coords[axis] - rects.reference[axis];
318
309
  const arrowOffsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(element));
319
310
  let clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;
320
-
321
311
  if (clientSize === 0) {
322
312
  clientSize = rects.floating[length];
323
313
  }
314
+ const centerToReference = endDiff / 2 - startDiff / 2;
324
315
 
325
- const centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the floating element if the center
326
- // point is outside the floating element's bounds
327
-
316
+ // Make sure the arrow doesn't overflow the floating element if the center
317
+ // point is outside the floating element's bounds.
328
318
  const min = paddingObject[minProp];
329
319
  const max = clientSize - arrowDimensions[length] - paddingObject[maxProp];
330
320
  const center = clientSize / 2 - arrowDimensions[length] / 2 + centerToReference;
331
- const offset = within(min, center, max); // Make sure that arrow points at the reference
321
+ const offset = within(min, center, max);
332
322
 
333
- const alignmentPadding = alignment === 'start' ? paddingObject[minProp] : paddingObject[maxProp];
334
- const shouldAddOffset = alignmentPadding > 0 && center !== offset && rects.reference[length] <= rects.floating[length];
323
+ // If the reference is small enough that the arrow's padding causes it to
324
+ // to point to nothing for an aligned placement, adjust the offset of the
325
+ // floating element itself. This stops `shift()` from taking action, but can
326
+ // be worked around by calling it again after the `arrow()` if desired.
327
+ const shouldAddOffset = getAlignment(placement) != null && center != offset && rects.reference[length] / 2 - (center < min ? paddingObject[minProp] : paddingObject[maxProp]) - arrowDimensions[length] / 2 < 0;
335
328
  const alignmentOffset = shouldAddOffset ? center < min ? min - center : max - center : 0;
336
329
  return {
337
330
  [axis]: coords[axis] - alignmentOffset,
@@ -341,71 +334,97 @@ const arrow = options => ({
341
334
  }
342
335
  };
343
336
  }
344
-
345
337
  });
346
338
 
347
- const hash$1 = {
339
+ const sides = ['top', 'right', 'bottom', 'left'];
340
+
341
+ const oppositeSideMap = {
348
342
  left: 'right',
349
343
  right: 'left',
350
344
  bottom: 'top',
351
345
  top: 'bottom'
352
346
  };
353
347
  function getOppositePlacement(placement) {
354
- return placement.replace(/left|right|bottom|top/g, matched => hash$1[matched]);
348
+ return placement.replace(/left|right|bottom|top/g, side => oppositeSideMap[side]);
355
349
  }
356
350
 
357
351
  function getAlignmentSides(placement, rects, rtl) {
358
352
  if (rtl === void 0) {
359
353
  rtl = false;
360
354
  }
361
-
362
355
  const alignment = getAlignment(placement);
363
356
  const mainAxis = getMainAxisFromPlacement(placement);
364
357
  const length = getLengthFromAxis(mainAxis);
365
358
  let mainAlignmentSide = mainAxis === 'x' ? alignment === (rtl ? 'end' : 'start') ? 'right' : 'left' : alignment === 'start' ? 'bottom' : 'top';
366
-
367
359
  if (rects.reference[length] > rects.floating[length]) {
368
360
  mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
369
361
  }
370
-
371
362
  return {
372
363
  main: mainAlignmentSide,
373
364
  cross: getOppositePlacement(mainAlignmentSide)
374
365
  };
375
366
  }
376
367
 
377
- const hash = {
368
+ const oppositeAlignmentMap = {
378
369
  start: 'end',
379
370
  end: 'start'
380
371
  };
381
372
  function getOppositeAlignmentPlacement(placement) {
382
- return placement.replace(/start|end/g, matched => hash[matched]);
373
+ return placement.replace(/start|end/g, alignment => oppositeAlignmentMap[alignment]);
383
374
  }
384
375
 
385
- const sides = ['top', 'right', 'bottom', 'left'];
386
-
387
376
  function getExpandedPlacements(placement) {
388
377
  const oppositePlacement = getOppositePlacement(placement);
389
378
  return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
390
379
  }
391
380
 
381
+ function getSideList(side, isStart, rtl) {
382
+ const lr = ['left', 'right'];
383
+ const rl = ['right', 'left'];
384
+ const tb = ['top', 'bottom'];
385
+ const bt = ['bottom', 'top'];
386
+ switch (side) {
387
+ case 'top':
388
+ case 'bottom':
389
+ if (rtl) return isStart ? rl : lr;
390
+ return isStart ? lr : rl;
391
+ case 'left':
392
+ case 'right':
393
+ return isStart ? tb : bt;
394
+ default:
395
+ return [];
396
+ }
397
+ }
398
+ function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
399
+ const alignment = getAlignment(placement);
400
+ let list = getSideList(getSide(placement), direction === 'start', rtl);
401
+ if (alignment) {
402
+ list = list.map(side => side + "-" + alignment);
403
+ if (flipAlignment) {
404
+ list = list.concat(list.map(getOppositeAlignmentPlacement));
405
+ }
406
+ }
407
+ return list;
408
+ }
409
+
392
410
  /**
393
- * Changes the placement of the floating element to one that will fit if the
394
- * initially specified `placement` does not.
411
+ * A visibility optimizer that changes the placement of the floating element in
412
+ * order to keep it in view. By default, only the opposite placement is tried.
413
+ *
414
+ * It has the ability to flip to any placement, not just the opposite one. You
415
+ * can use a series of “fallback” placements, where each placement is
416
+ * progressively tried until the one that fits can be used.
395
417
  * @see https://floating-ui.com/docs/flip
396
418
  */
397
419
  const flip = function (options) {
398
420
  if (options === void 0) {
399
421
  options = {};
400
422
  }
401
-
402
423
  return {
403
424
  name: 'flip',
404
425
  options,
405
-
406
426
  async fn(middlewareArguments) {
407
427
  var _middlewareData$flip;
408
-
409
428
  const {
410
429
  placement,
411
430
  middlewareData,
@@ -419,42 +438,43 @@ const flip = function (options) {
419
438
  crossAxis: checkCrossAxis = true,
420
439
  fallbackPlacements: specifiedFallbackPlacements,
421
440
  fallbackStrategy = 'bestFit',
441
+ fallbackAxisSideDirection = 'none',
422
442
  flipAlignment = true,
423
443
  ...detectOverflowOptions
424
444
  } = options;
425
445
  const side = getSide(placement);
426
- const isBasePlacement = side === initialPlacement;
446
+ const isBasePlacement = getSide(initialPlacement) === initialPlacement;
447
+ const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating));
427
448
  const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement));
449
+ if (!specifiedFallbackPlacements && fallbackAxisSideDirection !== 'none') {
450
+ fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));
451
+ }
428
452
  const placements = [initialPlacement, ...fallbackPlacements];
429
453
  const overflow = await detectOverflow(middlewareArguments, detectOverflowOptions);
430
454
  const overflows = [];
431
455
  let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
432
-
433
456
  if (checkMainAxis) {
434
457
  overflows.push(overflow[side]);
435
458
  }
436
-
437
459
  if (checkCrossAxis) {
438
460
  const {
439
461
  main,
440
462
  cross
441
- } = getAlignmentSides(placement, rects, await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating)));
463
+ } = getAlignmentSides(placement, rects, rtl);
442
464
  overflows.push(overflow[main], overflow[cross]);
443
465
  }
444
-
445
466
  overflowsData = [...overflowsData, {
446
467
  placement,
447
468
  overflows
448
- }]; // One or more sides is overflowing
469
+ }];
449
470
 
471
+ // One or more sides is overflowing.
450
472
  if (!overflows.every(side => side <= 0)) {
451
- var _middlewareData$flip$, _middlewareData$flip2;
452
-
453
- const nextIndex = ((_middlewareData$flip$ = (_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) != null ? _middlewareData$flip$ : 0) + 1;
473
+ var _middlewareData$flip2, _overflowsData$filter;
474
+ const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;
454
475
  const nextPlacement = placements[nextIndex];
455
-
456
476
  if (nextPlacement) {
457
- // Try next placement and re-run the lifecycle
477
+ // Try next placement and re-run the lifecycle.
458
478
  return {
459
479
  data: {
460
480
  index: nextIndex,
@@ -466,27 +486,27 @@ const flip = function (options) {
466
486
  };
467
487
  }
468
488
 
469
- let resetPlacement = 'bottom';
470
-
471
- switch (fallbackStrategy) {
472
- case 'bestFit':
473
- {
474
- var _overflowsData$map$so;
475
-
476
- 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;
477
-
478
- if (placement) {
479
- resetPlacement = placement;
489
+ // First, find the candidates that fit on the mainAxis side of overflow,
490
+ // then find the placement that fits the best on the main crossAxis side.
491
+ let resetPlacement = (_overflowsData$filter = overflowsData.filter(d => d.overflows[0] <= 0).sort((a, b) => a.overflows[1] - b.overflows[1])[0]) == null ? void 0 : _overflowsData$filter.placement;
492
+
493
+ // Otherwise fallback.
494
+ if (!resetPlacement) {
495
+ switch (fallbackStrategy) {
496
+ case 'bestFit':
497
+ {
498
+ var _overflowsData$map$so;
499
+ 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];
500
+ if (placement) {
501
+ resetPlacement = placement;
502
+ }
503
+ break;
480
504
  }
481
-
505
+ case 'initialPlacement':
506
+ resetPlacement = initialPlacement;
482
507
  break;
483
- }
484
-
485
- case 'initialPlacement':
486
- resetPlacement = initialPlacement;
487
- break;
508
+ }
488
509
  }
489
-
490
510
  if (placement !== resetPlacement) {
491
511
  return {
492
512
  reset: {
@@ -495,10 +515,8 @@ const flip = function (options) {
495
515
  };
496
516
  }
497
517
  }
498
-
499
518
  return {};
500
519
  }
501
-
502
520
  };
503
521
  };
504
522
 
@@ -510,33 +528,35 @@ function getSideOffsets(overflow, rect) {
510
528
  left: overflow.left - rect.width
511
529
  };
512
530
  }
513
-
514
531
  function isAnySideFullyClipped(overflow) {
515
532
  return sides.some(side => overflow[side] >= 0);
516
533
  }
517
-
518
534
  /**
519
- * Provides data to hide the floating element in applicable situations, such as
520
- * when it is not in the same clipping context as the reference element.
535
+ * A data provider that allows you to hide the floating element in applicable
536
+ * situations, usually when it’s not within the same clipping context as the
537
+ * reference element.
521
538
  * @see https://floating-ui.com/docs/hide
522
539
  */
523
- const hide = function (_temp) {
524
- let {
525
- strategy = 'referenceHidden',
526
- ...detectOverflowOptions
527
- } = _temp === void 0 ? {} : _temp;
540
+ const hide = function (options) {
541
+ if (options === void 0) {
542
+ options = {};
543
+ }
528
544
  return {
529
545
  name: 'hide',
530
-
546
+ options,
531
547
  async fn(middlewareArguments) {
548
+ const {
549
+ strategy = 'referenceHidden',
550
+ ...detectOverflowOptions
551
+ } = options;
532
552
  const {
533
553
  rects
534
554
  } = middlewareArguments;
535
-
536
555
  switch (strategy) {
537
556
  case 'referenceHidden':
538
557
  {
539
- const overflow = await detectOverflow(middlewareArguments, { ...detectOverflowOptions,
558
+ const overflow = await detectOverflow(middlewareArguments, {
559
+ ...detectOverflowOptions,
540
560
  elementContext: 'reference'
541
561
  });
542
562
  const offsets = getSideOffsets(overflow, rects.reference);
@@ -547,10 +567,10 @@ const hide = function (_temp) {
547
567
  }
548
568
  };
549
569
  }
550
-
551
570
  case 'escaped':
552
571
  {
553
- const overflow = await detectOverflow(middlewareArguments, { ...detectOverflowOptions,
572
+ const overflow = await detectOverflow(middlewareArguments, {
573
+ ...detectOverflowOptions,
554
574
  altBoundary: true
555
575
  });
556
576
  const offsets = getSideOffsets(overflow, rects.floating);
@@ -561,85 +581,12 @@ const hide = function (_temp) {
561
581
  }
562
582
  };
563
583
  }
564
-
565
584
  default:
566
585
  {
567
586
  return {};
568
587
  }
569
588
  }
570
589
  }
571
-
572
- };
573
- };
574
-
575
- async function convertValueToCoords(middlewareArguments, value) {
576
- const {
577
- placement,
578
- platform,
579
- elements
580
- } = middlewareArguments;
581
- const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating));
582
- const side = getSide(placement);
583
- const alignment = getAlignment(placement);
584
- const isVertical = getMainAxisFromPlacement(placement) === 'x';
585
- const mainAxisMulti = ['left', 'top'].includes(side) ? -1 : 1;
586
- const crossAxisMulti = rtl && isVertical ? -1 : 1;
587
- const rawValue = typeof value === 'function' ? value(middlewareArguments) : value; // eslint-disable-next-line prefer-const
588
-
589
- let {
590
- mainAxis,
591
- crossAxis,
592
- alignmentAxis
593
- } = typeof rawValue === 'number' ? {
594
- mainAxis: rawValue,
595
- crossAxis: 0,
596
- alignmentAxis: null
597
- } : {
598
- mainAxis: 0,
599
- crossAxis: 0,
600
- alignmentAxis: null,
601
- ...rawValue
602
- };
603
-
604
- if (alignment && typeof alignmentAxis === 'number') {
605
- crossAxis = alignment === 'end' ? alignmentAxis * -1 : alignmentAxis;
606
- }
607
-
608
- return isVertical ? {
609
- x: crossAxis * crossAxisMulti,
610
- y: mainAxis * mainAxisMulti
611
- } : {
612
- x: mainAxis * mainAxisMulti,
613
- y: crossAxis * crossAxisMulti
614
- };
615
- }
616
- /**
617
- * Displaces the floating element from its reference element.
618
- * @see https://floating-ui.com/docs/offset
619
- */
620
-
621
- const offset = function (value) {
622
- if (value === void 0) {
623
- value = 0;
624
- }
625
-
626
- return {
627
- name: 'offset',
628
- options: value,
629
-
630
- async fn(middlewareArguments) {
631
- const {
632
- x,
633
- y
634
- } = middlewareArguments;
635
- const diffCoords = await convertValueToCoords(middlewareArguments, value);
636
- return {
637
- x: x + diffCoords.x,
638
- y: y + diffCoords.y,
639
- data: diffCoords
640
- };
641
- }
642
-
643
590
  };
644
591
  };
645
592
 
@@ -652,24 +599,20 @@ const inline = function (options) {
652
599
  if (options === void 0) {
653
600
  options = {};
654
601
  }
655
-
656
602
  return {
657
603
  name: 'inline',
658
604
  options,
659
-
660
605
  async fn(middlewareArguments) {
661
- var _await$platform$getCl;
662
-
663
606
  const {
664
607
  placement,
665
608
  elements,
666
609
  rects,
667
610
  platform,
668
611
  strategy
669
- } = middlewareArguments; // A MouseEvent's client{X,Y} coords can be up to 2 pixels off a
612
+ } = middlewareArguments;
613
+ // A MouseEvent's client{X,Y} coords can be up to 2 pixels off a
670
614
  // ClientRect's bounds, despite the event listener being triggered. A
671
615
  // padding of 2 seems to handle this issue.
672
-
673
616
  const {
674
617
  padding = 2,
675
618
  x,
@@ -680,19 +623,16 @@ const inline = function (options) {
680
623
  offsetParent: await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating)),
681
624
  strategy
682
625
  }) : rects.reference);
683
- const clientRects = (_await$platform$getCl = await (platform.getClientRects == null ? void 0 : platform.getClientRects(elements.reference))) != null ? _await$platform$getCl : [];
626
+ const clientRects = (await (platform.getClientRects == null ? void 0 : platform.getClientRects(elements.reference))) || [];
684
627
  const paddingObject = getSideObjectFromPadding(padding);
685
-
686
628
  function getBoundingClientRect() {
687
- // There are two rects and they are disjoined
629
+ // There are two rects and they are disjoined.
688
630
  if (clientRects.length === 2 && clientRects[0].left > clientRects[1].right && x != null && y != null) {
689
- var _clientRects$find;
690
-
691
- // Find the first rect in which the point is fully inside
692
- 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;
693
- } // There are 2 or more connected rects
694
-
631
+ // Find the first rect in which the point is fully inside.
632
+ 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;
633
+ }
695
634
 
635
+ // There are 2 or more connected rects.
696
636
  if (clientRects.length >= 2) {
697
637
  if (getMainAxisFromPlacement(placement) === 'x') {
698
638
  const firstRect = clientRects[0];
@@ -715,7 +655,6 @@ const inline = function (options) {
715
655
  y: top
716
656
  };
717
657
  }
718
-
719
658
  const isLeftSide = getSide(placement) === 'left';
720
659
  const maxRight = max$1(...clientRects.map(rect => rect.right));
721
660
  const minLeft = min$1(...clientRects.map(rect => rect.left));
@@ -737,10 +676,8 @@ const inline = function (options) {
737
676
  y: top
738
677
  };
739
678
  }
740
-
741
679
  return fallback;
742
680
  }
743
-
744
681
  const resetRects = await platform.getElementRects({
745
682
  reference: {
746
683
  getBoundingClientRect
@@ -748,7 +685,6 @@ const inline = function (options) {
748
685
  floating: elements.floating,
749
686
  strategy
750
687
  });
751
-
752
688
  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) {
753
689
  return {
754
690
  reset: {
@@ -756,44 +692,126 @@ const inline = function (options) {
756
692
  }
757
693
  };
758
694
  }
759
-
760
695
  return {};
761
696
  }
762
-
763
697
  };
764
698
  };
765
699
 
766
- function isWindow(value) {
767
- return value && value.document && value.location && value.alert && value.setInterval;
768
- }
769
- function getWindow(node) {
770
- if (node == null) {
771
- return window;
700
+ async function convertValueToCoords(middlewareArguments, value) {
701
+ const {
702
+ placement,
703
+ platform,
704
+ elements
705
+ } = middlewareArguments;
706
+ const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating));
707
+ const side = getSide(placement);
708
+ const alignment = getAlignment(placement);
709
+ const isVertical = getMainAxisFromPlacement(placement) === 'x';
710
+ const mainAxisMulti = ['left', 'top'].includes(side) ? -1 : 1;
711
+ const crossAxisMulti = rtl && isVertical ? -1 : 1;
712
+ const rawValue = typeof value === 'function' ? value(middlewareArguments) : value;
713
+
714
+ // eslint-disable-next-line prefer-const
715
+ let {
716
+ mainAxis,
717
+ crossAxis,
718
+ alignmentAxis
719
+ } = typeof rawValue === 'number' ? {
720
+ mainAxis: rawValue,
721
+ crossAxis: 0,
722
+ alignmentAxis: null
723
+ } : {
724
+ mainAxis: 0,
725
+ crossAxis: 0,
726
+ alignmentAxis: null,
727
+ ...rawValue
728
+ };
729
+ if (alignment && typeof alignmentAxis === 'number') {
730
+ crossAxis = alignment === 'end' ? alignmentAxis * -1 : alignmentAxis;
772
731
  }
732
+ return isVertical ? {
733
+ x: crossAxis * crossAxisMulti,
734
+ y: mainAxis * mainAxisMulti
735
+ } : {
736
+ x: mainAxis * mainAxisMulti,
737
+ y: crossAxis * crossAxisMulti
738
+ };
739
+ }
773
740
 
774
- if (!isWindow(node)) {
775
- const ownerDocument = node.ownerDocument;
776
- return ownerDocument ? ownerDocument.defaultView || window : window;
741
+ /**
742
+ * A placement modifier that translates the floating element along the specified
743
+ * axes.
744
+ * A number (shorthand for `mainAxis` or distance), or an axes configuration
745
+ * object may be passed.
746
+ * @see https://floating-ui.com/docs/offset
747
+ */
748
+ const offset = function (value) {
749
+ if (value === void 0) {
750
+ value = 0;
777
751
  }
752
+ return {
753
+ name: 'offset',
754
+ options: value,
755
+ async fn(middlewareArguments) {
756
+ const {
757
+ x,
758
+ y
759
+ } = middlewareArguments;
760
+ const diffCoords = await convertValueToCoords(middlewareArguments, value);
761
+ return {
762
+ x: x + diffCoords.x,
763
+ y: y + diffCoords.y,
764
+ data: diffCoords
765
+ };
766
+ }
767
+ };
768
+ };
778
769
 
779
- return node;
770
+ function getWindow(node) {
771
+ var _node$ownerDocument;
772
+ return ((_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
780
773
  }
781
774
 
782
775
  function getComputedStyle$1(element) {
783
776
  return getWindow(element).getComputedStyle(element);
784
777
  }
785
778
 
786
- function getNodeName(node) {
787
- return isWindow(node) ? '' : node ? (node.nodeName || '').toLowerCase() : '';
779
+ const min = Math.min;
780
+ const max = Math.max;
781
+ const round = Math.round;
782
+
783
+ function getCssDimensions(element) {
784
+ const css = getComputedStyle$1(element);
785
+ let width = parseFloat(css.width);
786
+ let height = parseFloat(css.height);
787
+ const offsetWidth = element.offsetWidth;
788
+ const offsetHeight = element.offsetHeight;
789
+ const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
790
+ if (shouldFallback) {
791
+ width = offsetWidth;
792
+ height = offsetHeight;
793
+ }
794
+ return {
795
+ width,
796
+ height,
797
+ fallback: shouldFallback
798
+ };
799
+ }
800
+
801
+ function getNodeName(node) {
802
+ return isNode(node) ? (node.nodeName || '').toLowerCase() : '';
788
803
  }
789
804
 
805
+ let uaString;
790
806
  function getUAString() {
807
+ if (uaString) {
808
+ return uaString;
809
+ }
791
810
  const uaData = navigator.userAgentData;
792
-
793
- if (uaData != null && uaData.brands) {
794
- return uaData.brands.map(item => item.brand + "/" + item.version).join(' ');
811
+ if (uaData && Array.isArray(uaData.brands)) {
812
+ uaString = uaData.brands.map(item => item.brand + "/" + item.version).join(' ');
813
+ return uaString;
795
814
  }
796
-
797
815
  return navigator.userAgent;
798
816
  }
799
817
 
@@ -807,75 +825,142 @@ function isNode(value) {
807
825
  return value instanceof getWindow(value).Node;
808
826
  }
809
827
  function isShadowRoot(node) {
810
- // Browsers without `ShadowRoot` support
828
+ // Browsers without `ShadowRoot` support.
811
829
  if (typeof ShadowRoot === 'undefined') {
812
830
  return false;
813
831
  }
814
-
815
832
  const OwnElement = getWindow(node).ShadowRoot;
816
833
  return node instanceof OwnElement || node instanceof ShadowRoot;
817
834
  }
818
835
  function isOverflowElement(element) {
819
- // Firefox wants us to check `-x` and `-y` variations as well
820
836
  const {
821
837
  overflow,
822
838
  overflowX,
823
- overflowY
839
+ overflowY,
840
+ display
824
841
  } = getComputedStyle$1(element);
825
- return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);
842
+ return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !['inline', 'contents'].includes(display);
826
843
  }
827
844
  function isTableElement(element) {
828
845
  return ['table', 'td', 'th'].includes(getNodeName(element));
829
846
  }
830
847
  function isContainingBlock(element) {
831
- // TODO: Try and use feature detection here instead
848
+ // TODO: Try to use feature detection here instead.
832
849
  const isFirefox = /firefox/i.test(getUAString());
833
- const css = getComputedStyle$1(element); // This is non-exhaustive but covers the most common CSS properties that
850
+ const css = getComputedStyle$1(element);
851
+ const backdropFilter = css.backdropFilter || css.WebkitBackdropFilter;
852
+
853
+ // This is non-exhaustive but covers the most common CSS properties that
834
854
  // create a containing block.
835
855
  // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
836
-
837
- return css.transform !== 'none' || css.perspective !== 'none' || // @ts-ignore (TS 4.1 compat)
838
- css.contain === 'paint' || ['transform', 'perspective'].includes(css.willChange) || isFirefox && css.willChange === 'filter' || isFirefox && (css.filter ? css.filter !== 'none' : false);
856
+ 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 => {
857
+ // Add type check for old browsers.
858
+ const contain = css.contain;
859
+ return contain != null ? contain.includes(value) : false;
860
+ });
839
861
  }
840
- function isLayoutViewport() {
841
- // Not Safari
842
- return !/^((?!chrome|android).)*safari/i.test(getUAString()); // Feature detection for this fails in various ways
862
+
863
+ /**
864
+ * Determines whether or not `.getBoundingClientRect()` is affected by visual
865
+ * viewport offsets. In Safari, the `x`/`y` offsets are values relative to the
866
+ * visual viewport, while in other engines, they are values relative to the
867
+ * layout viewport.
868
+ */
869
+ function isClientRectVisualViewportBased() {
870
+ // TODO: Try to use feature detection here instead. Feature detection for
871
+ // this can fail in various ways, making the userAgent check the most
872
+ // reliable:
843
873
  // • Always-visible scrollbar or not
844
- // • Width of <html>, etc.
845
- // const vV = win.visualViewport;
846
- // return vV ? Math.abs(win.innerWidth / vV.scale - vV.width) < 0.5 : true;
874
+ // • Width of <html>
875
+
876
+ // Is Safari.
877
+ return /^((?!chrome|android).)*safari/i.test(getUAString());
878
+ }
879
+ function isLastTraversableNode(node) {
880
+ return ['html', 'body', '#document'].includes(getNodeName(node));
847
881
  }
848
882
 
849
- const min = Math.min;
850
- const max = Math.max;
851
- const round = Math.round;
883
+ function unwrapElement(element) {
884
+ return !isElement(element) ? element.contextElement : element;
885
+ }
852
886
 
853
- function getBoundingClientRect(element, includeScale, isFixedStrategy) {
854
- var _win$visualViewport$o, _win$visualViewport, _win$visualViewport$o2, _win$visualViewport2;
887
+ const FALLBACK_SCALE = {
888
+ x: 1,
889
+ y: 1
890
+ };
891
+ function getScale(element) {
892
+ const domElement = unwrapElement(element);
893
+ if (!isHTMLElement(domElement)) {
894
+ return FALLBACK_SCALE;
895
+ }
896
+ const rect = domElement.getBoundingClientRect();
897
+ const {
898
+ width,
899
+ height,
900
+ fallback
901
+ } = getCssDimensions(domElement);
902
+ let x = (fallback ? round(rect.width) : rect.width) / width;
903
+ let y = (fallback ? round(rect.height) : rect.height) / height;
855
904
 
905
+ // 0, NaN, or Infinity should always fallback to 1.
906
+
907
+ if (!x || !Number.isFinite(x)) {
908
+ x = 1;
909
+ }
910
+ if (!y || !Number.isFinite(y)) {
911
+ y = 1;
912
+ }
913
+ return {
914
+ x,
915
+ y
916
+ };
917
+ }
918
+
919
+ function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
920
+ var _win$visualViewport, _win$visualViewport2;
856
921
  if (includeScale === void 0) {
857
922
  includeScale = false;
858
923
  }
859
-
860
924
  if (isFixedStrategy === void 0) {
861
925
  isFixedStrategy = false;
862
926
  }
863
-
864
927
  const clientRect = element.getBoundingClientRect();
865
- let scaleX = 1;
866
- let scaleY = 1;
867
-
868
- if (includeScale && isHTMLElement(element)) {
869
- scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;
870
- scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;
928
+ const domElement = unwrapElement(element);
929
+ let scale = FALLBACK_SCALE;
930
+ if (includeScale) {
931
+ if (offsetParent) {
932
+ if (isElement(offsetParent)) {
933
+ scale = getScale(offsetParent);
934
+ }
935
+ } else {
936
+ scale = getScale(element);
937
+ }
938
+ }
939
+ const win = domElement ? getWindow(domElement) : window;
940
+ const addVisualOffsets = isClientRectVisualViewportBased() && isFixedStrategy;
941
+ let x = (clientRect.left + (addVisualOffsets ? ((_win$visualViewport = win.visualViewport) == null ? void 0 : _win$visualViewport.offsetLeft) || 0 : 0)) / scale.x;
942
+ let y = (clientRect.top + (addVisualOffsets ? ((_win$visualViewport2 = win.visualViewport) == null ? void 0 : _win$visualViewport2.offsetTop) || 0 : 0)) / scale.y;
943
+ let width = clientRect.width / scale.x;
944
+ let height = clientRect.height / scale.y;
945
+ if (domElement) {
946
+ const win = getWindow(domElement);
947
+ const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
948
+ let currentIFrame = win.frameElement;
949
+ while (currentIFrame && offsetParent && offsetWin !== win) {
950
+ const iframeScale = getScale(currentIFrame);
951
+ const iframeRect = currentIFrame.getBoundingClientRect();
952
+ const css = getComputedStyle(currentIFrame);
953
+ iframeRect.x += (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
954
+ iframeRect.y += (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
955
+ x *= iframeScale.x;
956
+ y *= iframeScale.y;
957
+ width *= iframeScale.x;
958
+ height *= iframeScale.y;
959
+ x += iframeRect.x;
960
+ y += iframeRect.y;
961
+ currentIFrame = getWindow(currentIFrame).frameElement;
962
+ }
871
963
  }
872
-
873
- const win = isElement(element) ? getWindow(element) : window;
874
- const addVisualOffsets = !isLayoutViewport() && isFixedStrategy;
875
- 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;
876
- 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;
877
- const width = clientRect.width / scaleX;
878
- const height = clientRect.height / scaleY;
879
964
  return {
880
965
  width,
881
966
  height,
@@ -899,133 +984,12 @@ function getNodeScroll(element) {
899
984
  scrollTop: element.scrollTop
900
985
  };
901
986
  }
902
-
903
987
  return {
904
988
  scrollLeft: element.pageXOffset,
905
989
  scrollTop: element.pageYOffset
906
990
  };
907
991
  }
908
992
 
909
- function getWindowScrollBarX(element) {
910
- // If <html> has a CSS width greater than the viewport, then this will be
911
- // incorrect for RTL.
912
- return getBoundingClientRect(getDocumentElement(element)).left + getNodeScroll(element).scrollLeft;
913
- }
914
-
915
- function isScaled(element) {
916
- const rect = getBoundingClientRect(element);
917
- return round(rect.width) !== element.offsetWidth || round(rect.height) !== element.offsetHeight;
918
- }
919
-
920
- function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
921
- const isOffsetParentAnElement = isHTMLElement(offsetParent);
922
- const documentElement = getDocumentElement(offsetParent);
923
- const rect = getBoundingClientRect(element, // @ts-ignore - checked above (TS 4.1 compat)
924
- isOffsetParentAnElement && isScaled(offsetParent), strategy === 'fixed');
925
- let scroll = {
926
- scrollLeft: 0,
927
- scrollTop: 0
928
- };
929
- const offsets = {
930
- x: 0,
931
- y: 0
932
- };
933
-
934
- if (isOffsetParentAnElement || !isOffsetParentAnElement && strategy !== 'fixed') {
935
- if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
936
- scroll = getNodeScroll(offsetParent);
937
- }
938
-
939
- if (isHTMLElement(offsetParent)) {
940
- const offsetRect = getBoundingClientRect(offsetParent, true);
941
- offsets.x = offsetRect.x + offsetParent.clientLeft;
942
- offsets.y = offsetRect.y + offsetParent.clientTop;
943
- } else if (documentElement) {
944
- offsets.x = getWindowScrollBarX(documentElement);
945
- }
946
- }
947
-
948
- return {
949
- x: rect.left + scroll.scrollLeft - offsets.x,
950
- y: rect.top + scroll.scrollTop - offsets.y,
951
- width: rect.width,
952
- height: rect.height
953
- };
954
- }
955
-
956
- function getParentNode(node) {
957
- if (getNodeName(node) === 'html') {
958
- return node;
959
- }
960
-
961
- return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle
962
- // @ts-ignore
963
- node.assignedSlot || // step into the shadow DOM of the parent of a slotted node
964
- node.parentNode || ( // DOM Element detected
965
- isShadowRoot(node) ? node.host : null) || // ShadowRoot detected
966
- getDocumentElement(node) // fallback
967
-
968
- );
969
- }
970
-
971
- function getTrueOffsetParent(element) {
972
- if (!isHTMLElement(element) || getComputedStyle(element).position === 'fixed') {
973
- return null;
974
- }
975
-
976
- return element.offsetParent;
977
- }
978
-
979
- function getContainingBlock(element) {
980
- let currentNode = getParentNode(element);
981
-
982
- if (isShadowRoot(currentNode)) {
983
- currentNode = currentNode.host;
984
- }
985
-
986
- while (isHTMLElement(currentNode) && !['html', 'body'].includes(getNodeName(currentNode))) {
987
- if (isContainingBlock(currentNode)) {
988
- return currentNode;
989
- } else {
990
- currentNode = currentNode.parentNode;
991
- }
992
- }
993
-
994
- return null;
995
- } // Gets the closest ancestor positioned element. Handles some edge cases,
996
- // such as table ancestors and cross browser bugs.
997
-
998
-
999
- function getOffsetParent(element) {
1000
- const window = getWindow(element);
1001
- let offsetParent = getTrueOffsetParent(element);
1002
-
1003
- while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') {
1004
- offsetParent = getTrueOffsetParent(offsetParent);
1005
- }
1006
-
1007
- if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static' && !isContainingBlock(offsetParent))) {
1008
- return window;
1009
- }
1010
-
1011
- return offsetParent || getContainingBlock(element) || window;
1012
- }
1013
-
1014
- function getDimensions(element) {
1015
- if (isHTMLElement(element)) {
1016
- return {
1017
- width: element.offsetWidth,
1018
- height: element.offsetHeight
1019
- };
1020
- }
1021
-
1022
- const rect = getBoundingClientRect(element);
1023
- return {
1024
- width: rect.width,
1025
- height: rect.height
1026
- };
1027
- }
1028
-
1029
993
  function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
1030
994
  let {
1031
995
  rect,
@@ -1034,87 +998,59 @@ function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
1034
998
  } = _ref;
1035
999
  const isOffsetParentAnElement = isHTMLElement(offsetParent);
1036
1000
  const documentElement = getDocumentElement(offsetParent);
1037
-
1038
1001
  if (offsetParent === documentElement) {
1039
1002
  return rect;
1040
1003
  }
1041
-
1042
1004
  let scroll = {
1043
1005
  scrollLeft: 0,
1044
1006
  scrollTop: 0
1045
1007
  };
1008
+ let scale = {
1009
+ x: 1,
1010
+ y: 1
1011
+ };
1046
1012
  const offsets = {
1047
1013
  x: 0,
1048
1014
  y: 0
1049
1015
  };
1050
-
1051
1016
  if (isOffsetParentAnElement || !isOffsetParentAnElement && strategy !== 'fixed') {
1052
1017
  if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
1053
1018
  scroll = getNodeScroll(offsetParent);
1054
1019
  }
1055
-
1056
1020
  if (isHTMLElement(offsetParent)) {
1057
- const offsetRect = getBoundingClientRect(offsetParent, true);
1021
+ const offsetRect = getBoundingClientRect(offsetParent);
1022
+ scale = getScale(offsetParent);
1058
1023
  offsets.x = offsetRect.x + offsetParent.clientLeft;
1059
1024
  offsets.y = offsetRect.y + offsetParent.clientTop;
1060
- } // This doesn't appear to be need to be negated.
1061
- // else if (documentElement) {
1062
- // offsets.x = getWindowScrollBarX(documentElement);
1063
- // }
1064
-
1065
- }
1066
-
1067
- return { ...rect,
1068
- x: rect.x - scroll.scrollLeft + offsets.x,
1069
- y: rect.y - scroll.scrollTop + offsets.y
1070
- };
1071
- }
1072
-
1073
- function getViewportRect(element, strategy) {
1074
- const win = getWindow(element);
1075
- const html = getDocumentElement(element);
1076
- const visualViewport = win.visualViewport;
1077
- let width = html.clientWidth;
1078
- let height = html.clientHeight;
1079
- let x = 0;
1080
- let y = 0;
1081
-
1082
- if (visualViewport) {
1083
- width = visualViewport.width;
1084
- height = visualViewport.height;
1085
- const layoutViewport = isLayoutViewport();
1086
-
1087
- if (layoutViewport || !layoutViewport && strategy === 'fixed') {
1088
- x = visualViewport.offsetLeft;
1089
- y = visualViewport.offsetTop;
1090
1025
  }
1091
1026
  }
1092
-
1093
1027
  return {
1094
- width,
1095
- height,
1096
- x,
1097
- y
1028
+ width: rect.width * scale.x,
1029
+ height: rect.height * scale.y,
1030
+ x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x,
1031
+ y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y
1098
1032
  };
1099
1033
  }
1100
1034
 
1101
- // of the `<html>` and `<body>` rect bounds if horizontally scrollable
1035
+ function getWindowScrollBarX(element) {
1036
+ // If <html> has a CSS width greater than the viewport, then this will be
1037
+ // incorrect for RTL.
1038
+ return getBoundingClientRect(getDocumentElement(element)).left + getNodeScroll(element).scrollLeft;
1039
+ }
1102
1040
 
1041
+ // Gets the entire size of the scrollable document area, even extending outside
1042
+ // of the `<html>` and `<body>` rect bounds if horizontally scrollable.
1103
1043
  function getDocumentRect(element) {
1104
- var _element$ownerDocumen;
1105
-
1106
1044
  const html = getDocumentElement(element);
1107
1045
  const scroll = getNodeScroll(element);
1108
- const body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;
1109
- const width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);
1110
- const height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);
1046
+ const body = element.ownerDocument.body;
1047
+ const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
1048
+ const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
1111
1049
  let x = -scroll.scrollLeft + getWindowScrollBarX(element);
1112
1050
  const y = -scroll.scrollTop;
1113
-
1114
- if (getComputedStyle$1(body || html).direction === 'rtl') {
1115
- x += max(html.clientWidth, body ? body.clientWidth : 0) - width;
1051
+ if (getComputedStyle$1(body).direction === 'rtl') {
1052
+ x += max(html.clientWidth, body.clientWidth) - width;
1116
1053
  }
1117
-
1118
1054
  return {
1119
1055
  width,
1120
1056
  height,
@@ -1123,106 +1059,150 @@ function getDocumentRect(element) {
1123
1059
  };
1124
1060
  }
1125
1061
 
1062
+ function getParentNode(node) {
1063
+ if (getNodeName(node) === 'html') {
1064
+ return node;
1065
+ }
1066
+ const result =
1067
+ // Step into the shadow DOM of the parent of a slotted node.
1068
+ node.assignedSlot ||
1069
+ // DOM Element detected.
1070
+ node.parentNode ||
1071
+ // ShadowRoot detected.
1072
+ isShadowRoot(node) && node.host ||
1073
+ // Fallback.
1074
+ getDocumentElement(node);
1075
+ return isShadowRoot(result) ? result.host : result;
1076
+ }
1077
+
1126
1078
  function getNearestOverflowAncestor(node) {
1127
1079
  const parentNode = getParentNode(node);
1128
-
1129
- if (['html', 'body', '#document'].includes(getNodeName(parentNode))) {
1130
- // @ts-ignore assume body is always available
1131
- return node.ownerDocument.body;
1080
+ if (isLastTraversableNode(parentNode)) {
1081
+ // `getParentNode` will never return a `Document` due to the fallback
1082
+ // check, so it's either the <html> or <body> element.
1083
+ return parentNode.ownerDocument.body;
1132
1084
  }
1133
-
1134
1085
  if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
1135
1086
  return parentNode;
1136
1087
  }
1137
-
1138
1088
  return getNearestOverflowAncestor(parentNode);
1139
1089
  }
1140
1090
 
1141
1091
  function getOverflowAncestors(node, list) {
1142
1092
  var _node$ownerDocument;
1143
-
1144
1093
  if (list === void 0) {
1145
1094
  list = [];
1146
1095
  }
1147
-
1148
1096
  const scrollableAncestor = getNearestOverflowAncestor(node);
1149
1097
  const isBody = scrollableAncestor === ((_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.body);
1150
1098
  const win = getWindow(scrollableAncestor);
1151
- const target = isBody ? [win].concat(win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : []) : scrollableAncestor;
1152
- const updatedList = list.concat(target);
1153
- return isBody ? updatedList : // @ts-ignore: isBody tells us target will be an HTMLElement here
1154
- updatedList.concat(getOverflowAncestors(target));
1099
+ if (isBody) {
1100
+ return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : []);
1101
+ }
1102
+ return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor));
1155
1103
  }
1156
1104
 
1157
- function contains(parent, child) {
1158
- const rootNode = child.getRootNode == null ? void 0 : child.getRootNode(); // First, attempt with faster native method
1159
-
1160
- if (parent.contains(child)) {
1161
- return true;
1162
- } // then fallback to custom implementation with Shadow DOM support
1163
- else if (rootNode && isShadowRoot(rootNode)) {
1164
- let next = child;
1165
-
1166
- do {
1167
- // use `===` replace node.isSameNode()
1168
- if (next && parent === next) {
1169
- return true;
1170
- } // @ts-ignore: need a better way to handle this...
1171
-
1172
-
1173
- next = next.parentNode || next.host;
1174
- } while (next);
1105
+ function getViewportRect(element, strategy) {
1106
+ const win = getWindow(element);
1107
+ const html = getDocumentElement(element);
1108
+ const visualViewport = win.visualViewport;
1109
+ let width = html.clientWidth;
1110
+ let height = html.clientHeight;
1111
+ let x = 0;
1112
+ let y = 0;
1113
+ if (visualViewport) {
1114
+ width = visualViewport.width;
1115
+ height = visualViewport.height;
1116
+ const visualViewportBased = isClientRectVisualViewportBased();
1117
+ if (!visualViewportBased || visualViewportBased && strategy === 'fixed') {
1118
+ x = visualViewport.offsetLeft;
1119
+ y = visualViewport.offsetTop;
1120
+ }
1175
1121
  }
1176
-
1177
- return false;
1122
+ return {
1123
+ width,
1124
+ height,
1125
+ x,
1126
+ y
1127
+ };
1178
1128
  }
1179
1129
 
1130
+ // Returns the inner client rect, subtracting scrollbars if present.
1180
1131
  function getInnerBoundingClientRect(element, strategy) {
1181
- const clientRect = getBoundingClientRect(element, false, strategy === 'fixed');
1132
+ const clientRect = getBoundingClientRect(element, true, strategy === 'fixed');
1182
1133
  const top = clientRect.top + element.clientTop;
1183
1134
  const left = clientRect.left + element.clientLeft;
1135
+ const scale = isHTMLElement(element) ? getScale(element) : {
1136
+ x: 1,
1137
+ y: 1
1138
+ };
1139
+ const width = element.clientWidth * scale.x;
1140
+ const height = element.clientHeight * scale.y;
1141
+ const x = left * scale.x;
1142
+ const y = top * scale.y;
1184
1143
  return {
1185
- top,
1186
- left,
1187
- x: left,
1188
- y: top,
1189
- right: left + element.clientWidth,
1190
- bottom: top + element.clientHeight,
1191
- width: element.clientWidth,
1192
- height: element.clientHeight
1144
+ width,
1145
+ height,
1146
+ x,
1147
+ y
1193
1148
  };
1194
1149
  }
1195
-
1196
- function getClientRectFromClippingAncestor(element, clippingParent, strategy) {
1197
- if (clippingParent === 'viewport') {
1198
- return rectToClientRect(getViewportRect(element, strategy));
1150
+ function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
1151
+ let rect;
1152
+ if (clippingAncestor === 'viewport') {
1153
+ rect = getViewportRect(element, strategy);
1154
+ } else if (clippingAncestor === 'document') {
1155
+ rect = getDocumentRect(getDocumentElement(element));
1156
+ } else if (isElement(clippingAncestor)) {
1157
+ rect = getInnerBoundingClientRect(clippingAncestor, strategy);
1158
+ } else {
1159
+ const mutableRect = {
1160
+ ...clippingAncestor
1161
+ };
1162
+ if (isClientRectVisualViewportBased()) {
1163
+ var _win$visualViewport, _win$visualViewport2;
1164
+ const win = getWindow(element);
1165
+ mutableRect.x -= ((_win$visualViewport = win.visualViewport) == null ? void 0 : _win$visualViewport.offsetLeft) || 0;
1166
+ mutableRect.y -= ((_win$visualViewport2 = win.visualViewport) == null ? void 0 : _win$visualViewport2.offsetTop) || 0;
1167
+ }
1168
+ rect = mutableRect;
1199
1169
  }
1170
+ return rectToClientRect(rect);
1171
+ }
1200
1172
 
1201
- if (isElement(clippingParent)) {
1202
- return getInnerBoundingClientRect(clippingParent, strategy);
1173
+ // A "clipping ancestor" is an `overflow` element with the characteristic of
1174
+ // clipping (or hiding) child elements. This returns all clipping ancestors
1175
+ // of the given element up the tree.
1176
+ function getClippingElementAncestors(element, cache) {
1177
+ const cachedResult = cache.get(element);
1178
+ if (cachedResult) {
1179
+ return cachedResult;
1203
1180
  }
1181
+ let result = getOverflowAncestors(element).filter(el => isElement(el) && getNodeName(el) !== 'body');
1182
+ let currentContainingBlockComputedStyle = null;
1183
+ const elementIsFixed = getComputedStyle$1(element).position === 'fixed';
1184
+ let currentNode = elementIsFixed ? getParentNode(element) : element;
1204
1185
 
1205
- return rectToClientRect(getDocumentRect(getDocumentElement(element)));
1206
- } // A "clipping ancestor" is an overflowable container with the characteristic of
1207
- // clipping (or hiding) overflowing elements with a position different from
1208
- // `initial`
1209
-
1210
-
1211
- function getClippingAncestors(element) {
1212
- const clippingAncestors = getOverflowAncestors(element);
1213
- const canEscapeClipping = ['absolute', 'fixed'].includes(getComputedStyle$1(element).position);
1214
- const clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;
1215
-
1216
- if (!isElement(clipperElement)) {
1217
- return [];
1218
- } // @ts-ignore isElement check ensures we return Array<Element>
1219
-
1220
-
1221
- return clippingAncestors.filter(clippingAncestors => isElement(clippingAncestors) && contains(clippingAncestors, clipperElement) && getNodeName(clippingAncestors) !== 'body');
1222
- } // Gets the maximum area that the element is visible in due to any number of
1223
- // clipping ancestors
1224
-
1186
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
1187
+ while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
1188
+ const computedStyle = getComputedStyle$1(currentNode);
1189
+ const containingBlock = isContainingBlock(currentNode);
1190
+ const shouldDropCurrentNode = elementIsFixed ? !containingBlock && !currentContainingBlockComputedStyle : !containingBlock && computedStyle.position === 'static' && !!currentContainingBlockComputedStyle && ['absolute', 'fixed'].includes(currentContainingBlockComputedStyle.position);
1191
+ if (shouldDropCurrentNode) {
1192
+ // Drop non-containing blocks.
1193
+ result = result.filter(ancestor => ancestor !== currentNode);
1194
+ } else {
1195
+ // Record last containing block for next iteration.
1196
+ currentContainingBlockComputedStyle = computedStyle;
1197
+ }
1198
+ currentNode = getParentNode(currentNode);
1199
+ }
1200
+ cache.set(element, result);
1201
+ return result;
1202
+ }
1225
1203
 
1204
+ // Gets the maximum area that the element is visible in due to any number of
1205
+ // clipping ancestors.
1226
1206
  function getClippingRect(_ref) {
1227
1207
  let {
1228
1208
  element,
@@ -1230,8 +1210,8 @@ function getClippingRect(_ref) {
1230
1210
  rootBoundary,
1231
1211
  strategy
1232
1212
  } = _ref;
1233
- const mainClippingAncestors = boundary === 'clippingAncestors' ? getClippingAncestors(element) : [].concat(boundary);
1234
- const clippingAncestors = [...mainClippingAncestors, rootBoundary];
1213
+ const elementClippingAncestors = boundary === 'clippingAncestors' ? getClippingElementAncestors(element, this._c) : [].concat(boundary);
1214
+ const clippingAncestors = [...elementClippingAncestors, rootBoundary];
1235
1215
  const firstClippingAncestor = clippingAncestors[0];
1236
1216
  const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => {
1237
1217
  const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy);
@@ -1249,6 +1229,80 @@ function getClippingRect(_ref) {
1249
1229
  };
1250
1230
  }
1251
1231
 
1232
+ function getDimensions(element) {
1233
+ if (isHTMLElement(element)) {
1234
+ return getCssDimensions(element);
1235
+ }
1236
+ return element.getBoundingClientRect();
1237
+ }
1238
+
1239
+ function getTrueOffsetParent(element, polyfill) {
1240
+ if (!isHTMLElement(element) || getComputedStyle$1(element).position === 'fixed') {
1241
+ return null;
1242
+ }
1243
+ if (polyfill) {
1244
+ return polyfill(element);
1245
+ }
1246
+ return element.offsetParent;
1247
+ }
1248
+ function getContainingBlock(element) {
1249
+ let currentNode = getParentNode(element);
1250
+ while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
1251
+ if (isContainingBlock(currentNode)) {
1252
+ return currentNode;
1253
+ } else {
1254
+ currentNode = getParentNode(currentNode);
1255
+ }
1256
+ }
1257
+ return null;
1258
+ }
1259
+
1260
+ // Gets the closest ancestor positioned element. Handles some edge cases,
1261
+ // such as table ancestors and cross browser bugs.
1262
+ function getOffsetParent(element, polyfill) {
1263
+ const window = getWindow(element);
1264
+ let offsetParent = getTrueOffsetParent(element, polyfill);
1265
+ while (offsetParent && isTableElement(offsetParent) && getComputedStyle$1(offsetParent).position === 'static') {
1266
+ offsetParent = getTrueOffsetParent(offsetParent, polyfill);
1267
+ }
1268
+ if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle$1(offsetParent).position === 'static' && !isContainingBlock(offsetParent))) {
1269
+ return window;
1270
+ }
1271
+ return offsetParent || getContainingBlock(element) || window;
1272
+ }
1273
+
1274
+ function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
1275
+ const isOffsetParentAnElement = isHTMLElement(offsetParent);
1276
+ const documentElement = getDocumentElement(offsetParent);
1277
+ const rect = getBoundingClientRect(element, true, strategy === 'fixed', offsetParent);
1278
+ let scroll = {
1279
+ scrollLeft: 0,
1280
+ scrollTop: 0
1281
+ };
1282
+ const offsets = {
1283
+ x: 0,
1284
+ y: 0
1285
+ };
1286
+ if (isOffsetParentAnElement || !isOffsetParentAnElement && strategy !== 'fixed') {
1287
+ if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
1288
+ scroll = getNodeScroll(offsetParent);
1289
+ }
1290
+ if (isHTMLElement(offsetParent)) {
1291
+ const offsetRect = getBoundingClientRect(offsetParent, true);
1292
+ offsets.x = offsetRect.x + offsetParent.clientLeft;
1293
+ offsets.y = offsetRect.y + offsetParent.clientTop;
1294
+ } else if (documentElement) {
1295
+ offsets.x = getWindowScrollBarX(documentElement);
1296
+ }
1297
+ }
1298
+ return {
1299
+ x: rect.left + scroll.scrollLeft - offsets.x,
1300
+ y: rect.top + scroll.scrollTop - offsets.y,
1301
+ width: rect.width,
1302
+ height: rect.height
1303
+ };
1304
+ }
1305
+
1252
1306
  const platform = {
1253
1307
  getClippingRect,
1254
1308
  convertOffsetParentRelativeRectToViewportRelativeRect,
@@ -1256,17 +1310,21 @@ const platform = {
1256
1310
  getDimensions,
1257
1311
  getOffsetParent,
1258
1312
  getDocumentElement,
1259
- getElementRects: _ref => {
1313
+ getScale,
1314
+ async getElementRects(_ref) {
1260
1315
  let {
1261
1316
  reference,
1262
1317
  floating,
1263
1318
  strategy
1264
1319
  } = _ref;
1320
+ const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
1321
+ const getDimensionsFn = this.getDimensions;
1265
1322
  return {
1266
- reference: getRectRelativeToOffsetParent(reference, getOffsetParent(floating), strategy),
1267
- floating: { ...getDimensions(floating),
1323
+ reference: getRectRelativeToOffsetParent(reference, await getOffsetParentFn(floating), strategy),
1324
+ floating: {
1268
1325
  x: 0,
1269
- y: 0
1326
+ y: 0,
1327
+ ...(await getDimensionsFn(floating))
1270
1328
  }
1271
1329
  };
1272
1330
  },
@@ -1282,16 +1340,14 @@ function autoUpdate(reference, floating, update, options) {
1282
1340
  if (options === void 0) {
1283
1341
  options = {};
1284
1342
  }
1285
-
1286
1343
  const {
1287
1344
  ancestorScroll: _ancestorScroll = true,
1288
- ancestorResize: _ancestorResize = true,
1345
+ ancestorResize = true,
1289
1346
  elementResize = true,
1290
1347
  animationFrame = false
1291
1348
  } = options;
1292
1349
  const ancestorScroll = _ancestorScroll && !animationFrame;
1293
- const ancestorResize = _ancestorResize && !animationFrame;
1294
- const ancestors = ancestorScroll || ancestorResize ? [...(isElement(reference) ? getOverflowAncestors(reference) : []), ...getOverflowAncestors(floating)] : [];
1350
+ const ancestors = ancestorScroll || ancestorResize ? [...(isElement(reference) ? getOverflowAncestors(reference) : reference.contextElement ? getOverflowAncestors(reference.contextElement) : []), ...getOverflowAncestors(floating)] : [];
1295
1351
  ancestors.forEach(ancestor => {
1296
1352
  ancestorScroll && ancestor.addEventListener('scroll', update, {
1297
1353
  passive: true
@@ -1299,49 +1355,42 @@ function autoUpdate(reference, floating, update, options) {
1299
1355
  ancestorResize && ancestor.addEventListener('resize', update);
1300
1356
  });
1301
1357
  let observer = null;
1302
-
1303
1358
  if (elementResize) {
1304
1359
  let initialUpdate = true;
1305
1360
  observer = new ResizeObserver(() => {
1306
1361
  if (!initialUpdate) {
1307
1362
  update();
1308
1363
  }
1309
-
1310
1364
  initialUpdate = false;
1311
1365
  });
1312
1366
  isElement(reference) && !animationFrame && observer.observe(reference);
1367
+ if (!isElement(reference) && reference.contextElement && !animationFrame) {
1368
+ observer.observe(reference.contextElement);
1369
+ }
1313
1370
  observer.observe(floating);
1314
1371
  }
1315
-
1316
1372
  let frameId;
1317
1373
  let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;
1318
-
1319
1374
  if (animationFrame) {
1320
1375
  frameLoop();
1321
1376
  }
1322
-
1323
1377
  function frameLoop() {
1324
1378
  const nextRefRect = getBoundingClientRect(reference);
1325
-
1326
1379
  if (prevRefRect && (nextRefRect.x !== prevRefRect.x || nextRefRect.y !== prevRefRect.y || nextRefRect.width !== prevRefRect.width || nextRefRect.height !== prevRefRect.height)) {
1327
1380
  update();
1328
1381
  }
1329
-
1330
1382
  prevRefRect = nextRefRect;
1331
1383
  frameId = requestAnimationFrame(frameLoop);
1332
1384
  }
1333
-
1334
1385
  update();
1335
1386
  return () => {
1336
1387
  var _observer;
1337
-
1338
1388
  ancestors.forEach(ancestor => {
1339
1389
  ancestorScroll && ancestor.removeEventListener('scroll', update);
1340
1390
  ancestorResize && ancestor.removeEventListener('resize', update);
1341
1391
  });
1342
1392
  (_observer = observer) == null ? void 0 : _observer.disconnect();
1343
1393
  observer = null;
1344
-
1345
1394
  if (animationFrame) {
1346
1395
  cancelAnimationFrame(frameId);
1347
1396
  }
@@ -1353,11 +1402,24 @@ function autoUpdate(reference, floating, update, options) {
1353
1402
  * next to a reference element when it is given a certain CSS positioning
1354
1403
  * strategy.
1355
1404
  */
1356
-
1357
- const computePosition = (reference, floating, options) => computePosition$1(reference, floating, {
1358
- platform,
1359
- ...options
1360
- });
1405
+ const computePosition = (reference, floating, options) => {
1406
+ // This caches the expensive `getClippingElementAncestors` function so that
1407
+ // multiple lifecycle resets re-use the same result. It only lives for a
1408
+ // single call. If other functions become expensive, we can add them as well.
1409
+ const cache = new Map();
1410
+ const mergedOptions = {
1411
+ platform,
1412
+ ...options
1413
+ };
1414
+ const platformWithCache = {
1415
+ ...mergedOptions.platform,
1416
+ _c: cache
1417
+ };
1418
+ return computePosition$1(reference, floating, {
1419
+ ...mergedOptions,
1420
+ platform: platformWithCache
1421
+ });
1422
+ };
1361
1423
 
1362
1424
  var _Popup_instances, _Popup_arrowPosition_get, _Popup_padding_get, _Popup_distance_get, _Popup_middleware_get, _Popup_cleanup, _Popup_assignPopupPosition, _Popup_assignArrowPosition, _Popup_getAnchor;
1363
1425
  class Popup extends FoundationElement {
@@ -1390,7 +1452,7 @@ class Popup extends FoundationElement {
1390
1452
  }
1391
1453
  case 'open':
1392
1454
  {
1393
- this.open ? this.showPopover() : this.hidePopover();
1455
+ this.open ? this.show() : this.hide();
1394
1456
  break;
1395
1457
  }
1396
1458
  }
@@ -1414,17 +1476,11 @@ class Popup extends FoundationElement {
1414
1476
  __classPrivateFieldGet(this, _Popup_instances, "m", _Popup_assignArrowPosition).call(this, positionData);
1415
1477
  }
1416
1478
  }
1417
- showPopover() {
1418
- if (!this.classList.contains(':open')) {
1419
- super.showPopover();
1420
- }
1421
- this.open = this.classList.contains(':open');
1479
+ show() {
1480
+ this.open = true;
1422
1481
  }
1423
- hidePopover() {
1424
- if (this.classList.contains(':open')) {
1425
- super.hidePopover();
1426
- }
1427
- this.open = this.classList.contains(':open');
1482
+ hide() {
1483
+ this.open = false;
1428
1484
  }
1429
1485
  }
1430
1486
  _Popup_cleanup = new WeakMap(), _Popup_instances = new WeakSet(), _Popup_arrowPosition_get = function _Popup_arrowPosition_get() {
@@ -1526,311 +1582,6 @@ const popupTemplate = context => {
1526
1582
  class="dismissible-button" icon="close-small-solid" shape="pill"></${0}>`), buttonTag, x => x.open = false, buttonTag)), when(x => x.arrow, html(_t3 || (_t3 = _`<div class="arrow" ${0}></div>`), ref('arrowEl'))), elevationTag);
1527
1583
  };
1528
1584
 
1529
- // node_modules/query-selector-shadow-dom/src/normalize.js
1530
- function normalizeSelector(sel) {
1531
- function saveUnmatched() {
1532
- if (unmatched) {
1533
- if (tokens.length > 0 && /^[~+>]$/.test(tokens[tokens.length - 1])) {
1534
- tokens.push(" ");
1535
- }
1536
- tokens.push(unmatched);
1537
- }
1538
- }
1539
- var tokens = [], match, unmatched, regex, state = [0], next_match_idx = 0, prev_match_idx, not_escaped_pattern = /(?:[^\\]|(?:^|[^\\])(?:\\\\)+)$/, whitespace_pattern = /^\s+$/, state_patterns = [
1540
- /\s+|\/\*|["'>~+[(]/g,
1541
- /\s+|\/\*|["'[\]()]/g,
1542
- /\s+|\/\*|["'[\]()]/g,
1543
- null,
1544
- /\*\//g
1545
- ];
1546
- sel = sel.trim();
1547
- while (true) {
1548
- unmatched = "";
1549
- regex = state_patterns[state[state.length - 1]];
1550
- regex.lastIndex = next_match_idx;
1551
- match = regex.exec(sel);
1552
- if (match) {
1553
- prev_match_idx = next_match_idx;
1554
- next_match_idx = regex.lastIndex;
1555
- if (prev_match_idx < next_match_idx - match[0].length) {
1556
- unmatched = sel.substring(
1557
- prev_match_idx,
1558
- next_match_idx - match[0].length
1559
- );
1560
- }
1561
- if (state[state.length - 1] < 3) {
1562
- saveUnmatched();
1563
- if (match[0] === "[") {
1564
- state.push(1);
1565
- } else if (match[0] === "(") {
1566
- state.push(2);
1567
- } else if (/^["']$/.test(match[0])) {
1568
- state.push(3);
1569
- state_patterns[3] = new RegExp(match[0], "g");
1570
- } else if (match[0] === "/*") {
1571
- state.push(4);
1572
- } else if (/^[\])]$/.test(match[0]) && state.length > 0) {
1573
- state.pop();
1574
- } else if (/^(?:\s+|[~+>])$/.test(match[0])) {
1575
- if (tokens.length > 0 && !whitespace_pattern.test(tokens[tokens.length - 1]) && state[state.length - 1] === 0) {
1576
- tokens.push(" ");
1577
- }
1578
- if (state[state.length - 1] === 1 && tokens.length === 5 && tokens[2].charAt(tokens[2].length - 1) === "=") {
1579
- tokens[4] = " " + tokens[4];
1580
- }
1581
- if (whitespace_pattern.test(match[0])) {
1582
- continue;
1583
- }
1584
- }
1585
- tokens.push(match[0]);
1586
- } else {
1587
- tokens[tokens.length - 1] += unmatched;
1588
- if (not_escaped_pattern.test(tokens[tokens.length - 1])) {
1589
- if (state[state.length - 1] === 4) {
1590
- if (tokens.length < 2 || whitespace_pattern.test(tokens[tokens.length - 2])) {
1591
- tokens.pop();
1592
- } else {
1593
- tokens[tokens.length - 1] = " ";
1594
- }
1595
- match[0] = "";
1596
- }
1597
- state.pop();
1598
- }
1599
- tokens[tokens.length - 1] += match[0];
1600
- }
1601
- } else {
1602
- unmatched = sel.substr(next_match_idx);
1603
- saveUnmatched();
1604
- break;
1605
- }
1606
- }
1607
- return tokens.join("").trim();
1608
- }
1609
-
1610
- // node_modules/query-selector-shadow-dom/src/querySelectorDeep.js
1611
- function querySelectorAllDeep(selector, root = document, allElements = null) {
1612
- return _querySelectorDeep(selector, true, root, allElements);
1613
- }
1614
- function _querySelectorDeep(selector, findMany, root, allElements = null) {
1615
- selector = normalizeSelector(selector);
1616
- let lightElement = root.querySelector(selector);
1617
- if (document.head.createShadowRoot || document.head.attachShadow) {
1618
- if (!findMany && lightElement) {
1619
- return lightElement;
1620
- }
1621
- const selectionsToMake = splitByCharacterUnlessQuoted(selector, ",");
1622
- return selectionsToMake.reduce((acc, minimalSelector) => {
1623
- if (!findMany && acc) {
1624
- return acc;
1625
- }
1626
- const splitSelector = splitByCharacterUnlessQuoted(minimalSelector.replace(/^\s+/g, "").replace(/\s*([>+~]+)\s*/g, "$1"), " ").filter((entry) => !!entry).map((entry) => splitByCharacterUnlessQuoted(entry, ">"));
1627
- const possibleElementsIndex = splitSelector.length - 1;
1628
- const lastSplitPart = splitSelector[possibleElementsIndex][splitSelector[possibleElementsIndex].length - 1];
1629
- const possibleElements = collectAllElementsDeep(lastSplitPart, root, allElements);
1630
- const findElements = findMatchingElement(splitSelector, possibleElementsIndex, root);
1631
- if (findMany) {
1632
- acc = acc.concat(possibleElements.filter(findElements));
1633
- return acc;
1634
- } else {
1635
- acc = possibleElements.find(findElements);
1636
- return acc || null;
1637
- }
1638
- }, findMany ? [] : null);
1639
- } else {
1640
- if (!findMany) {
1641
- return lightElement;
1642
- } else {
1643
- return root.querySelectorAll(selector);
1644
- }
1645
- }
1646
- }
1647
- function findMatchingElement(splitSelector, possibleElementsIndex, root) {
1648
- return (element) => {
1649
- let position = possibleElementsIndex;
1650
- let parent = element;
1651
- let foundElement = false;
1652
- while (parent && !isDocumentNode(parent)) {
1653
- let foundMatch = true;
1654
- if (splitSelector[position].length === 1) {
1655
- foundMatch = parent.matches(splitSelector[position]);
1656
- } else {
1657
- const reversedParts = [].concat(splitSelector[position]).reverse();
1658
- let newParent = parent;
1659
- for (const part of reversedParts) {
1660
- if (!newParent || !newParent.matches(part)) {
1661
- foundMatch = false;
1662
- break;
1663
- }
1664
- newParent = findParentOrHost(newParent, root);
1665
- }
1666
- }
1667
- if (foundMatch && position === 0) {
1668
- foundElement = true;
1669
- break;
1670
- }
1671
- if (foundMatch) {
1672
- position--;
1673
- }
1674
- parent = findParentOrHost(parent, root);
1675
- }
1676
- return foundElement;
1677
- };
1678
- }
1679
- function splitByCharacterUnlessQuoted(selector, character) {
1680
- return selector.match(/\\?.|^$/g).reduce((p, c) => {
1681
- if (c === '"' && !p.sQuote) {
1682
- p.quote ^= 1;
1683
- p.a[p.a.length - 1] += c;
1684
- } else if (c === "'" && !p.quote) {
1685
- p.sQuote ^= 1;
1686
- p.a[p.a.length - 1] += c;
1687
- } else if (!p.quote && !p.sQuote && c === character) {
1688
- p.a.push("");
1689
- } else {
1690
- p.a[p.a.length - 1] += c;
1691
- }
1692
- return p;
1693
- }, { a: [""] }).a;
1694
- }
1695
- function isDocumentNode(node) {
1696
- return node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.DOCUMENT_NODE;
1697
- }
1698
- function findParentOrHost(element, root) {
1699
- const parentNode = element.parentNode;
1700
- return parentNode && parentNode.host && parentNode.nodeType === 11 ? parentNode.host : parentNode === root ? null : parentNode;
1701
- }
1702
- function collectAllElementsDeep(selector = null, root, cachedElements = null) {
1703
- let allElements = [];
1704
- if (cachedElements) {
1705
- allElements = cachedElements;
1706
- } else {
1707
- const findAllElements = function (nodes) {
1708
- for (let i = 0; i < nodes.length; i++) {
1709
- const el = nodes[i];
1710
- allElements.push(el);
1711
- if (el.shadowRoot) {
1712
- findAllElements(el.shadowRoot.querySelectorAll("*"));
1713
- }
1714
- }
1715
- };
1716
- if (root.shadowRoot) {
1717
- findAllElements(root.shadowRoot.querySelectorAll("*"));
1718
- }
1719
- findAllElements(root.querySelectorAll("*"));
1720
- }
1721
- return selector ? allElements.filter((el) => el.matches(selector)) : allElements;
1722
- }
1723
-
1724
- // src/popover.ts
1725
- function closestComposed(event) {
1726
- return event.composedPath().find((el) => el instanceof HTMLElement && el.hasAttribute("popover")) || null;
1727
- }
1728
- function isSupported() {
1729
- return typeof HTMLElement !== "undefined" && typeof HTMLElement.prototype === "object" && "popover" in HTMLElement.prototype;
1730
- }
1731
- var notSupportedMessage = "Not supported on element that does not have valid popover attribute";
1732
- function apply() {
1733
- const visibleElements = /* @__PURE__ */ new WeakSet();
1734
- Object.defineProperties(HTMLElement.prototype, {
1735
- popover: {
1736
- enumerable: true,
1737
- configurable: true,
1738
- get() {
1739
- const value = (this.getAttribute("popover") || "").toLowerCase();
1740
- if (value === "manual")
1741
- return "manual";
1742
- if (value === "" || value == "auto")
1743
- return "auto";
1744
- return null;
1745
- },
1746
- set(value) {
1747
- this.setAttribute("popover", value);
1748
- }
1749
- },
1750
- showPopover: {
1751
- enumerable: true,
1752
- configurable: true,
1753
- value() {
1754
- if (!this.popover)
1755
- throw new DOMException(notSupportedMessage, "NotSupportedError");
1756
- if (visibleElements.has(this))
1757
- throw new DOMException(
1758
- "Invalid on already-showing Popovers",
1759
- "InvalidStateError"
1760
- );
1761
- this.classList.add(":open");
1762
- visibleElements.add(this);
1763
- if (this.popover === "auto") {
1764
- const focusEl = this.hasAttribute("autofocus") ? this : this.querySelector("[autofocus]");
1765
- focusEl?.focus();
1766
- }
1767
- }
1768
- },
1769
- hidePopover: {
1770
- enumerable: true,
1771
- configurable: true,
1772
- value() {
1773
- if (!this.popover)
1774
- throw new DOMException(notSupportedMessage, "NotSupportedError");
1775
- if (!visibleElements.has(this))
1776
- throw new DOMException(
1777
- "Invalid on already-hidden Popovers",
1778
- "InvalidStateError"
1779
- );
1780
- this.classList.remove(":open");
1781
- visibleElements.delete(this);
1782
- }
1783
- }
1784
- });
1785
- document.addEventListener("click", (event) => {
1786
- const target = event.target;
1787
- if (!(target instanceof Element))
1788
- return;
1789
- const doc = target.ownerDocument;
1790
- let effectedPopover = closestComposed(event);
1791
- const button = target.closest(
1792
- "[popovertoggletarget],[popoverhidetarget],[popovershowtarget]"
1793
- );
1794
- const isButton = button instanceof HTMLButtonElement;
1795
- if (isButton && button.hasAttribute("popovershowtarget")) {
1796
- effectedPopover = doc.getElementById(
1797
- button.getAttribute("popovershowtarget") || ""
1798
- );
1799
- if (effectedPopover && effectedPopover.popover && !visibleElements.has(effectedPopover)) {
1800
- effectedPopover.showPopover();
1801
- }
1802
- } else if (isButton && button.hasAttribute("popoverhidetarget")) {
1803
- effectedPopover = doc.getElementById(
1804
- button.getAttribute("popoverhidetarget") || ""
1805
- );
1806
- if (effectedPopover && effectedPopover.popover && visibleElements.has(effectedPopover)) {
1807
- effectedPopover.hidePopover();
1808
- }
1809
- } else if (isButton && button.hasAttribute("popovertoggletarget")) {
1810
- effectedPopover = doc.getElementById(
1811
- button.getAttribute("popovertoggletarget") || ""
1812
- );
1813
- if (effectedPopover && effectedPopover.popover) {
1814
- if (visibleElements.has(effectedPopover)) {
1815
- effectedPopover.hidePopover();
1816
- } else {
1817
- effectedPopover.showPopover();
1818
- }
1819
- }
1820
- }
1821
- for (const popover of querySelectorAllDeep(
1822
- '[popover="" i].\\:open, [popover=auto i].\\:open'
1823
- )) {
1824
- if (popover instanceof HTMLElement && popover !== effectedPopover)
1825
- popover.hidePopover();
1826
- }
1827
- });
1828
- }
1829
-
1830
- // src/index.ts
1831
- if (!isSupported())
1832
- apply();
1833
-
1834
1585
  const popupDefinition = Popup.compose({
1835
1586
  baseName: 'popup',
1836
1587
  template: popupTemplate,