@beeq/core 1.13.0 → 1.13.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 (102) hide show
  1. package/dist/beeq/beeq.esm.js +1 -1
  2. package/dist/beeq/index.esm.js +1 -1
  3. package/dist/beeq/index.esm.js.map +1 -1
  4. package/dist/beeq/p-923da026.entry.js +6 -0
  5. package/dist/beeq/p-923da026.entry.js.map +1 -0
  6. package/dist/beeq/p-DXYHHeJY.js +6 -0
  7. package/dist/beeq/p-DXYHHeJY.js.map +1 -0
  8. package/dist/beeq/{p-2fd6ea70.entry.js → p-d4fa3abb.entry.js} +2 -2
  9. package/dist/beeq/p-d4fa3abb.entry.js.map +1 -0
  10. package/dist/beeq/p-seEHHqwi.js +6 -0
  11. package/dist/beeq/p-seEHHqwi.js.map +1 -0
  12. package/dist/beeq/svg/.icons-meta.json +1 -1
  13. package/dist/beeq.html-custom-data.json +74 -74
  14. package/dist/cjs/beeq.cjs.js +1 -1
  15. package/dist/cjs/bq-dropdown_2.cjs.entry.js +12 -6
  16. package/dist/cjs/bq-dropdown_2.cjs.entry.js.map +1 -1
  17. package/dist/cjs/bq-tooltip.cjs.entry.js +76 -14
  18. package/dist/cjs/bq-tooltip.cjs.entry.js.map +1 -1
  19. package/dist/cjs/{index-CfLTYjba.js → index-CVDzXB4K.js} +213 -189
  20. package/dist/cjs/index-CVDzXB4K.js.map +1 -0
  21. package/dist/cjs/index.cjs.js +2 -0
  22. package/dist/cjs/index.cjs.js.map +1 -1
  23. package/dist/cjs/isPopoverSupported-CfD5YIXR.js +18 -0
  24. package/dist/cjs/isPopoverSupported-CfD5YIXR.js.map +1 -0
  25. package/dist/cjs/loader.cjs.js +1 -1
  26. package/dist/collection/components/empty-state/scss/bq-empty-state.css +1 -1
  27. package/dist/collection/components/icon/svg/.icons-meta.json +1 -1
  28. package/dist/collection/components/panel/bq-panel.js +11 -5
  29. package/dist/collection/components/panel/bq-panel.js.map +1 -1
  30. package/dist/collection/components/progress/scss/bq-progress.css +1 -1
  31. package/dist/collection/components/side-menu-item/scss/bq-side-menu-item.css +1 -1
  32. package/dist/collection/components/slider/scss/bq-slider.css +1 -1
  33. package/dist/collection/components/tooltip/bq-tooltip.js +74 -13
  34. package/dist/collection/components/tooltip/bq-tooltip.js.map +1 -1
  35. package/dist/collection/components/tooltip/scss/bq-tooltip.css +1 -1
  36. package/dist/collection/services/interfaces/floating-ui.js.map +1 -1
  37. package/dist/collection/services/libraries/floating-ui/index.js +93 -64
  38. package/dist/collection/services/libraries/floating-ui/index.js.map +1 -1
  39. package/dist/collection/shared/test-utils/setProperties.js +1 -1
  40. package/dist/collection/shared/test-utils/setProperties.js.map +1 -1
  41. package/dist/collection/shared/utils/index.js +1 -0
  42. package/dist/collection/shared/utils/index.js.map +1 -1
  43. package/dist/collection/shared/utils/isPopoverSupported.js +12 -0
  44. package/dist/collection/shared/utils/isPopoverSupported.js.map +1 -0
  45. package/dist/components/bq-date-picker.js +1 -1
  46. package/dist/components/bq-dropdown.js +1 -1
  47. package/dist/components/bq-empty-state.js +1 -1
  48. package/dist/components/bq-empty-state.js.map +1 -1
  49. package/dist/components/bq-panel.js +1 -1
  50. package/dist/components/bq-progress.js +1 -1
  51. package/dist/components/bq-progress.js.map +1 -1
  52. package/dist/components/bq-select.js +1 -1
  53. package/dist/components/bq-side-menu-item.js +1 -1
  54. package/dist/components/bq-side-menu-item.js.map +1 -1
  55. package/dist/components/bq-slider.js +1 -1
  56. package/dist/components/bq-slider.js.map +1 -1
  57. package/dist/components/bq-tooltip.js +1 -1
  58. package/dist/components/index.js +1 -1
  59. package/dist/components/index.js.map +1 -1
  60. package/dist/components/p-B4jdbg-4.js +6 -0
  61. package/dist/components/p-B4jdbg-4.js.map +1 -0
  62. package/dist/components/p-DXYHHeJY.js +6 -0
  63. package/dist/components/p-DXYHHeJY.js.map +1 -0
  64. package/dist/components/{p-BS8hIETL.js → p-_I8PqzzU.js} +2 -2
  65. package/dist/components/{p-iyX-PhkX.js → p-c6L-z8md.js} +2 -2
  66. package/dist/components/p-c6L-z8md.js.map +1 -0
  67. package/dist/custom-elements.json +776 -736
  68. package/dist/esm/beeq.js +1 -1
  69. package/dist/esm/bq-dropdown_2.entry.js +12 -6
  70. package/dist/esm/bq-dropdown_2.entry.js.map +1 -1
  71. package/dist/esm/bq-tooltip.entry.js +76 -14
  72. package/dist/esm/bq-tooltip.entry.js.map +1 -1
  73. package/dist/esm/{index-CSAZnAFf.js → index-DXYHHeJY.js} +213 -189
  74. package/dist/esm/index-DXYHHeJY.js.map +1 -0
  75. package/dist/esm/index.js +1 -0
  76. package/dist/esm/index.js.map +1 -1
  77. package/dist/esm/isPopoverSupported-seEHHqwi.js +16 -0
  78. package/dist/esm/isPopoverSupported-seEHHqwi.js.map +1 -0
  79. package/dist/esm/loader.js +1 -1
  80. package/dist/hydrate/index.js +304 -205
  81. package/dist/hydrate/index.mjs +304 -205
  82. package/dist/types/components/panel/bq-panel.d.ts +1 -0
  83. package/dist/types/components/tooltip/bq-tooltip.d.ts +14 -0
  84. package/dist/types/services/interfaces/floating-ui.d.ts +1 -1
  85. package/dist/types/services/libraries/floating-ui/index.d.ts +37 -14
  86. package/dist/types/shared/test-utils/setProperties.d.ts +1 -1
  87. package/dist/types/shared/utils/index.d.ts +1 -0
  88. package/dist/types/shared/utils/isPopoverSupported.d.ts +2 -0
  89. package/package.json +3 -3
  90. package/dist/beeq/p-2fd6ea70.entry.js.map +0 -1
  91. package/dist/beeq/p-CSAZnAFf.js +0 -6
  92. package/dist/beeq/p-CSAZnAFf.js.map +0 -1
  93. package/dist/beeq/p-a55354ee.entry.js +0 -6
  94. package/dist/beeq/p-a55354ee.entry.js.map +0 -1
  95. package/dist/cjs/index-CfLTYjba.js.map +0 -1
  96. package/dist/components/p-CSAZnAFf.js +0 -6
  97. package/dist/components/p-CSAZnAFf.js.map +0 -1
  98. package/dist/components/p-Dd3v3b2E.js +0 -6
  99. package/dist/components/p-Dd3v3b2E.js.map +0 -1
  100. package/dist/components/p-iyX-PhkX.js.map +0 -1
  101. package/dist/esm/index-CSAZnAFf.js.map +0 -1
  102. /package/dist/components/{p-BS8hIETL.js.map → p-_I8PqzzU.js.map} +0 -0
@@ -102,12 +102,12 @@ function getOppositePlacement(placement) {
102
102
  return oppositeSideMap[side] + placement.slice(side.length);
103
103
  }
104
104
  function expandPaddingObject(padding) {
105
+ var _padding$top, _padding$right, _padding$bottom, _padding$left;
105
106
  return {
106
- top: 0,
107
- right: 0,
108
- bottom: 0,
109
- left: 0,
110
- ...padding
107
+ top: (_padding$top = padding.top) != null ? _padding$top : 0,
108
+ right: (_padding$right = padding.right) != null ? _padding$right : 0,
109
+ bottom: (_padding$bottom = padding.bottom) != null ? _padding$bottom : 0,
110
+ left: (_padding$left = padding.left) != null ? _padding$left : 0
111
111
  };
112
112
  }
113
113
  function getPaddingObject(padding) {
@@ -182,13 +182,9 @@ function computeCoordsFromPlacement(_ref, placement, rtl) {
182
182
  y: reference.y
183
183
  };
184
184
  }
185
- switch (getAlignment(placement)) {
186
- case 'start':
187
- coords[alignmentAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);
188
- break;
189
- case 'end':
190
- coords[alignmentAxis] += commonAlign * (rtl && isVertical ? -1 : 1);
191
- break;
185
+ const alignment = getAlignment(placement);
186
+ if (alignment) {
187
+ coords[alignmentAxis] += commonAlign * (alignment === 'end' ? 1 : -1) * (rtl && isVertical ? -1 : 1);
192
188
  }
193
189
  return coords;
194
190
  }
@@ -237,10 +233,7 @@ async function detectOverflow(state, options) {
237
233
  height: rects.floating.height
238
234
  } : rects.reference;
239
235
  const offsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating));
240
- const offsetScale = (await (platform.isElement == null ? void 0 : platform.isElement(offsetParent))) ? (await (platform.getScale == null ? void 0 : platform.getScale(offsetParent))) || {
241
- x: 1,
242
- y: 1
243
- } : {
236
+ const offsetScale = (await (platform.isElement == null ? void 0 : platform.isElement(offsetParent))) && (await (platform.getScale == null ? void 0 : platform.getScale(offsetParent))) || {
244
237
  x: 1,
245
238
  y: 1
246
239
  };
@@ -413,17 +406,16 @@ const arrow$1 = options => ({
413
406
 
414
407
  // Make sure the arrow doesn't overflow the floating element if the center
415
408
  // point is outside the floating element's bounds.
416
- const min$1 = minPadding;
417
409
  const max = clientSize - arrowDimensions[length] - maxPadding;
418
410
  const center = clientSize / 2 - arrowDimensions[length] / 2 + centerToReference;
419
- const offset = clamp(min$1, center, max);
411
+ const offset = clamp(minPadding, center, max);
420
412
 
421
413
  // If the reference is small enough that the arrow's padding causes it to
422
414
  // to point to nothing for an aligned placement, adjust the offset of the
423
415
  // floating element itself. To ensure `shift()` continues to take action,
424
416
  // a single reset is performed when this is true.
425
- const shouldAddOffset = !middlewareData.arrow && getAlignment(placement) != null && center !== offset && rects.reference[length] / 2 - (center < min$1 ? minPadding : maxPadding) - arrowDimensions[length] / 2 < 0;
426
- const alignmentOffset = shouldAddOffset ? center < min$1 ? center - min$1 : center - max : 0;
417
+ const shouldAddOffset = !middlewareData.arrow && getAlignment(placement) != null && center !== offset && rects.reference[length] / 2 - (center < minPadding ? minPadding : maxPadding) - arrowDimensions[length] / 2 < 0;
418
+ const alignmentOffset = shouldAddOffset ? center < minPadding ? center - minPadding : center - max : 0;
427
419
  return {
428
420
  [axis]: coords[axis] + alignmentOffset,
429
421
  data: {
@@ -767,23 +759,16 @@ const shift$1 = function (options) {
767
759
  y
768
760
  };
769
761
  const overflow = await platform.detectOverflow(state, detectOverflowOptions);
770
- const crossAxis = getSideAxis(getSide(placement));
762
+ const crossAxis = getSideAxis(placement);
771
763
  const mainAxis = getOppositeAxis(crossAxis);
772
764
  let mainAxisCoord = coords[mainAxis];
773
765
  let crossAxisCoord = coords[crossAxis];
766
+ const clampCoord = (axis, coord) => clamp(coord + overflow[axis === 'y' ? 'top' : 'left'], coord, coord - overflow[axis === 'y' ? 'bottom' : 'right']);
774
767
  if (checkMainAxis) {
775
- const minSide = mainAxis === 'y' ? 'top' : 'left';
776
- const maxSide = mainAxis === 'y' ? 'bottom' : 'right';
777
- const min = mainAxisCoord + overflow[minSide];
778
- const max = mainAxisCoord - overflow[maxSide];
779
- mainAxisCoord = clamp(min, mainAxisCoord, max);
768
+ mainAxisCoord = clampCoord(mainAxis, mainAxisCoord);
780
769
  }
781
770
  if (checkCrossAxis) {
782
- const minSide = crossAxis === 'y' ? 'top' : 'left';
783
- const maxSide = crossAxis === 'y' ? 'bottom' : 'right';
784
- const min = crossAxisCoord + overflow[minSide];
785
- const max = crossAxisCoord - overflow[maxSide];
786
- crossAxisCoord = clamp(min, crossAxisCoord, max);
771
+ crossAxisCoord = clampCoord(crossAxis, crossAxisCoord);
787
772
  }
788
773
  const limitedCoords = limiter.fn({
789
774
  ...state,
@@ -805,6 +790,12 @@ const shift$1 = function (options) {
805
790
  };
806
791
  };
807
792
 
793
+ // Method syntax keeps callback parameters bivariant, but expressing the
794
+ // explicit `| undefined` required by `exactOptionalPropertyTypes` needs
795
+ // property syntax, which is contravariant under `strictFunctionTypes`.
796
+ // Extracting the function from a method position restores that bivariance so
797
+ // consumers can still assign callbacks with narrower parameter types.
798
+
808
799
  /**
809
800
  * Provides data that allows you to change the size of the floating element —
810
801
  * for instance, prevent it from overflowing the clipping boundary or match the
@@ -819,7 +810,6 @@ const size$1 = function (options) {
819
810
  name: 'size',
820
811
  options,
821
812
  async fn(state) {
822
- var _state$middlewareData, _state$middlewareData2;
823
813
  const {
824
814
  placement,
825
815
  rects,
@@ -851,24 +841,21 @@ const size$1 = function (options) {
851
841
  const maximumClippingWidth = width - overflow.left - overflow.right;
852
842
  const overflowAvailableHeight = min(height - overflow[heightSide], maximumClippingHeight);
853
843
  const overflowAvailableWidth = min(width - overflow[widthSide], maximumClippingWidth);
854
- const noShift = !state.middlewareData.shift;
844
+ const shiftData = state.middlewareData.shift;
845
+ const noShift = !shiftData;
855
846
  let availableHeight = overflowAvailableHeight;
856
847
  let availableWidth = overflowAvailableWidth;
857
- if ((_state$middlewareData = state.middlewareData.shift) != null && _state$middlewareData.enabled.x) {
848
+ if (shiftData != null && shiftData.enabled.x) {
858
849
  availableWidth = maximumClippingWidth;
859
850
  }
860
- if ((_state$middlewareData2 = state.middlewareData.shift) != null && _state$middlewareData2.enabled.y) {
851
+ if (shiftData != null && shiftData.enabled.y) {
861
852
  availableHeight = maximumClippingHeight;
862
853
  }
863
854
  if (noShift && !alignment) {
864
- const xMin = max(overflow.left, 0);
865
- const xMax = max(overflow.right, 0);
866
- const yMin = max(overflow.top, 0);
867
- const yMax = max(overflow.bottom, 0);
868
855
  if (isYAxis) {
869
- availableWidth = width - 2 * (xMin !== 0 || xMax !== 0 ? xMin + xMax : max(overflow.left, overflow.right));
856
+ availableWidth = width - 2 * max(overflow.left, overflow.right);
870
857
  } else {
871
- availableHeight = height - 2 * (yMin !== 0 || yMax !== 0 ? yMin + yMax : max(overflow.top, overflow.bottom));
858
+ availableHeight = height - 2 * max(overflow.top, overflow.bottom);
872
859
  }
873
860
  }
874
861
  await apply({
@@ -1024,7 +1011,7 @@ function getParentNode(node) {
1024
1011
  function getNearestOverflowAncestor(node) {
1025
1012
  const parentNode = getParentNode(node);
1026
1013
  if (isLastTraversableNode(parentNode)) {
1027
- return node.ownerDocument ? node.ownerDocument.body : node.body;
1014
+ return (node.ownerDocument || node).body;
1028
1015
  }
1029
1016
  if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
1030
1017
  return parentNode;
@@ -1121,10 +1108,7 @@ function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {
1121
1108
  if (isFixed === void 0) {
1122
1109
  isFixed = false;
1123
1110
  }
1124
- if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) {
1125
- return false;
1126
- }
1127
- return isFixed;
1111
+ return !!floatingOffsetParent && isFixed && floatingOffsetParent === getWindow(element);
1128
1112
  }
1129
1113
 
1130
1114
  function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
@@ -1151,12 +1135,12 @@ function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetPar
1151
1135
  let y = (clientRect.top + visualOffsets.y) / scale.y;
1152
1136
  let width = clientRect.width / scale.x;
1153
1137
  let height = clientRect.height / scale.y;
1154
- if (domElement) {
1138
+ if (domElement && offsetParent) {
1155
1139
  const win = getWindow(domElement);
1156
- const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
1140
+ const offsetWin = isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
1157
1141
  let currentWin = win;
1158
1142
  let currentIFrame = getFrameElement(currentWin);
1159
- while (currentIFrame && offsetParent && offsetWin !== currentWin) {
1143
+ while (currentIFrame && offsetWin !== currentWin) {
1160
1144
  const iframeScale = getScale(currentIFrame);
1161
1145
  const iframeRect = currentIFrame.getBoundingClientRect();
1162
1146
  const css = getComputedStyle$1(currentIFrame);
@@ -1220,7 +1204,7 @@ function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
1220
1204
  let scale = createCoords(1);
1221
1205
  const offsets = createCoords(0);
1222
1206
  const isOffsetParentAnElement = isHTMLElement(offsetParent);
1223
- if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
1207
+ if (isOffsetParentAnElement || !isFixed) {
1224
1208
  if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
1225
1209
  scroll = getNodeScroll(offsetParent);
1226
1210
  }
@@ -1241,18 +1225,17 @@ function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
1241
1225
  }
1242
1226
 
1243
1227
  function getClientRects(element) {
1244
- return Array.from(element.getClientRects());
1228
+ return element.getClientRects ? Array.from(element.getClientRects()) : [];
1245
1229
  }
1246
1230
 
1247
1231
  // Gets the entire size of the scrollable document area, even extending outside
1248
1232
  // of the `<html>` and `<body>` rect bounds if horizontally scrollable.
1249
- function getDocumentRect(element) {
1250
- const html = getDocumentElement(element);
1251
- const scroll = getNodeScroll(element);
1252
- const body = element.ownerDocument.body;
1233
+ function getDocumentRect(html) {
1234
+ const scroll = getNodeScroll(html);
1235
+ const body = html.ownerDocument.body;
1253
1236
  const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
1254
1237
  const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
1255
- let x = -scroll.scrollLeft + getWindowScrollBarX(element);
1238
+ let x = -scroll.scrollLeft + getWindowScrollBarX(html);
1256
1239
  const y = -scroll.scrollTop;
1257
1240
  if (getComputedStyle$1(body).direction === 'rtl') {
1258
1241
  x += max(html.clientWidth, body.clientWidth) - width;
@@ -1269,7 +1252,11 @@ function getDocumentRect(element) {
1269
1252
  // calculation is affected by unusual styles.
1270
1253
  // Most scrollbars leave 15-18px of space.
1271
1254
  const SCROLLBAR_MAX = 25;
1272
- function getViewportRect(element, strategy) {
1255
+ function getViewportRect(element, strategy, rootBoundary) {
1256
+ if (rootBoundary === void 0) {
1257
+ rootBoundary = 'viewport';
1258
+ }
1259
+ const isLayoutViewport = rootBoundary === 'layoutViewport';
1273
1260
  const win = getWindow(element);
1274
1261
  const html = getDocumentElement(element);
1275
1262
  const visualViewport = win.visualViewport;
@@ -1278,31 +1265,42 @@ function getViewportRect(element, strategy) {
1278
1265
  let x = 0;
1279
1266
  let y = 0;
1280
1267
  if (visualViewport) {
1281
- width = visualViewport.width;
1282
- height = visualViewport.height;
1283
- const visualViewportBased = isWebKit();
1284
- if (!visualViewportBased || visualViewportBased && strategy === 'fixed') {
1285
- x = visualViewport.offsetLeft;
1286
- y = visualViewport.offsetTop;
1268
+ // Client coordinates are relative to the layout viewport, except in
1269
+ // WebKit with an `absolute` strategy, where they are relative to the
1270
+ // visual viewport.
1271
+ const layoutRelativeClientCoords = !isWebKit() || strategy === 'fixed';
1272
+ if (isLayoutViewport) {
1273
+ if (!layoutRelativeClientCoords) {
1274
+ x = -visualViewport.offsetLeft;
1275
+ y = -visualViewport.offsetTop;
1276
+ }
1277
+ } else {
1278
+ width = visualViewport.width;
1279
+ height = visualViewport.height;
1280
+ if (layoutRelativeClientCoords) {
1281
+ x = visualViewport.offsetLeft;
1282
+ y = visualViewport.offsetTop;
1283
+ }
1287
1284
  }
1288
1285
  }
1289
1286
  const windowScrollbarX = getWindowScrollBarX(html);
1290
- // <html> `overflow: hidden` + `scrollbar-gutter: stable` reduces the
1291
- // visual width of the <html> but this is not considered in the size
1292
- // of `html.clientWidth`.
1287
+ // `scrollbar-gutter: stable` on the <html> reserves gutter space that shrinks
1288
+ // the visual width but isn't reflected in `html.clientWidth`, so subtract it.
1289
+ // Only the inline-end (right) gutter can hold the scrollbar; `both-edges` also
1290
+ // reserves an empty inline-start gutter that clips nothing, so exclude just
1291
+ // the one scrollbar-side gutter — halve the measured (two-gutter) total. A
1292
+ // left-side scrollbar (`windowScrollbarX > 0`) is already handled by
1293
+ // `getHTMLOffset`/`visualViewport.width`; skip it here.
1293
1294
  if (windowScrollbarX <= 0) {
1294
1295
  const doc = html.ownerDocument;
1295
1296
  const body = doc.body;
1296
1297
  const bodyStyles = getComputedStyle(body);
1297
1298
  const bodyMarginInline = doc.compatMode === 'CSS1Compat' ? parseFloat(bodyStyles.marginLeft) + parseFloat(bodyStyles.marginRight) || 0 : 0;
1298
- const clippingStableScrollbarWidth = Math.abs(html.clientWidth - body.clientWidth - bodyMarginInline);
1299
- if (clippingStableScrollbarWidth <= SCROLLBAR_MAX) {
1300
- width -= clippingStableScrollbarWidth;
1299
+ const reservedWidth = Math.abs(html.clientWidth - body.clientWidth - bodyMarginInline);
1300
+ const gutter = getComputedStyle(html).scrollbarGutter === 'stable both-edges' ? reservedWidth / 2 : reservedWidth;
1301
+ if (gutter <= SCROLLBAR_MAX) {
1302
+ width -= gutter;
1301
1303
  }
1302
- } else if (windowScrollbarX <= SCROLLBAR_MAX) {
1303
- // If the <body> scrollbar is on the left, the width needs to be extended
1304
- // by the scrollbar amount so there isn't extra space on the right.
1305
- width += windowScrollbarX;
1306
1304
  }
1307
1305
  return {
1308
1306
  width,
@@ -1317,7 +1315,7 @@ function getInnerBoundingClientRect(element, strategy) {
1317
1315
  const clientRect = getBoundingClientRect(element, true, strategy === 'fixed');
1318
1316
  const top = clientRect.top + element.clientTop;
1319
1317
  const left = clientRect.left + element.clientLeft;
1320
- const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);
1318
+ const scale = getScale(element);
1321
1319
  const width = element.clientWidth * scale.x;
1322
1320
  const height = element.clientHeight * scale.y;
1323
1321
  const x = left * scale.x;
@@ -1331,8 +1329,8 @@ function getInnerBoundingClientRect(element, strategy) {
1331
1329
  }
1332
1330
  function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
1333
1331
  let rect;
1334
- if (clippingAncestor === 'viewport') {
1335
- rect = getViewportRect(element, strategy);
1332
+ if (clippingAncestor === 'viewport' || clippingAncestor === 'layoutViewport') {
1333
+ rect = getViewportRect(element, strategy, clippingAncestor);
1336
1334
  } else if (clippingAncestor === 'document') {
1337
1335
  rect = getDocumentRect(getDocumentElement(element));
1338
1336
  } else if (isElement(clippingAncestor)) {
@@ -1348,13 +1346,6 @@ function getClientRectFromClippingAncestor(element, clippingAncestor, strategy)
1348
1346
  }
1349
1347
  return rectToClientRect(rect);
1350
1348
  }
1351
- function hasFixedPositionAncestor(element, stopNode) {
1352
- const parentNode = getParentNode(element);
1353
- if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) {
1354
- return false;
1355
- }
1356
- return getComputedStyle$1(parentNode).position === 'fixed' || hasFixedPositionAncestor(parentNode, stopNode);
1357
- }
1358
1349
 
1359
1350
  // A "clipping ancestor" is an `overflow` element with the characteristic of
1360
1351
  // clipping (or hiding) child elements. This returns all clipping ancestors
@@ -1365,7 +1356,7 @@ function getClippingElementAncestors(element, cache) {
1365
1356
  return cachedResult;
1366
1357
  }
1367
1358
  let result = getOverflowAncestors(element, [], false).filter(el => isElement(el) && getNodeName(el) !== 'body');
1368
- let currentContainingBlockComputedStyle = null;
1359
+ let lastKeptComputedStyle = null;
1369
1360
  const elementIsFixed = getComputedStyle$1(element).position === 'fixed';
1370
1361
  let currentNode = elementIsFixed ? getParentNode(element) : element;
1371
1362
 
@@ -1373,16 +1364,20 @@ function getClippingElementAncestors(element, cache) {
1373
1364
  while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
1374
1365
  const computedStyle = getComputedStyle$1(currentNode);
1375
1366
  const currentNodeIsContaining = isContainingBlock(currentNode);
1376
- if (!currentNodeIsContaining && computedStyle.position === 'fixed') {
1377
- currentContainingBlockComputedStyle = null;
1378
- }
1379
- const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === 'static' && !!currentContainingBlockComputedStyle && (currentContainingBlockComputedStyle.position === 'absolute' || currentContainingBlockComputedStyle.position === 'fixed') || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
1367
+ // Position of the containing block chain below the current node. A fixed
1368
+ // element whose containing block hasn't been found yet is a fixed chain.
1369
+ const lastPosition = lastKeptComputedStyle ? lastKeptComputedStyle.position : elementIsFixed ? 'fixed' : '';
1370
+
1371
+ // A non-containing ancestor does not clip the element when the chain
1372
+ // below it escapes it: a fixed chain escapes all ancestors up to the
1373
+ // next containing block, an absolute chain escapes static ancestors.
1374
+ const shouldDropCurrentNode = !currentNodeIsContaining && (lastPosition === 'fixed' || lastPosition === 'absolute' && computedStyle.position === 'static');
1380
1375
  if (shouldDropCurrentNode) {
1381
1376
  // Drop non-containing blocks.
1382
1377
  result = result.filter(ancestor => ancestor !== currentNode);
1383
1378
  } else {
1384
- // Record last containing block for next iteration.
1385
- currentContainingBlockComputedStyle = computedStyle;
1379
+ // The kept node carries the chain position for the next iteration.
1380
+ lastKeptComputedStyle = computedStyle;
1386
1381
  }
1387
1382
  currentNode = getParentNode(currentNode);
1388
1383
  }
@@ -1442,13 +1437,7 @@ function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
1442
1437
  scrollTop: 0
1443
1438
  };
1444
1439
  const offsets = createCoords(0);
1445
-
1446
- // If the <body> scrollbar appears on the left (e.g. RTL systems). Use
1447
- // Firefox with layout.scrollbar.side = 3 in about:config to test this.
1448
- function setLeftRTLScrollbarOffset() {
1449
- offsets.x = getWindowScrollBarX(documentElement);
1450
- }
1451
- if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
1440
+ if (isOffsetParentAnElement || !isFixed) {
1452
1441
  if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
1453
1442
  scroll = getNodeScroll(offsetParent);
1454
1443
  }
@@ -1456,12 +1445,13 @@ function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
1456
1445
  const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);
1457
1446
  offsets.x = offsetRect.x + offsetParent.clientLeft;
1458
1447
  offsets.y = offsetRect.y + offsetParent.clientTop;
1459
- } else if (documentElement) {
1460
- setLeftRTLScrollbarOffset();
1461
1448
  }
1462
1449
  }
1463
- if (isFixed && !isOffsetParentAnElement && documentElement) {
1464
- setLeftRTLScrollbarOffset();
1450
+
1451
+ // If the <body> scrollbar appears on the left (e.g. RTL systems). Use
1452
+ // Firefox with layout.scrollbar.side = 3 in about:config to test this.
1453
+ if (!isOffsetParentAnElement && documentElement) {
1454
+ offsets.x = getWindowScrollBarX(documentElement);
1465
1455
  }
1466
1456
  const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
1467
1457
  const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;
@@ -1561,7 +1551,7 @@ function rectsAreEqual(a, b) {
1561
1551
  }
1562
1552
 
1563
1553
  // https://samthor.au/2021/observing-dom/
1564
- function observeMove(element, onMove) {
1554
+ function observeMove(element, onMove, ancestorResize) {
1565
1555
  let io = null;
1566
1556
  let timeoutId;
1567
1557
  const root = getDocumentElement(element);
@@ -1604,13 +1594,22 @@ function observeMove(element, onMove) {
1604
1594
  let isFirstUpdate = true;
1605
1595
  function handleObserve(entries) {
1606
1596
  const ratio = entries[0].intersectionRatio;
1597
+
1598
+ // The entry is a snapshot, so the reference may have moved since the
1599
+ // intersection was computed (under performance constraints, or between
1600
+ // consecutive frames of a multi-frame layout shift). The reported ratio
1601
+ // and the observed area are stale in that case and cannot be trusted to
1602
+ // detect subsequent movement, so refresh regardless of the ratio.
1603
+ if (!rectsAreEqual(elementRectForRootMargin, element.getBoundingClientRect())) {
1604
+ return refresh();
1605
+ }
1607
1606
  if (ratio !== threshold) {
1608
1607
  if (!isFirstUpdate) {
1609
1608
  return refresh();
1610
1609
  }
1611
1610
  if (!ratio) {
1612
- // If the reference is clipped, the ratio is 0. Throttle the refresh
1613
- // to prevent an infinite loop of updates.
1611
+ // If the reference is clipped in place, the ratio is 0. Throttle
1612
+ // the refresh to prevent an infinite loop of updates.
1614
1613
  timeoutId = setTimeout(() => {
1615
1614
  refresh(false, 1e-7);
1616
1615
  }, 1000);
@@ -1618,16 +1617,6 @@ function observeMove(element, onMove) {
1618
1617
  refresh(false, ratio);
1619
1618
  }
1620
1619
  }
1621
- if (ratio === 1 && !rectsAreEqual(elementRectForRootMargin, element.getBoundingClientRect())) {
1622
- // It's possible that even though the ratio is reported as 1, the
1623
- // element is not actually fully within the IntersectionObserver's root
1624
- // area anymore. This can happen under performance constraints. This may
1625
- // be a bug in the browser's IntersectionObserver implementation. To
1626
- // work around this, we compare the element's bounding rect now with
1627
- // what it was at the time we created the IntersectionObserver. If they
1628
- // are not equal then the element moved, so we refresh.
1629
- refresh();
1630
- }
1631
1620
  isFirstUpdate = false;
1632
1621
  }
1633
1622
 
@@ -1644,8 +1633,18 @@ function observeMove(element, onMove) {
1644
1633
  }
1645
1634
  io.observe(element);
1646
1635
  }
1636
+ const win = getWindow(element);
1637
+ // The window is a resize ancestor, so when `ancestorResize` is enabled its
1638
+ // listener already runs the update on resize. Here we only need to rebuild
1639
+ // the `IntersectionObserver` for the new root size, skipping a redundant
1640
+ // update. When `ancestorResize` is disabled, this becomes the sole update.
1641
+ const handleResize = () => refresh(ancestorResize);
1642
+ win.addEventListener('resize', handleResize);
1647
1643
  refresh(true);
1648
- return cleanup;
1644
+ return () => {
1645
+ win.removeEventListener('resize', handleResize);
1646
+ cleanup();
1647
+ };
1649
1648
  }
1650
1649
 
1651
1650
  /**
@@ -1670,12 +1669,10 @@ function autoUpdate(reference, floating, update, options) {
1670
1669
  const referenceEl = unwrapElement(reference);
1671
1670
  const ancestors = ancestorScroll || ancestorResize ? [...(referenceEl ? getOverflowAncestors(referenceEl) : []), ...(floating ? getOverflowAncestors(floating) : [])] : [];
1672
1671
  ancestors.forEach(ancestor => {
1673
- ancestorScroll && ancestor.addEventListener('scroll', update, {
1674
- passive: true
1675
- });
1672
+ ancestorScroll && ancestor.addEventListener('scroll', update);
1676
1673
  ancestorResize && ancestor.addEventListener('resize', update);
1677
1674
  });
1678
- const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update) : null;
1675
+ const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update, ancestorResize) : null;
1679
1676
  let reobserveFrame = -1;
1680
1677
  let resizeObserver = null;
1681
1678
  if (elementResize) {
@@ -1784,11 +1781,9 @@ const computePosition = (reference, floating, options) => {
1784
1781
  // multiple lifecycle resets re-use the same result. It only lives for a
1785
1782
  // single call. If other functions become expensive, we can add them as well.
1786
1783
  const cache = new Map();
1787
- const mergedOptions = {
1788
- platform,
1789
- ...options
1790
- };
1784
+ const mergedOptions = options != null ? options : {};
1791
1785
  const platformWithCache = {
1786
+ ...platform,
1792
1787
  ...mergedOptions.platform,
1793
1788
  _c: cache
1794
1789
  };
@@ -1798,11 +1793,28 @@ const computePosition = (reference, floating, options) => {
1798
1793
  });
1799
1794
  };
1800
1795
 
1796
+ const STATIC_SIDE_BY_PLACEMENT = {
1797
+ top: 'bottom',
1798
+ right: 'left',
1799
+ bottom: 'top',
1800
+ left: 'right',
1801
+ };
1802
+ /**
1803
+ * Thin wrapper around Floating UI that owns the shared middleware pipeline
1804
+ * and ensures each instance has at most one `autoUpdate` subscription.
1805
+ *
1806
+ * Lifecycle:
1807
+ * - `start()` starts position tracking and performs an initial reposition.
1808
+ * - `stop()` stops tracking and invalidates pending positioning results.
1809
+ * - `reposition()` computes and applies the position once.
1810
+ * - `configure(options)` updates options and repositions only when active.
1811
+ */
1801
1812
  class FloatingUI {
1802
1813
  panel;
1803
1814
  trigger;
1804
1815
  options;
1805
- cleanUp;
1816
+ cleanup;
1817
+ repositionId = 0;
1806
1818
  constructor(trigger, panel, options) {
1807
1819
  this.trigger = trigger;
1808
1820
  this.panel = panel;
@@ -1813,74 +1825,92 @@ class FloatingUI {
1813
1825
  sameWidth: false,
1814
1826
  ...options,
1815
1827
  };
1816
- this.init(options);
1817
1828
  }
1818
- init(options) {
1819
- this.options = Object.assign(this.options, options);
1820
- this.update();
1829
+ /**
1830
+ * Merges new options into the current configuration. Active instances
1831
+ * reposition without recreating their `autoUpdate` subscription; stopped
1832
+ * instances apply the options the next time they start.
1833
+ */
1834
+ configure(options) {
1835
+ Object.assign(this.options, options);
1836
+ this.repositionId += 1;
1837
+ if (options.sameWidth === false) {
1838
+ this.panel.style.width = '';
1839
+ }
1840
+ if (!this.cleanup)
1841
+ return;
1842
+ void this.reposition();
1821
1843
  }
1822
- update() {
1823
- this.cleanUp = autoUpdate(this.trigger, this.panel, () => {
1824
- (async () => {
1825
- const { x, y, placement, middlewareData } = await computePosition(this.trigger, this.panel, {
1826
- placement: this.options.placement,
1827
- strategy: this.options.strategy,
1828
- middleware: [
1829
- offset({ mainAxis: this.options.distance, crossAxis: this.options.skidding }),
1830
- flip(),
1831
- shift(),
1832
- size(this.options.sameWidth && {
1833
- apply({ rects, elements }) {
1834
- Object.assign(elements.floating.style, {
1835
- width: `${rects.reference.width}px`,
1836
- });
1837
- },
1838
- }),
1839
- arrow({ element: this.options.arrow || null }),
1840
- this.positionChange(),
1841
- hide(),
1842
- ],
1843
- });
1844
- this.applyPanelPosition(x, y);
1845
- this.applyArrowPosition(placement, middlewareData);
1846
- this.applyVisibility(middlewareData);
1847
- })();
1848
- });
1844
+ /**
1845
+ * Opens the `autoUpdate` subscription so the panel keeps tracking the
1846
+ * trigger through scroll, resize, layout and ancestor changes. No-op if
1847
+ * the subscription is already running.
1848
+ */
1849
+ start() {
1850
+ if (this.cleanup)
1851
+ return;
1852
+ this.cleanup = autoUpdate(this.trigger, this.panel, () => void this.reposition());
1849
1853
  }
1850
- destroy() {
1851
- if (!this.cleanUp)
1854
+ /**
1855
+ * Tears down the `autoUpdate` subscription. Idempotent — safe to call
1856
+ * multiple times, and before the first `start()`.
1857
+ */
1858
+ stop() {
1859
+ this.repositionId += 1;
1860
+ if (!this.cleanup)
1852
1861
  return;
1853
- this.cleanUp();
1862
+ this.cleanup();
1863
+ this.cleanup = undefined;
1854
1864
  }
1855
- positionChange() {
1856
- return {
1857
- name: 'positionChange',
1858
- fn: ({ placement: position }) => {
1859
- if (typeof this.options.onPositionChange !== 'function')
1860
- return {};
1861
- this.options.onPositionChange(position);
1862
- return {};
1863
- },
1864
- };
1865
+ /**
1866
+ * Runs a single Floating UI `computePosition` pass and applies the
1867
+ * resulting styles to the panel (and the arrow, if configured).
1868
+ */
1869
+ async reposition() {
1870
+ const repositionId = ++this.repositionId;
1871
+ const { arrow: arrowElement, distance, onPositionChange, placement: configuredPlacement, sameWidth, skidding, strategy, } = this.options;
1872
+ const { x, y, placement, middlewareData } = await computePosition(this.trigger, this.panel, {
1873
+ placement: configuredPlacement,
1874
+ strategy,
1875
+ middleware: [
1876
+ offset({ mainAxis: distance, crossAxis: skidding }),
1877
+ flip(),
1878
+ shift(),
1879
+ size({
1880
+ apply: ({ rects, elements }) => {
1881
+ if (repositionId !== this.repositionId || !elements.floating.isConnected)
1882
+ return;
1883
+ elements.floating.style.width = sameWidth ? `${rects.reference.width}px` : '';
1884
+ },
1885
+ }),
1886
+ ...(arrowElement ? [arrow({ element: arrowElement })] : []),
1887
+ hide(),
1888
+ ],
1889
+ });
1890
+ if (repositionId !== this.repositionId || !this.panel.isConnected)
1891
+ return;
1892
+ this.applyPanelPosition(x, y);
1893
+ this.applyArrowPosition(arrowElement, placement, middlewareData);
1894
+ this.applyVisibility(middlewareData);
1895
+ onPositionChange?.(placement);
1865
1896
  }
1866
1897
  applyPanelPosition(x, y) {
1898
+ const dpr = window.devicePixelRatio || 1;
1899
+ const roundedX = Math.round(x * dpr) / dpr;
1900
+ const roundedY = Math.round(y * dpr) / dpr;
1867
1901
  Object.assign(this.panel.style, {
1868
1902
  top: '0',
1869
1903
  left: '0',
1870
- transform: `translate(${this.roundByDPR(x)}px,${this.roundByDPR(y)}px)`,
1904
+ transform: `translate(${roundedX}px, ${roundedY}px)`,
1871
1905
  });
1872
1906
  }
1873
- applyArrowPosition(placement, middlewareData) {
1874
- if (!this.options.arrow)
1907
+ applyArrowPosition(arrowElement, placement, middlewareData) {
1908
+ if (!arrowElement)
1875
1909
  return;
1876
- const { x: arrowX, y: arrowY } = middlewareData.arrow;
1877
- const staticSide = {
1878
- top: 'bottom',
1879
- right: 'left',
1880
- bottom: 'top',
1881
- left: 'right',
1882
- }[placement.split('-')[0]];
1883
- Object.assign(this.options.arrow.style, {
1910
+ const { x: arrowX, y: arrowY } = middlewareData.arrow ?? {};
1911
+ const basePlacement = placement.split('-')[0];
1912
+ const staticSide = STATIC_SIDE_BY_PLACEMENT[basePlacement];
1913
+ Object.assign(arrowElement.style, {
1884
1914
  left: arrowX != null ? `${arrowX}px` : '',
1885
1915
  top: arrowY != null ? `${arrowY}px` : '',
1886
1916
  right: '',
@@ -1889,18 +1919,12 @@ class FloatingUI {
1889
1919
  });
1890
1920
  }
1891
1921
  applyVisibility(middlewareData) {
1892
- const { referenceHidden } = middlewareData.hide;
1893
- Object.assign(this.panel.style, {
1894
- visibility: referenceHidden ? 'hidden' : 'visible',
1895
- });
1896
- }
1897
- roundByDPR(value) {
1898
- const dpr = window.devicePixelRatio || 1;
1899
- return Math.round(value * dpr) / dpr;
1922
+ const referenceHidden = middlewareData.hide?.referenceHidden;
1923
+ this.panel.style.visibility = referenceHidden ? 'hidden' : 'visible';
1900
1924
  }
1901
1925
  }
1902
1926
 
1903
1927
  exports.FloatingUI = FloatingUI;
1904
- //# sourceMappingURL=index-CfLTYjba.js.map
1928
+ //# sourceMappingURL=index-CVDzXB4K.js.map
1905
1929
 
1906
- //# sourceMappingURL=index-CfLTYjba.js.map
1930
+ //# sourceMappingURL=index-CVDzXB4K.js.map