@jobber/components 9.6.0 → 9.6.2

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 (187) hide show
  1. package/dist/ActivityIndicator-cjs.js +1 -0
  2. package/dist/ActivityIndicator-es.js +1 -0
  3. package/dist/Autocomplete/index.cjs +2 -0
  4. package/dist/Autocomplete/index.mjs +2 -0
  5. package/dist/Autocomplete-cjs.js +6 -4
  6. package/dist/Autocomplete-es.js +3 -1
  7. package/dist/Banner-cjs.js +1 -0
  8. package/dist/Banner-es.js +1 -0
  9. package/dist/Card/index.cjs +2 -1
  10. package/dist/Card/index.mjs +2 -1
  11. package/dist/Chip/index.cjs +2 -0
  12. package/dist/Chip/index.mjs +2 -0
  13. package/dist/Chip-cjs.js +1 -0
  14. package/dist/Chip-es.js +1 -0
  15. package/dist/Chips/InternalChipDismissible/hooks/index.cjs +2 -0
  16. package/dist/Chips/InternalChipDismissible/hooks/index.mjs +2 -0
  17. package/dist/Chips/InternalChipDismissible/index.cjs +2 -0
  18. package/dist/Chips/InternalChipDismissible/index.mjs +2 -0
  19. package/dist/Chips/index.cjs +2 -0
  20. package/dist/Chips/index.mjs +2 -0
  21. package/dist/Combobox/index.cjs +4 -2
  22. package/dist/Combobox/index.mjs +4 -2
  23. package/dist/{ComboboxSeparator-cjs.js → ComboboxChipRemove-cjs.js} +455 -501
  24. package/dist/{ComboboxSeparator-es.js → ComboboxChipRemove-es.js} +456 -500
  25. package/dist/ComboboxPrimitive-cjs.js +30 -29
  26. package/dist/ComboboxPrimitive-es.js +3 -2
  27. package/dist/ConfirmationModal/index.cjs +2 -0
  28. package/dist/ConfirmationModal/index.mjs +2 -0
  29. package/dist/ConfirmationModal-cjs.js +1 -0
  30. package/dist/ConfirmationModal-es.js +1 -0
  31. package/dist/DataDump/index.cjs +2 -1
  32. package/dist/DataDump/index.mjs +2 -1
  33. package/dist/DataDump-cjs.js +1 -0
  34. package/dist/DataDump-es.js +1 -0
  35. package/dist/DataList/components/DataListActions/index.cjs +2 -0
  36. package/dist/DataList/components/DataListActions/index.mjs +2 -0
  37. package/dist/DataList/components/DataListBulkActions/index.cjs +2 -0
  38. package/dist/DataList/components/DataListBulkActions/index.mjs +2 -0
  39. package/dist/DataList/components/DataListFilters/components/DataListSort/index.cjs +2 -0
  40. package/dist/DataList/components/DataListFilters/components/DataListSort/index.mjs +2 -0
  41. package/dist/DataList/components/DataListFilters/index.cjs +2 -0
  42. package/dist/DataList/components/DataListFilters/index.mjs +2 -0
  43. package/dist/DataList/components/DataListHeader/index.cjs +2 -0
  44. package/dist/DataList/components/DataListHeader/index.mjs +2 -0
  45. package/dist/DataList/components/DataListItem/index.cjs +2 -0
  46. package/dist/DataList/components/DataListItem/index.mjs +2 -0
  47. package/dist/DataList/components/DataListItemActions/index.cjs +2 -0
  48. package/dist/DataList/components/DataListItemActions/index.mjs +2 -0
  49. package/dist/DataList/components/DataListItemActionsOverflow/index.cjs +2 -0
  50. package/dist/DataList/components/DataListItemActionsOverflow/index.mjs +2 -0
  51. package/dist/DataList/components/DataListItems/index.cjs +2 -0
  52. package/dist/DataList/components/DataListItems/index.mjs +2 -0
  53. package/dist/DataList/components/DataListLayout/index.cjs +2 -0
  54. package/dist/DataList/components/DataListLayout/index.mjs +2 -0
  55. package/dist/DataList/components/DataListLayoutActions/index.cjs +2 -0
  56. package/dist/DataList/components/DataListLayoutActions/index.mjs +2 -0
  57. package/dist/DataList/index.cjs +2 -0
  58. package/dist/DataList/index.mjs +2 -0
  59. package/dist/DataTable-cjs.js +1 -0
  60. package/dist/DataTable-es.js +1 -0
  61. package/dist/DatePicker/index.cjs +2 -0
  62. package/dist/DatePicker/index.mjs +2 -0
  63. package/dist/DatePicker-cjs.js +8 -7
  64. package/dist/DatePicker-es.js +6 -5
  65. package/dist/Dialog/index.cjs +2 -1
  66. package/dist/Dialog/index.mjs +2 -1
  67. package/dist/DrawerDescription-cjs.js +99 -268
  68. package/dist/DrawerDescription-es.js +103 -270
  69. package/dist/DrawerGrid-cjs.js +1 -0
  70. package/dist/DrawerGrid-es.js +1 -0
  71. package/dist/DrawerTitle-cjs.js +6 -2
  72. package/dist/DrawerTitle-es.js +7 -3
  73. package/dist/FeatureSwitch-cjs.js +1 -0
  74. package/dist/FeatureSwitch-es.js +1 -0
  75. package/dist/FieldDescription-cjs.js +181 -184
  76. package/dist/FieldDescription-es.js +184 -187
  77. package/dist/FilterPicker/components/FilterPickerActivator/index.cjs +2 -0
  78. package/dist/FilterPicker/components/FilterPickerActivator/index.mjs +2 -0
  79. package/dist/FilterPicker/components/FilterPickerContent/index.cjs +2 -0
  80. package/dist/FilterPicker/components/FilterPickerContent/index.mjs +2 -0
  81. package/dist/FilterPicker/components/FilterPickerTrigger/index.cjs +2 -0
  82. package/dist/FilterPicker/components/FilterPickerTrigger/index.mjs +2 -0
  83. package/dist/FilterPicker/index.cjs +2 -0
  84. package/dist/FilterPicker/index.mjs +2 -0
  85. package/dist/FilterPickerContent-cjs.js +5 -4
  86. package/dist/FilterPickerContent-es.js +2 -1
  87. package/dist/FormFieldWrapper-cjs.js +1 -0
  88. package/dist/FormFieldWrapper-es.js +1 -0
  89. package/dist/FormatFile/index.cjs +2 -0
  90. package/dist/FormatFile/index.mjs +2 -0
  91. package/dist/FormatFile-cjs.js +1 -0
  92. package/dist/FormatFile-es.js +1 -0
  93. package/dist/Gallery/index.cjs +2 -0
  94. package/dist/Gallery/index.mjs +2 -0
  95. package/dist/InputAvatar-cjs.js +1 -0
  96. package/dist/InputAvatar-es.js +1 -0
  97. package/dist/InputDate/index.cjs +2 -0
  98. package/dist/InputDate/index.mjs +2 -0
  99. package/dist/InputDate-cjs.js +1 -0
  100. package/dist/InputDate-es.js +1 -0
  101. package/dist/InputNumber/index.cjs +2 -1
  102. package/dist/InputNumber/index.mjs +2 -1
  103. package/dist/InternalChipDismissible-cjs.js +1 -0
  104. package/dist/InternalChipDismissible-es.js +1 -0
  105. package/dist/LightBox/index.cjs +2 -0
  106. package/dist/LightBox/index.mjs +2 -0
  107. package/dist/LightBox-cjs.js +1 -0
  108. package/dist/LightBox-es.js +1 -0
  109. package/dist/Menu/index.cjs +2 -1
  110. package/dist/Menu/index.mjs +2 -1
  111. package/dist/Menu-cjs.js +6 -4
  112. package/dist/Menu-es.js +3 -1
  113. package/dist/MenuSubmenuTrigger-cjs.js +164 -206
  114. package/dist/MenuSubmenuTrigger-es.js +152 -194
  115. package/dist/Modal/index.cjs +3 -1
  116. package/dist/Modal/index.mjs +4 -2
  117. package/dist/NumberFieldInput-cjs.js +308 -187
  118. package/dist/NumberFieldInput-es.js +308 -187
  119. package/dist/Page/index.cjs +2 -1
  120. package/dist/Page/index.mjs +2 -1
  121. package/dist/Page-cjs.js +1 -0
  122. package/dist/Page-es.js +1 -0
  123. package/dist/Popover/index.cjs +2 -0
  124. package/dist/Popover/index.mjs +2 -0
  125. package/dist/Popover-cjs.js +9 -7
  126. package/dist/Popover-es.js +3 -1
  127. package/dist/ProgressBar-cjs.js +1 -0
  128. package/dist/ProgressBar-es.js +1 -0
  129. package/dist/ScrollAreaViewport-cjs.js +1093 -747
  130. package/dist/ScrollAreaViewport-es.js +1081 -734
  131. package/dist/Select/index.cjs +2 -1
  132. package/dist/Select/index.mjs +2 -1
  133. package/dist/SelectGroupLabel-cjs.js +306 -207
  134. package/dist/SelectGroupLabel-es.js +302 -203
  135. package/dist/SideDrawer-cjs.js +1 -0
  136. package/dist/SideDrawer-es.js +1 -0
  137. package/dist/Spinner-cjs.js +1 -0
  138. package/dist/Spinner-es.js +1 -0
  139. package/dist/Tooltip/index.cjs +2 -0
  140. package/dist/Tooltip/index.mjs +2 -0
  141. package/dist/Tooltip-cjs.js +7 -6
  142. package/dist/Tooltip-es.js +2 -1
  143. package/dist/dialogReturnFocus-cjs.js +1 -1
  144. package/dist/dialogReturnFocus-es.js +2 -2
  145. package/dist/floating-ui.react-cjs.js +192 -2564
  146. package/dist/floating-ui.react-dom-cjs.js +2103 -0
  147. package/dist/floating-ui.react-dom-es.js +2072 -0
  148. package/dist/floating-ui.react-es.js +156 -2519
  149. package/dist/floating-ui.utils-cjs.js +342 -0
  150. package/dist/floating-ui.utils-es.js +300 -0
  151. package/dist/index.cjs +4 -3
  152. package/dist/index.mjs +4 -3
  153. package/dist/primitives/BottomSheet/index.cjs +1 -1
  154. package/dist/primitives/BottomSheet/index.mjs +1 -1
  155. package/dist/primitives/ComboboxPrimitive/index.cjs +4 -2
  156. package/dist/primitives/ComboboxPrimitive/index.mjs +4 -2
  157. package/dist/primitives/SelectPrimitive/index.cjs +2 -0
  158. package/dist/primitives/SelectPrimitive/index.mjs +2 -0
  159. package/dist/primitives/index.cjs +3 -2
  160. package/dist/primitives/index.mjs +3 -2
  161. package/dist/scrollEdges-cjs.js +11 -1
  162. package/dist/scrollEdges-es.js +11 -1
  163. package/dist/sharedHelpers/i18n/index.cjs +1 -0
  164. package/dist/sharedHelpers/i18n/index.d.ts +1 -0
  165. package/dist/sharedHelpers/i18n/index.mjs +1 -1
  166. package/dist/sharedHelpers/i18n/releasedLanguages.d.ts +12 -0
  167. package/dist/sharedHelpers/i18n/useReleasedLocale.d.ts +6 -0
  168. package/dist/showToast-cjs.js +1 -1
  169. package/dist/showToast-es.js +1 -1
  170. package/dist/testUtils/releasedLanguages.d.ts +16 -0
  171. package/dist/unstyledPrimitives/index.cjs +478 -720
  172. package/dist/unstyledPrimitives/index.mjs +421 -663
  173. package/dist/useAtlantisI18n-cjs.js +44 -11
  174. package/dist/useAtlantisI18n-es.js +44 -12
  175. package/dist/useCompositeListItem-cjs.js +361 -2108
  176. package/dist/useCompositeListItem-es.js +331 -2076
  177. package/dist/useLabel-cjs.js +3 -2
  178. package/dist/useLabel-es.js +3 -2
  179. package/dist/useRenderElement-cjs.js +7 -9
  180. package/dist/useRenderElement-es.js +7 -9
  181. package/dist/useScrollLock-cjs.js +344 -819
  182. package/dist/useScrollLock-es.js +296 -732
  183. package/dist/useScrollToActive-cjs.js +5 -4
  184. package/dist/useScrollToActive-es.js +2 -1
  185. package/package.json +3 -3
  186. package/dist/scrollable-cjs.js +0 -58
  187. package/dist/scrollable-es.js +0 -54
@@ -2,9 +2,10 @@
2
2
 
3
3
  var React = require('react');
4
4
  var useScrollLock = require('./useScrollLock-cjs.js');
5
+ var floatingUi_utils = require('./floating-ui.utils-cjs.js');
5
6
  var useRenderElement = require('./useRenderElement-cjs.js');
6
7
  var jsxRuntime = require('react/jsx-runtime');
7
- var ReactDOM = require('react-dom');
8
+ var floatingUi_reactDom = require('./floating-ui.react-dom-cjs.js');
8
9
 
9
10
  function _interopNamespaceDefault(e) {
10
11
  var n = Object.create(null);
@@ -24,1718 +25,6 @@ function _interopNamespaceDefault(e) {
24
25
  }
25
26
 
26
27
  var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
27
- var ReactDOM__namespace = /*#__PURE__*/_interopNamespaceDefault(ReactDOM);
28
-
29
- function useOnFirstRender(fn) {
30
- const ref = React__namespace.useRef(true);
31
- if (ref.current) {
32
- ref.current = false;
33
- fn();
34
- }
35
- }
36
-
37
- function computeCoordsFromPlacement(_ref, placement, rtl) {
38
- let {
39
- reference,
40
- floating
41
- } = _ref;
42
- const sideAxis = useScrollLock.getSideAxis(placement);
43
- const alignmentAxis = useScrollLock.getAlignmentAxis(placement);
44
- const alignLength = useScrollLock.getAxisLength(alignmentAxis);
45
- const side = useScrollLock.getSide(placement);
46
- const isVertical = sideAxis === 'y';
47
- const commonX = reference.x + reference.width / 2 - floating.width / 2;
48
- const commonY = reference.y + reference.height / 2 - floating.height / 2;
49
- const commonAlign = reference[alignLength] / 2 - floating[alignLength] / 2;
50
- let coords;
51
- switch (side) {
52
- case 'top':
53
- coords = {
54
- x: commonX,
55
- y: reference.y - floating.height
56
- };
57
- break;
58
- case 'bottom':
59
- coords = {
60
- x: commonX,
61
- y: reference.y + reference.height
62
- };
63
- break;
64
- case 'right':
65
- coords = {
66
- x: reference.x + reference.width,
67
- y: commonY
68
- };
69
- break;
70
- case 'left':
71
- coords = {
72
- x: reference.x - floating.width,
73
- y: commonY
74
- };
75
- break;
76
- default:
77
- coords = {
78
- x: reference.x,
79
- y: reference.y
80
- };
81
- }
82
- const alignment = useScrollLock.getAlignment(placement);
83
- if (alignment) {
84
- coords[alignmentAxis] += commonAlign * (alignment === 'end' ? 1 : -1) * (rtl && isVertical ? -1 : 1);
85
- }
86
- return coords;
87
- }
88
-
89
- /**
90
- * Resolves with an object of overflow side offsets that determine how much the
91
- * element is overflowing a given clipping boundary on each side.
92
- * - positive = overflowing the boundary by that number of pixels
93
- * - negative = how many pixels left before it will overflow
94
- * - 0 = lies flush with the boundary
95
- * @see https://floating-ui.com/docs/detectOverflow
96
- */
97
- async function detectOverflow(state, options) {
98
- var _await$platform$isEle;
99
- if (options === void 0) {
100
- options = {};
101
- }
102
- const {
103
- x,
104
- y,
105
- platform,
106
- rects,
107
- elements,
108
- strategy
109
- } = state;
110
- const {
111
- boundary = 'clippingAncestors',
112
- rootBoundary = 'viewport',
113
- elementContext = 'floating',
114
- altBoundary = false,
115
- padding = 0
116
- } = useScrollLock.evaluate(options, state);
117
- const paddingObject = useScrollLock.getPaddingObject(padding);
118
- const altContext = elementContext === 'floating' ? 'reference' : 'floating';
119
- const element = elements[altBoundary ? altContext : elementContext];
120
- const clippingClientRect = useScrollLock.rectToClientRect(await platform.getClippingRect({
121
- element: ((_await$platform$isEle = await (platform.isElement == null ? void 0 : platform.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || (await (platform.getDocumentElement == null ? void 0 : platform.getDocumentElement(elements.floating))),
122
- boundary,
123
- rootBoundary,
124
- strategy
125
- }));
126
- const rect = elementContext === 'floating' ? {
127
- x,
128
- y,
129
- width: rects.floating.width,
130
- height: rects.floating.height
131
- } : rects.reference;
132
- const offsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating));
133
- const offsetScale = (await (platform.isElement == null ? void 0 : platform.isElement(offsetParent))) && (await (platform.getScale == null ? void 0 : platform.getScale(offsetParent))) || {
134
- x: 1,
135
- y: 1
136
- };
137
- const elementClientRect = useScrollLock.rectToClientRect(platform.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform.convertOffsetParentRelativeRectToViewportRelativeRect({
138
- elements,
139
- rect,
140
- offsetParent,
141
- strategy
142
- }) : rect);
143
- return {
144
- top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
145
- bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
146
- left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
147
- right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
148
- };
149
- }
150
-
151
- // Maximum number of resets that can occur before bailing to avoid infinite reset loops.
152
- const MAX_RESET_COUNT = 50;
153
-
154
- /**
155
- * Computes the `x` and `y` coordinates that will place the floating element
156
- * next to a given reference element.
157
- *
158
- * This export does not have any `platform` interface logic. You will need to
159
- * write one for the platform you are using Floating UI with.
160
- */
161
- const computePosition$1 = async (reference, floating, config) => {
162
- const {
163
- placement = 'bottom',
164
- strategy = 'absolute',
165
- middleware = [],
166
- platform
167
- } = config;
168
- const platformWithDetectOverflow = platform.detectOverflow ? platform : {
169
- ...platform,
170
- detectOverflow
171
- };
172
- const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(floating));
173
- let rects = await platform.getElementRects({
174
- reference,
175
- floating,
176
- strategy
177
- });
178
- let {
179
- x,
180
- y
181
- } = computeCoordsFromPlacement(rects, placement, rtl);
182
- let statefulPlacement = placement;
183
- let resetCount = 0;
184
- const middlewareData = {};
185
- for (let i = 0; i < middleware.length; i++) {
186
- const currentMiddleware = middleware[i];
187
- if (!currentMiddleware) {
188
- continue;
189
- }
190
- const {
191
- name,
192
- fn
193
- } = currentMiddleware;
194
- const {
195
- x: nextX,
196
- y: nextY,
197
- data,
198
- reset
199
- } = await fn({
200
- x,
201
- y,
202
- initialPlacement: placement,
203
- placement: statefulPlacement,
204
- strategy,
205
- middlewareData,
206
- rects,
207
- platform: platformWithDetectOverflow,
208
- elements: {
209
- reference,
210
- floating
211
- }
212
- });
213
- x = nextX != null ? nextX : x;
214
- y = nextY != null ? nextY : y;
215
- middlewareData[name] = {
216
- ...middlewareData[name],
217
- ...data
218
- };
219
- if (reset && resetCount < MAX_RESET_COUNT) {
220
- resetCount++;
221
- if (typeof reset === 'object') {
222
- if (reset.placement) {
223
- statefulPlacement = reset.placement;
224
- }
225
- if (reset.rects) {
226
- rects = reset.rects === true ? await platform.getElementRects({
227
- reference,
228
- floating,
229
- strategy
230
- }) : reset.rects;
231
- }
232
- ({
233
- x,
234
- y
235
- } = computeCoordsFromPlacement(rects, statefulPlacement, rtl));
236
- }
237
- i = -1;
238
- }
239
- }
240
- return {
241
- x,
242
- y,
243
- placement: statefulPlacement,
244
- strategy,
245
- middlewareData
246
- };
247
- };
248
-
249
- /**
250
- * Optimizes the visibility of the floating element by flipping the `placement`
251
- * in order to keep it in view when the preferred placement(s) will overflow the
252
- * clipping boundary. Alternative to `autoPlacement`.
253
- * @see https://floating-ui.com/docs/flip
254
- */
255
- const flip$2 = function (options) {
256
- if (options === void 0) {
257
- options = {};
258
- }
259
- return {
260
- name: 'flip',
261
- options,
262
- async fn(state) {
263
- var _middlewareData$arrow, _middlewareData$flip;
264
- const {
265
- placement,
266
- middlewareData,
267
- rects,
268
- initialPlacement,
269
- platform,
270
- elements
271
- } = state;
272
- const {
273
- mainAxis: checkMainAxis = true,
274
- crossAxis: checkCrossAxis = true,
275
- fallbackPlacements: specifiedFallbackPlacements,
276
- fallbackStrategy = 'bestFit',
277
- fallbackAxisSideDirection = 'none',
278
- flipAlignment = true,
279
- ...detectOverflowOptions
280
- } = useScrollLock.evaluate(options, state);
281
-
282
- // If a reset by the arrow was caused due to an alignment offset being
283
- // added, we should skip any logic now since `flip()` has already done its
284
- // work.
285
- // https://github.com/floating-ui/floating-ui/issues/2549#issuecomment-1719601643
286
- if ((_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
287
- return {};
288
- }
289
- const side = useScrollLock.getSide(placement);
290
- const initialSideAxis = useScrollLock.getSideAxis(initialPlacement);
291
- const isBasePlacement = useScrollLock.getSide(initialPlacement) === initialPlacement;
292
- const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating));
293
- const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [useScrollLock.getOppositePlacement(initialPlacement)] : useScrollLock.getExpandedPlacements(initialPlacement));
294
- const hasFallbackAxisSideDirection = fallbackAxisSideDirection !== 'none';
295
- if (!specifiedFallbackPlacements && hasFallbackAxisSideDirection) {
296
- fallbackPlacements.push(...useScrollLock.getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));
297
- }
298
- const placements = [initialPlacement, ...fallbackPlacements];
299
- const overflow = await platform.detectOverflow(state, detectOverflowOptions);
300
- const overflows = [];
301
- let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
302
- if (checkMainAxis) {
303
- overflows.push(overflow[side]);
304
- }
305
- if (checkCrossAxis) {
306
- const sides = useScrollLock.getAlignmentSides(placement, rects, rtl);
307
- overflows.push(overflow[sides[0]], overflow[sides[1]]);
308
- }
309
- overflowsData = [...overflowsData, {
310
- placement,
311
- overflows
312
- }];
313
-
314
- // One or more sides is overflowing.
315
- if (!overflows.every(side => side <= 0)) {
316
- var _middlewareData$flip2, _overflowsData$filter;
317
- const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;
318
- const nextPlacement = placements[nextIndex];
319
- if (nextPlacement) {
320
- const ignoreCrossAxisOverflow = checkCrossAxis === 'alignment' ? initialSideAxis !== useScrollLock.getSideAxis(nextPlacement) : false;
321
- if (!ignoreCrossAxisOverflow ||
322
- // We leave the current main axis only if every placement on that axis
323
- // overflows the main axis.
324
- overflowsData.every(d => useScrollLock.getSideAxis(d.placement) === initialSideAxis ? d.overflows[0] > 0 : true)) {
325
- // Try next placement and re-run the lifecycle.
326
- return {
327
- data: {
328
- index: nextIndex,
329
- overflows: overflowsData
330
- },
331
- reset: {
332
- placement: nextPlacement
333
- }
334
- };
335
- }
336
- }
337
-
338
- // First, find the candidates that fit on the mainAxis side of overflow,
339
- // then find the placement that fits the best on the main crossAxis side.
340
- 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;
341
-
342
- // Otherwise fallback.
343
- if (!resetPlacement) {
344
- switch (fallbackStrategy) {
345
- case 'bestFit':
346
- {
347
- var _overflowsData$filter2;
348
- const placement = (_overflowsData$filter2 = overflowsData.filter(d => {
349
- if (hasFallbackAxisSideDirection) {
350
- const currentSideAxis = useScrollLock.getSideAxis(d.placement);
351
- return currentSideAxis === initialSideAxis ||
352
- // Create a bias to the `y` side axis due to horizontal
353
- // reading directions favoring greater width.
354
- currentSideAxis === 'y';
355
- }
356
- return true;
357
- }).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$filter2[0];
358
- if (placement) {
359
- resetPlacement = placement;
360
- }
361
- break;
362
- }
363
- case 'initialPlacement':
364
- resetPlacement = initialPlacement;
365
- break;
366
- }
367
- }
368
- if (placement !== resetPlacement) {
369
- return {
370
- reset: {
371
- placement: resetPlacement
372
- }
373
- };
374
- }
375
- }
376
- return {};
377
- }
378
- };
379
- };
380
-
381
- const originSides = /*#__PURE__*/new Set(['left', 'top']);
382
-
383
- // For type backwards-compatibility, the `OffsetOptions` type was also
384
- // Derivable.
385
-
386
- async function convertValueToCoords(state, options) {
387
- const {
388
- placement,
389
- platform,
390
- elements
391
- } = state;
392
- const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating));
393
- const side = useScrollLock.getSide(placement);
394
- const alignment = useScrollLock.getAlignment(placement);
395
- const isVertical = useScrollLock.getSideAxis(placement) === 'y';
396
- const mainAxisMulti = originSides.has(side) ? -1 : 1;
397
- const crossAxisMulti = rtl && isVertical ? -1 : 1;
398
- const rawValue = useScrollLock.evaluate(options, state);
399
-
400
- // eslint-disable-next-line prefer-const
401
- let {
402
- mainAxis,
403
- crossAxis,
404
- alignmentAxis
405
- } = typeof rawValue === 'number' ? {
406
- mainAxis: rawValue,
407
- crossAxis: 0,
408
- alignmentAxis: null
409
- } : {
410
- mainAxis: rawValue.mainAxis || 0,
411
- crossAxis: rawValue.crossAxis || 0,
412
- alignmentAxis: rawValue.alignmentAxis
413
- };
414
- if (alignment && typeof alignmentAxis === 'number') {
415
- crossAxis = alignment === 'end' ? alignmentAxis * -1 : alignmentAxis;
416
- }
417
- return isVertical ? {
418
- x: crossAxis * crossAxisMulti,
419
- y: mainAxis * mainAxisMulti
420
- } : {
421
- x: mainAxis * mainAxisMulti,
422
- y: crossAxis * crossAxisMulti
423
- };
424
- }
425
-
426
- /**
427
- * Modifies the placement by translating the floating element along the
428
- * specified axes.
429
- * A number (shorthand for `mainAxis` or distance), or an axes configuration
430
- * object may be passed.
431
- * @see https://floating-ui.com/docs/offset
432
- */
433
- const offset$2 = function (options) {
434
- if (options === void 0) {
435
- options = 0;
436
- }
437
- return {
438
- name: 'offset',
439
- options,
440
- async fn(state) {
441
- var _middlewareData$offse, _middlewareData$arrow;
442
- const {
443
- x,
444
- y,
445
- placement,
446
- middlewareData
447
- } = state;
448
- const diffCoords = await convertValueToCoords(state, options);
449
-
450
- // If the placement is the same and the arrow caused an alignment offset
451
- // then we don't need to change the positioning coordinates.
452
- if (placement === ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse.placement) && (_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
453
- return {};
454
- }
455
- return {
456
- x: x + diffCoords.x,
457
- y: y + diffCoords.y,
458
- data: {
459
- ...diffCoords,
460
- placement
461
- }
462
- };
463
- }
464
- };
465
- };
466
-
467
- /**
468
- * Optimizes the visibility of the floating element by shifting it in order to
469
- * keep it in view when it will overflow the clipping boundary.
470
- * @see https://floating-ui.com/docs/shift
471
- */
472
- const shift$2 = function (options) {
473
- if (options === void 0) {
474
- options = {};
475
- }
476
- return {
477
- name: 'shift',
478
- options,
479
- async fn(state) {
480
- const {
481
- x,
482
- y,
483
- placement,
484
- platform
485
- } = state;
486
- const {
487
- mainAxis: checkMainAxis = true,
488
- crossAxis: checkCrossAxis = false,
489
- limiter = {
490
- fn: _ref => {
491
- let {
492
- x,
493
- y
494
- } = _ref;
495
- return {
496
- x,
497
- y
498
- };
499
- }
500
- },
501
- ...detectOverflowOptions
502
- } = useScrollLock.evaluate(options, state);
503
- const coords = {
504
- x,
505
- y
506
- };
507
- const overflow = await platform.detectOverflow(state, detectOverflowOptions);
508
- const crossAxis = useScrollLock.getSideAxis(placement);
509
- const mainAxis = useScrollLock.getOppositeAxis(crossAxis);
510
- let mainAxisCoord = coords[mainAxis];
511
- let crossAxisCoord = coords[crossAxis];
512
- const clampCoord = (axis, coord) => useScrollLock.clamp(coord + overflow[axis === 'y' ? 'top' : 'left'], coord, coord - overflow[axis === 'y' ? 'bottom' : 'right']);
513
- if (checkMainAxis) {
514
- mainAxisCoord = clampCoord(mainAxis, mainAxisCoord);
515
- }
516
- if (checkCrossAxis) {
517
- crossAxisCoord = clampCoord(crossAxis, crossAxisCoord);
518
- }
519
- const limitedCoords = limiter.fn({
520
- ...state,
521
- [mainAxis]: mainAxisCoord,
522
- [crossAxis]: crossAxisCoord
523
- });
524
- return {
525
- ...limitedCoords,
526
- data: {
527
- x: limitedCoords.x - x,
528
- y: limitedCoords.y - y,
529
- enabled: {
530
- [mainAxis]: checkMainAxis,
531
- [crossAxis]: checkCrossAxis
532
- }
533
- }
534
- };
535
- }
536
- };
537
- };
538
- /**
539
- * Built-in `limiter` that will stop `shift()` at a certain point.
540
- */
541
- const limitShift$2 = function (options) {
542
- if (options === void 0) {
543
- options = {};
544
- }
545
- return {
546
- options,
547
- fn(state) {
548
- var _rawOffset$mainAxis, _rawOffset$crossAxis;
549
- const {
550
- x,
551
- y,
552
- placement,
553
- rects,
554
- middlewareData
555
- } = state;
556
- const {
557
- offset = 0,
558
- mainAxis: checkMainAxis = true,
559
- crossAxis: checkCrossAxis = true
560
- } = useScrollLock.evaluate(options, state);
561
- const coords = {
562
- x,
563
- y
564
- };
565
- const crossAxis = useScrollLock.getSideAxis(placement);
566
- const mainAxis = useScrollLock.getOppositeAxis(crossAxis);
567
- let mainAxisCoord = coords[mainAxis];
568
- let crossAxisCoord = coords[crossAxis];
569
- const rawOffset = useScrollLock.evaluate(offset, state);
570
- const computedOffset = typeof rawOffset === 'number' ? {
571
- mainAxis: rawOffset,
572
- crossAxis: 0
573
- } : {
574
- mainAxis: (_rawOffset$mainAxis = rawOffset.mainAxis) != null ? _rawOffset$mainAxis : 0,
575
- crossAxis: (_rawOffset$crossAxis = rawOffset.crossAxis) != null ? _rawOffset$crossAxis : 0
576
- };
577
- if (checkMainAxis) {
578
- const len = mainAxis === 'y' ? 'height' : 'width';
579
- const limitMin = rects.reference[mainAxis] - rects.floating[len] + computedOffset.mainAxis;
580
- const limitMax = rects.reference[mainAxis] + rects.reference[len] - computedOffset.mainAxis;
581
- if (mainAxisCoord < limitMin) {
582
- mainAxisCoord = limitMin;
583
- } else if (mainAxisCoord > limitMax) {
584
- mainAxisCoord = limitMax;
585
- }
586
- }
587
- if (checkCrossAxis) {
588
- var _middlewareData$offse, _middlewareData$offse2;
589
- const len = mainAxis === 'y' ? 'width' : 'height';
590
- const isOriginSide = originSides.has(useScrollLock.getSide(placement));
591
- const limitMin = rects.reference[crossAxis] - rects.floating[len] + (isOriginSide ? ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse[crossAxis]) || 0 : 0) + (isOriginSide ? 0 : computedOffset.crossAxis);
592
- const limitMax = rects.reference[crossAxis] + rects.reference[len] + (isOriginSide ? 0 : ((_middlewareData$offse2 = middlewareData.offset) == null ? void 0 : _middlewareData$offse2[crossAxis]) || 0) - (isOriginSide ? computedOffset.crossAxis : 0);
593
- if (crossAxisCoord < limitMin) {
594
- crossAxisCoord = limitMin;
595
- } else if (crossAxisCoord > limitMax) {
596
- crossAxisCoord = limitMax;
597
- }
598
- }
599
- return {
600
- [mainAxis]: mainAxisCoord,
601
- [crossAxis]: crossAxisCoord
602
- };
603
- }
604
- };
605
- };
606
-
607
- // Method syntax keeps callback parameters bivariant, but expressing the
608
- // explicit `| undefined` required by `exactOptionalPropertyTypes` needs
609
- // property syntax, which is contravariant under `strictFunctionTypes`.
610
- // Extracting the function from a method position restores that bivariance so
611
- // consumers can still assign callbacks with narrower parameter types.
612
-
613
- /**
614
- * Provides data that allows you to change the size of the floating element —
615
- * for instance, prevent it from overflowing the clipping boundary or match the
616
- * width of the reference element.
617
- * @see https://floating-ui.com/docs/size
618
- */
619
- const size$2 = function (options) {
620
- if (options === void 0) {
621
- options = {};
622
- }
623
- return {
624
- name: 'size',
625
- options,
626
- async fn(state) {
627
- const {
628
- placement,
629
- rects,
630
- platform,
631
- elements
632
- } = state;
633
- const {
634
- apply = () => {},
635
- ...detectOverflowOptions
636
- } = useScrollLock.evaluate(options, state);
637
- const overflow = await platform.detectOverflow(state, detectOverflowOptions);
638
- const side = useScrollLock.getSide(placement);
639
- const alignment = useScrollLock.getAlignment(placement);
640
- const isYAxis = useScrollLock.getSideAxis(placement) === 'y';
641
- const {
642
- width,
643
- height
644
- } = rects.floating;
645
- let heightSide;
646
- let widthSide;
647
- if (side === 'top' || side === 'bottom') {
648
- heightSide = side;
649
- widthSide = alignment === ((await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating))) ? 'start' : 'end') ? 'left' : 'right';
650
- } else {
651
- widthSide = side;
652
- heightSide = alignment === 'end' ? 'top' : 'bottom';
653
- }
654
- const maximumClippingHeight = height - overflow.top - overflow.bottom;
655
- const maximumClippingWidth = width - overflow.left - overflow.right;
656
- const overflowAvailableHeight = useScrollLock.min(height - overflow[heightSide], maximumClippingHeight);
657
- const overflowAvailableWidth = useScrollLock.min(width - overflow[widthSide], maximumClippingWidth);
658
- const shiftData = state.middlewareData.shift;
659
- const noShift = !shiftData;
660
- let availableHeight = overflowAvailableHeight;
661
- let availableWidth = overflowAvailableWidth;
662
- if (shiftData != null && shiftData.enabled.x) {
663
- availableWidth = maximumClippingWidth;
664
- }
665
- if (shiftData != null && shiftData.enabled.y) {
666
- availableHeight = maximumClippingHeight;
667
- }
668
- if (noShift && !alignment) {
669
- if (isYAxis) {
670
- availableWidth = width - 2 * useScrollLock.max(overflow.left, overflow.right);
671
- } else {
672
- availableHeight = height - 2 * useScrollLock.max(overflow.top, overflow.bottom);
673
- }
674
- }
675
- await apply({
676
- ...state,
677
- availableWidth,
678
- availableHeight
679
- });
680
- const nextDimensions = await platform.getDimensions(elements.floating);
681
- if (width !== nextDimensions.width || height !== nextDimensions.height) {
682
- return {
683
- reset: {
684
- rects: true
685
- }
686
- };
687
- }
688
- return {};
689
- }
690
- };
691
- };
692
-
693
- function getCssDimensions(element) {
694
- const css = useScrollLock.getComputedStyle(element);
695
- // In testing environments, the `width` and `height` properties are empty
696
- // strings for SVG elements, returning NaN. Fallback to `0` in this case.
697
- let width = parseFloat(css.width) || 0;
698
- let height = parseFloat(css.height) || 0;
699
- const hasOffset = useScrollLock.isHTMLElement(element);
700
- const offsetWidth = hasOffset ? element.offsetWidth : width;
701
- const offsetHeight = hasOffset ? element.offsetHeight : height;
702
- const shouldFallback = useScrollLock.round(width) !== offsetWidth || useScrollLock.round(height) !== offsetHeight;
703
- if (shouldFallback) {
704
- width = offsetWidth;
705
- height = offsetHeight;
706
- }
707
- return {
708
- width,
709
- height,
710
- $: shouldFallback
711
- };
712
- }
713
-
714
- function unwrapElement(element) {
715
- return !useScrollLock.isElement(element) ? element.contextElement : element;
716
- }
717
-
718
- function getScale(element) {
719
- const domElement = unwrapElement(element);
720
- if (!useScrollLock.isHTMLElement(domElement)) {
721
- return useScrollLock.createCoords(1);
722
- }
723
- const rect = domElement.getBoundingClientRect();
724
- const {
725
- width,
726
- height,
727
- $
728
- } = getCssDimensions(domElement);
729
- let x = ($ ? useScrollLock.round(rect.width) : rect.width) / width;
730
- let y = ($ ? useScrollLock.round(rect.height) : rect.height) / height;
731
-
732
- // 0, NaN, or Infinity should always fallback to 1.
733
-
734
- if (!x || !Number.isFinite(x)) {
735
- x = 1;
736
- }
737
- if (!y || !Number.isFinite(y)) {
738
- y = 1;
739
- }
740
- return {
741
- x,
742
- y
743
- };
744
- }
745
-
746
- const noOffsets = /*#__PURE__*/useScrollLock.createCoords(0);
747
- function getVisualOffsets(element) {
748
- const win = useScrollLock.getWindow(element);
749
- if (!useScrollLock.isWebKit() || !win.visualViewport) {
750
- return noOffsets;
751
- }
752
- return {
753
- x: win.visualViewport.offsetLeft,
754
- y: win.visualViewport.offsetTop
755
- };
756
- }
757
- function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {
758
- if (isFixed === void 0) {
759
- isFixed = false;
760
- }
761
- return !!floatingOffsetParent && isFixed && floatingOffsetParent === useScrollLock.getWindow(element);
762
- }
763
-
764
- function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
765
- if (includeScale === void 0) {
766
- includeScale = false;
767
- }
768
- if (isFixedStrategy === void 0) {
769
- isFixedStrategy = false;
770
- }
771
- const clientRect = element.getBoundingClientRect();
772
- const domElement = unwrapElement(element);
773
- let scale = useScrollLock.createCoords(1);
774
- if (includeScale) {
775
- if (offsetParent) {
776
- if (useScrollLock.isElement(offsetParent)) {
777
- scale = getScale(offsetParent);
778
- }
779
- } else {
780
- scale = getScale(element);
781
- }
782
- }
783
- const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : useScrollLock.createCoords(0);
784
- let x = (clientRect.left + visualOffsets.x) / scale.x;
785
- let y = (clientRect.top + visualOffsets.y) / scale.y;
786
- let width = clientRect.width / scale.x;
787
- let height = clientRect.height / scale.y;
788
- if (domElement && offsetParent) {
789
- const win = useScrollLock.getWindow(domElement);
790
- const offsetWin = useScrollLock.isElement(offsetParent) ? useScrollLock.getWindow(offsetParent) : offsetParent;
791
- let currentWin = win;
792
- let currentIFrame = useScrollLock.getFrameElement(currentWin);
793
- while (currentIFrame && offsetWin !== currentWin) {
794
- const iframeScale = getScale(currentIFrame);
795
- const iframeRect = currentIFrame.getBoundingClientRect();
796
- const css = useScrollLock.getComputedStyle(currentIFrame);
797
- const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
798
- const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
799
- x *= iframeScale.x;
800
- y *= iframeScale.y;
801
- width *= iframeScale.x;
802
- height *= iframeScale.y;
803
- x += left;
804
- y += top;
805
- currentWin = useScrollLock.getWindow(currentIFrame);
806
- currentIFrame = useScrollLock.getFrameElement(currentWin);
807
- }
808
- }
809
- return useScrollLock.rectToClientRect({
810
- width,
811
- height,
812
- x,
813
- y
814
- });
815
- }
816
-
817
- // If <html> has a CSS width greater than the viewport, then this will be
818
- // incorrect for RTL.
819
- function getWindowScrollBarX(element, rect) {
820
- const leftScroll = useScrollLock.getNodeScroll(element).scrollLeft;
821
- if (!rect) {
822
- return getBoundingClientRect(useScrollLock.getDocumentElement(element)).left + leftScroll;
823
- }
824
- return rect.left + leftScroll;
825
- }
826
-
827
- function getHTMLOffset(documentElement, scroll) {
828
- const htmlRect = documentElement.getBoundingClientRect();
829
- const x = htmlRect.left + scroll.scrollLeft - getWindowScrollBarX(documentElement, htmlRect);
830
- const y = htmlRect.top + scroll.scrollTop;
831
- return {
832
- x,
833
- y
834
- };
835
- }
836
-
837
- function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
838
- let {
839
- elements,
840
- rect,
841
- offsetParent,
842
- strategy
843
- } = _ref;
844
- const isFixed = strategy === 'fixed';
845
- const documentElement = useScrollLock.getDocumentElement(offsetParent);
846
- const topLayer = elements ? useScrollLock.isTopLayer(elements.floating) : false;
847
- if (offsetParent === documentElement || topLayer && isFixed) {
848
- return rect;
849
- }
850
- let scroll = {
851
- scrollLeft: 0,
852
- scrollTop: 0
853
- };
854
- let scale = useScrollLock.createCoords(1);
855
- const offsets = useScrollLock.createCoords(0);
856
- const isOffsetParentAnElement = useScrollLock.isHTMLElement(offsetParent);
857
- if (isOffsetParentAnElement || !isFixed) {
858
- if (useScrollLock.getNodeName(offsetParent) !== 'body' || useScrollLock.isOverflowElement(documentElement)) {
859
- scroll = useScrollLock.getNodeScroll(offsetParent);
860
- }
861
- if (isOffsetParentAnElement) {
862
- const offsetRect = getBoundingClientRect(offsetParent);
863
- scale = getScale(offsetParent);
864
- offsets.x = offsetRect.x + offsetParent.clientLeft;
865
- offsets.y = offsetRect.y + offsetParent.clientTop;
866
- }
867
- }
868
- const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : useScrollLock.createCoords(0);
869
- return {
870
- width: rect.width * scale.x,
871
- height: rect.height * scale.y,
872
- x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,
873
- y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y
874
- };
875
- }
876
-
877
- function getClientRects(element) {
878
- return element.getClientRects ? Array.from(element.getClientRects()) : [];
879
- }
880
-
881
- // Gets the entire size of the scrollable document area, even extending outside
882
- // of the `<html>` and `<body>` rect bounds if horizontally scrollable.
883
- function getDocumentRect(html) {
884
- const scroll = useScrollLock.getNodeScroll(html);
885
- const body = html.ownerDocument.body;
886
- const width = useScrollLock.max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
887
- const height = useScrollLock.max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
888
- let x = -scroll.scrollLeft + getWindowScrollBarX(html);
889
- const y = -scroll.scrollTop;
890
- if (useScrollLock.getComputedStyle(body).direction === 'rtl') {
891
- x += useScrollLock.max(html.clientWidth, body.clientWidth) - width;
892
- }
893
- return {
894
- width,
895
- height,
896
- x,
897
- y
898
- };
899
- }
900
-
901
- // Safety check: ensure the scrollbar space is reasonable in case this
902
- // calculation is affected by unusual styles.
903
- // Most scrollbars leave 15-18px of space.
904
- const SCROLLBAR_MAX = 25;
905
- function getViewportRect(element, strategy, rootBoundary) {
906
- if (rootBoundary === void 0) {
907
- rootBoundary = 'viewport';
908
- }
909
- const isLayoutViewport = rootBoundary === 'layoutViewport';
910
- const win = useScrollLock.getWindow(element);
911
- const html = useScrollLock.getDocumentElement(element);
912
- const visualViewport = win.visualViewport;
913
- let width = html.clientWidth;
914
- let height = html.clientHeight;
915
- let x = 0;
916
- let y = 0;
917
- if (visualViewport) {
918
- // Client coordinates are relative to the layout viewport, except in
919
- // WebKit with an `absolute` strategy, where they are relative to the
920
- // visual viewport.
921
- const layoutRelativeClientCoords = !useScrollLock.isWebKit() || strategy === 'fixed';
922
- if (isLayoutViewport) {
923
- if (!layoutRelativeClientCoords) {
924
- x = -visualViewport.offsetLeft;
925
- y = -visualViewport.offsetTop;
926
- }
927
- } else {
928
- width = visualViewport.width;
929
- height = visualViewport.height;
930
- if (layoutRelativeClientCoords) {
931
- x = visualViewport.offsetLeft;
932
- y = visualViewport.offsetTop;
933
- }
934
- }
935
- }
936
- const windowScrollbarX = getWindowScrollBarX(html);
937
- // `scrollbar-gutter: stable` on the <html> reserves gutter space that shrinks
938
- // the visual width but isn't reflected in `html.clientWidth`, so subtract it.
939
- // Only the inline-end (right) gutter can hold the scrollbar; `both-edges` also
940
- // reserves an empty inline-start gutter that clips nothing, so exclude just
941
- // the one scrollbar-side gutter — halve the measured (two-gutter) total. A
942
- // left-side scrollbar (`windowScrollbarX > 0`) is already handled by
943
- // `getHTMLOffset`/`visualViewport.width`; skip it here.
944
- if (windowScrollbarX <= 0) {
945
- const doc = html.ownerDocument;
946
- const body = doc.body;
947
- const bodyStyles = getComputedStyle(body);
948
- const bodyMarginInline = doc.compatMode === 'CSS1Compat' ? parseFloat(bodyStyles.marginLeft) + parseFloat(bodyStyles.marginRight) || 0 : 0;
949
- const reservedWidth = Math.abs(html.clientWidth - body.clientWidth - bodyMarginInline);
950
- const gutter = getComputedStyle(html).scrollbarGutter === 'stable both-edges' ? reservedWidth / 2 : reservedWidth;
951
- if (gutter <= SCROLLBAR_MAX) {
952
- width -= gutter;
953
- }
954
- }
955
- return {
956
- width,
957
- height,
958
- x,
959
- y
960
- };
961
- }
962
-
963
- // Returns the inner client rect, subtracting scrollbars if present.
964
- function getInnerBoundingClientRect(element, strategy) {
965
- const clientRect = getBoundingClientRect(element, true, strategy === 'fixed');
966
- const top = clientRect.top + element.clientTop;
967
- const left = clientRect.left + element.clientLeft;
968
- const scale = getScale(element);
969
- const width = element.clientWidth * scale.x;
970
- const height = element.clientHeight * scale.y;
971
- const x = left * scale.x;
972
- const y = top * scale.y;
973
- return {
974
- width,
975
- height,
976
- x,
977
- y
978
- };
979
- }
980
- function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
981
- let rect;
982
- if (clippingAncestor === 'viewport' || clippingAncestor === 'layoutViewport') {
983
- rect = getViewportRect(element, strategy, clippingAncestor);
984
- } else if (clippingAncestor === 'document') {
985
- rect = getDocumentRect(useScrollLock.getDocumentElement(element));
986
- } else if (useScrollLock.isElement(clippingAncestor)) {
987
- rect = getInnerBoundingClientRect(clippingAncestor, strategy);
988
- } else {
989
- const visualOffsets = getVisualOffsets(element);
990
- rect = {
991
- x: clippingAncestor.x - visualOffsets.x,
992
- y: clippingAncestor.y - visualOffsets.y,
993
- width: clippingAncestor.width,
994
- height: clippingAncestor.height
995
- };
996
- }
997
- return useScrollLock.rectToClientRect(rect);
998
- }
999
-
1000
- // A "clipping ancestor" is an `overflow` element with the characteristic of
1001
- // clipping (or hiding) child elements. This returns all clipping ancestors
1002
- // of the given element up the tree.
1003
- function getClippingElementAncestors(element, cache) {
1004
- const cachedResult = cache.get(element);
1005
- if (cachedResult) {
1006
- return cachedResult;
1007
- }
1008
- let result = useScrollLock.getOverflowAncestors(element, [], false).filter(el => useScrollLock.isElement(el) && useScrollLock.getNodeName(el) !== 'body');
1009
- let lastKeptComputedStyle = null;
1010
- const elementIsFixed = useScrollLock.getComputedStyle(element).position === 'fixed';
1011
- let currentNode = elementIsFixed ? useScrollLock.getParentNode(element) : element;
1012
-
1013
- // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
1014
- while (useScrollLock.isElement(currentNode) && !useScrollLock.isLastTraversableNode(currentNode)) {
1015
- const computedStyle = useScrollLock.getComputedStyle(currentNode);
1016
- const currentNodeIsContaining = useScrollLock.isContainingBlock(currentNode);
1017
- // Position of the containing block chain below the current node. A fixed
1018
- // element whose containing block hasn't been found yet is a fixed chain.
1019
- const lastPosition = lastKeptComputedStyle ? lastKeptComputedStyle.position : elementIsFixed ? 'fixed' : '';
1020
-
1021
- // A non-containing ancestor does not clip the element when the chain
1022
- // below it escapes it: a fixed chain escapes all ancestors up to the
1023
- // next containing block, an absolute chain escapes static ancestors.
1024
- const shouldDropCurrentNode = !currentNodeIsContaining && (lastPosition === 'fixed' || lastPosition === 'absolute' && computedStyle.position === 'static');
1025
- if (shouldDropCurrentNode) {
1026
- // Drop non-containing blocks.
1027
- result = result.filter(ancestor => ancestor !== currentNode);
1028
- } else {
1029
- // The kept node carries the chain position for the next iteration.
1030
- lastKeptComputedStyle = computedStyle;
1031
- }
1032
- currentNode = useScrollLock.getParentNode(currentNode);
1033
- }
1034
- cache.set(element, result);
1035
- return result;
1036
- }
1037
-
1038
- // Gets the maximum area that the element is visible in due to any number of
1039
- // clipping ancestors.
1040
- function getClippingRect(_ref) {
1041
- let {
1042
- element,
1043
- boundary,
1044
- rootBoundary,
1045
- strategy
1046
- } = _ref;
1047
- const elementClippingAncestors = boundary === 'clippingAncestors' ? useScrollLock.isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary);
1048
- const clippingAncestors = [...elementClippingAncestors, rootBoundary];
1049
- const firstRect = getClientRectFromClippingAncestor(element, clippingAncestors[0], strategy);
1050
- let top = firstRect.top;
1051
- let right = firstRect.right;
1052
- let bottom = firstRect.bottom;
1053
- let left = firstRect.left;
1054
- for (let i = 1; i < clippingAncestors.length; i++) {
1055
- const rect = getClientRectFromClippingAncestor(element, clippingAncestors[i], strategy);
1056
- top = useScrollLock.max(rect.top, top);
1057
- right = useScrollLock.min(rect.right, right);
1058
- bottom = useScrollLock.min(rect.bottom, bottom);
1059
- left = useScrollLock.max(rect.left, left);
1060
- }
1061
- return {
1062
- width: right - left,
1063
- height: bottom - top,
1064
- x: left,
1065
- y: top
1066
- };
1067
- }
1068
-
1069
- function getDimensions(element) {
1070
- const {
1071
- width,
1072
- height
1073
- } = getCssDimensions(element);
1074
- return {
1075
- width,
1076
- height
1077
- };
1078
- }
1079
-
1080
- function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
1081
- const isOffsetParentAnElement = useScrollLock.isHTMLElement(offsetParent);
1082
- const documentElement = useScrollLock.getDocumentElement(offsetParent);
1083
- const isFixed = strategy === 'fixed';
1084
- const rect = getBoundingClientRect(element, true, isFixed, offsetParent);
1085
- let scroll = {
1086
- scrollLeft: 0,
1087
- scrollTop: 0
1088
- };
1089
- const offsets = useScrollLock.createCoords(0);
1090
- if (isOffsetParentAnElement || !isFixed) {
1091
- if (useScrollLock.getNodeName(offsetParent) !== 'body' || useScrollLock.isOverflowElement(documentElement)) {
1092
- scroll = useScrollLock.getNodeScroll(offsetParent);
1093
- }
1094
- if (isOffsetParentAnElement) {
1095
- const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);
1096
- offsets.x = offsetRect.x + offsetParent.clientLeft;
1097
- offsets.y = offsetRect.y + offsetParent.clientTop;
1098
- }
1099
- }
1100
-
1101
- // If the <body> scrollbar appears on the left (e.g. RTL systems). Use
1102
- // Firefox with layout.scrollbar.side = 3 in about:config to test this.
1103
- if (!isOffsetParentAnElement && documentElement) {
1104
- offsets.x = getWindowScrollBarX(documentElement);
1105
- }
1106
- const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : useScrollLock.createCoords(0);
1107
- const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;
1108
- const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;
1109
- return {
1110
- x,
1111
- y,
1112
- width: rect.width,
1113
- height: rect.height
1114
- };
1115
- }
1116
-
1117
- function isStaticPositioned(element) {
1118
- return useScrollLock.getComputedStyle(element).position === 'static';
1119
- }
1120
-
1121
- function getTrueOffsetParent(element, polyfill) {
1122
- if (!useScrollLock.isHTMLElement(element) || useScrollLock.getComputedStyle(element).position === 'fixed') {
1123
- return null;
1124
- }
1125
- if (polyfill) {
1126
- return polyfill(element);
1127
- }
1128
- let rawOffsetParent = element.offsetParent;
1129
-
1130
- // Firefox returns the <html> element as the offsetParent if it's non-static,
1131
- // while Chrome and Safari return the <body> element. The <body> element must
1132
- // be used to perform the correct calculations even if the <html> element is
1133
- // non-static.
1134
- if (useScrollLock.getDocumentElement(element) === rawOffsetParent) {
1135
- rawOffsetParent = rawOffsetParent.ownerDocument.body;
1136
- }
1137
- return rawOffsetParent;
1138
- }
1139
-
1140
- // Gets the closest ancestor positioned element. Handles some edge cases,
1141
- // such as table ancestors and cross browser bugs.
1142
- function getOffsetParent(element, polyfill) {
1143
- const win = useScrollLock.getWindow(element);
1144
- if (useScrollLock.isTopLayer(element)) {
1145
- return win;
1146
- }
1147
- if (!useScrollLock.isHTMLElement(element)) {
1148
- let svgOffsetParent = useScrollLock.getParentNode(element);
1149
- while (svgOffsetParent && !useScrollLock.isLastTraversableNode(svgOffsetParent)) {
1150
- if (useScrollLock.isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) {
1151
- return svgOffsetParent;
1152
- }
1153
- svgOffsetParent = useScrollLock.getParentNode(svgOffsetParent);
1154
- }
1155
- return win;
1156
- }
1157
- let offsetParent = getTrueOffsetParent(element, polyfill);
1158
- while (offsetParent && useScrollLock.isTableElement(offsetParent) && isStaticPositioned(offsetParent)) {
1159
- offsetParent = getTrueOffsetParent(offsetParent, polyfill);
1160
- }
1161
- if (offsetParent && useScrollLock.isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !useScrollLock.isContainingBlock(offsetParent)) {
1162
- return win;
1163
- }
1164
- return offsetParent || useScrollLock.getContainingBlock(element) || win;
1165
- }
1166
-
1167
- const getElementRects = async function (data) {
1168
- const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
1169
- const getDimensionsFn = this.getDimensions;
1170
- const floatingDimensions = await getDimensionsFn(data.floating);
1171
- return {
1172
- reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy),
1173
- floating: {
1174
- x: 0,
1175
- y: 0,
1176
- width: floatingDimensions.width,
1177
- height: floatingDimensions.height
1178
- }
1179
- };
1180
- };
1181
-
1182
- function isRTL(element) {
1183
- return useScrollLock.getComputedStyle(element).direction === 'rtl';
1184
- }
1185
-
1186
- const platform = {
1187
- convertOffsetParentRelativeRectToViewportRelativeRect,
1188
- getDocumentElement: useScrollLock.getDocumentElement,
1189
- getClippingRect,
1190
- getOffsetParent,
1191
- getElementRects,
1192
- getClientRects,
1193
- getDimensions,
1194
- getScale,
1195
- isElement: useScrollLock.isElement,
1196
- isRTL
1197
- };
1198
-
1199
- function rectsAreEqual(a, b) {
1200
- return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
1201
- }
1202
-
1203
- // https://samthor.au/2021/observing-dom/
1204
- function observeMove(element, onMove, ancestorResize) {
1205
- let io = null;
1206
- let timeoutId;
1207
- const root = useScrollLock.getDocumentElement(element);
1208
- function cleanup() {
1209
- var _io;
1210
- clearTimeout(timeoutId);
1211
- (_io = io) == null || _io.disconnect();
1212
- io = null;
1213
- }
1214
- function refresh(skip, threshold) {
1215
- if (skip === void 0) {
1216
- skip = false;
1217
- }
1218
- if (threshold === void 0) {
1219
- threshold = 1;
1220
- }
1221
- cleanup();
1222
- const elementRectForRootMargin = element.getBoundingClientRect();
1223
- const {
1224
- left,
1225
- top,
1226
- width,
1227
- height
1228
- } = elementRectForRootMargin;
1229
- if (!skip) {
1230
- onMove();
1231
- }
1232
- if (!width || !height) {
1233
- return;
1234
- }
1235
- const insetTop = useScrollLock.floor(top);
1236
- const insetRight = useScrollLock.floor(root.clientWidth - (left + width));
1237
- const insetBottom = useScrollLock.floor(root.clientHeight - (top + height));
1238
- const insetLeft = useScrollLock.floor(left);
1239
- const rootMargin = -insetTop + "px " + -insetRight + "px " + -insetBottom + "px " + -insetLeft + "px";
1240
- const options = {
1241
- rootMargin,
1242
- threshold: useScrollLock.max(0, useScrollLock.min(1, threshold)) || 1
1243
- };
1244
- let isFirstUpdate = true;
1245
- function handleObserve(entries) {
1246
- const ratio = entries[0].intersectionRatio;
1247
-
1248
- // The entry is a snapshot, so the reference may have moved since the
1249
- // intersection was computed (under performance constraints, or between
1250
- // consecutive frames of a multi-frame layout shift). The reported ratio
1251
- // and the observed area are stale in that case and cannot be trusted to
1252
- // detect subsequent movement, so refresh regardless of the ratio.
1253
- if (!rectsAreEqual(elementRectForRootMargin, element.getBoundingClientRect())) {
1254
- return refresh();
1255
- }
1256
- if (ratio !== threshold) {
1257
- if (!isFirstUpdate) {
1258
- return refresh();
1259
- }
1260
- if (!ratio) {
1261
- // If the reference is clipped in place, the ratio is 0. Throttle
1262
- // the refresh to prevent an infinite loop of updates.
1263
- timeoutId = setTimeout(() => {
1264
- refresh(false, 1e-7);
1265
- }, 1000);
1266
- } else {
1267
- refresh(false, ratio);
1268
- }
1269
- }
1270
- isFirstUpdate = false;
1271
- }
1272
-
1273
- // Older browsers don't support a `document` as the root and will throw an
1274
- // error.
1275
- try {
1276
- io = new IntersectionObserver(handleObserve, {
1277
- ...options,
1278
- // Handle <iframe>s
1279
- root: root.ownerDocument
1280
- });
1281
- } catch (_e) {
1282
- io = new IntersectionObserver(handleObserve, options);
1283
- }
1284
- io.observe(element);
1285
- }
1286
- const win = useScrollLock.getWindow(element);
1287
- // The window is a resize ancestor, so when `ancestorResize` is enabled its
1288
- // listener already runs the update on resize. Here we only need to rebuild
1289
- // the `IntersectionObserver` for the new root size, skipping a redundant
1290
- // update. When `ancestorResize` is disabled, this becomes the sole update.
1291
- const handleResize = () => refresh(ancestorResize);
1292
- win.addEventListener('resize', handleResize);
1293
- refresh(true);
1294
- return () => {
1295
- win.removeEventListener('resize', handleResize);
1296
- cleanup();
1297
- };
1298
- }
1299
-
1300
- /**
1301
- * Automatically updates the position of the floating element when necessary.
1302
- * Should only be called when the floating element is mounted on the DOM or
1303
- * visible on the screen.
1304
- * @returns cleanup function that should be invoked when the floating element is
1305
- * removed from the DOM or hidden from the screen.
1306
- * @see https://floating-ui.com/docs/autoUpdate
1307
- */
1308
- function autoUpdate(reference, floating, update, options) {
1309
- if (options === void 0) {
1310
- options = {};
1311
- }
1312
- const {
1313
- ancestorScroll = true,
1314
- ancestorResize = true,
1315
- elementResize = typeof ResizeObserver === 'function',
1316
- layoutShift = typeof IntersectionObserver === 'function',
1317
- animationFrame = false
1318
- } = options;
1319
- const referenceEl = unwrapElement(reference);
1320
- const ancestors = ancestorScroll || ancestorResize ? [...(referenceEl ? useScrollLock.getOverflowAncestors(referenceEl) : []), ...(floating ? useScrollLock.getOverflowAncestors(floating) : [])] : [];
1321
- ancestors.forEach(ancestor => {
1322
- ancestorScroll && ancestor.addEventListener('scroll', update);
1323
- ancestorResize && ancestor.addEventListener('resize', update);
1324
- });
1325
- const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update, ancestorResize) : null;
1326
- let reobserveFrame = -1;
1327
- let resizeObserver = null;
1328
- if (elementResize) {
1329
- resizeObserver = new ResizeObserver(_ref => {
1330
- let [firstEntry] = _ref;
1331
- if (firstEntry && firstEntry.target === referenceEl && resizeObserver && floating) {
1332
- // Prevent update loops when using the `size` middleware.
1333
- // https://github.com/floating-ui/floating-ui/issues/1740
1334
- resizeObserver.unobserve(floating);
1335
- cancelAnimationFrame(reobserveFrame);
1336
- reobserveFrame = requestAnimationFrame(() => {
1337
- var _resizeObserver;
1338
- (_resizeObserver = resizeObserver) == null || _resizeObserver.observe(floating);
1339
- });
1340
- }
1341
- update();
1342
- });
1343
- if (referenceEl && !animationFrame) {
1344
- resizeObserver.observe(referenceEl);
1345
- }
1346
- if (floating) {
1347
- resizeObserver.observe(floating);
1348
- }
1349
- }
1350
- let frameId;
1351
- let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;
1352
- if (animationFrame) {
1353
- frameLoop();
1354
- }
1355
- function frameLoop() {
1356
- const nextRefRect = getBoundingClientRect(reference);
1357
- if (prevRefRect && !rectsAreEqual(prevRefRect, nextRefRect)) {
1358
- update();
1359
- }
1360
- prevRefRect = nextRefRect;
1361
- frameId = requestAnimationFrame(frameLoop);
1362
- }
1363
- update();
1364
- return () => {
1365
- var _resizeObserver2;
1366
- ancestors.forEach(ancestor => {
1367
- ancestorScroll && ancestor.removeEventListener('scroll', update);
1368
- ancestorResize && ancestor.removeEventListener('resize', update);
1369
- });
1370
- cleanupIo == null || cleanupIo();
1371
- (_resizeObserver2 = resizeObserver) == null || _resizeObserver2.disconnect();
1372
- resizeObserver = null;
1373
- if (animationFrame) {
1374
- cancelAnimationFrame(frameId);
1375
- }
1376
- };
1377
- }
1378
-
1379
- /**
1380
- * Modifies the placement by translating the floating element along the
1381
- * specified axes.
1382
- * A number (shorthand for `mainAxis` or distance), or an axes configuration
1383
- * object may be passed.
1384
- * @see https://floating-ui.com/docs/offset
1385
- */
1386
- const offset$1 = offset$2;
1387
-
1388
- /**
1389
- * Optimizes the visibility of the floating element by shifting it in order to
1390
- * keep it in view when it will overflow the clipping boundary.
1391
- * @see https://floating-ui.com/docs/shift
1392
- */
1393
- const shift$1 = shift$2;
1394
-
1395
- /**
1396
- * Optimizes the visibility of the floating element by flipping the `placement`
1397
- * in order to keep it in view when the preferred placement(s) will overflow the
1398
- * clipping boundary. Alternative to `autoPlacement`.
1399
- * @see https://floating-ui.com/docs/flip
1400
- */
1401
- const flip$1 = flip$2;
1402
-
1403
- /**
1404
- * Provides data that allows you to change the size of the floating element —
1405
- * for instance, prevent it from overflowing the clipping boundary or match the
1406
- * width of the reference element.
1407
- * @see https://floating-ui.com/docs/size
1408
- */
1409
- const size$1 = size$2;
1410
-
1411
- /**
1412
- * Built-in `limiter` that will stop `shift()` at a certain point.
1413
- */
1414
- const limitShift$1 = limitShift$2;
1415
-
1416
- /**
1417
- * Computes the `x` and `y` coordinates that will place the floating element
1418
- * next to a given reference element.
1419
- */
1420
- const computePosition = (reference, floating, options) => {
1421
- // This caches the expensive `getClippingElementAncestors` function so that
1422
- // multiple lifecycle resets re-use the same result. It only lives for a
1423
- // single call. If other functions become expensive, we can add them as well.
1424
- const cache = new Map();
1425
- const mergedOptions = options != null ? options : {};
1426
- const platformWithCache = {
1427
- ...platform,
1428
- ...mergedOptions.platform,
1429
- _c: cache
1430
- };
1431
- return computePosition$1(reference, floating, {
1432
- ...mergedOptions,
1433
- platform: platformWithCache
1434
- });
1435
- };
1436
-
1437
- var isClient = typeof document !== 'undefined';
1438
-
1439
- var noop = function noop() {};
1440
- var index = isClient ? React.useLayoutEffect : noop;
1441
-
1442
- // Fork of `fast-deep-equal` that only does the comparisons we need and compares
1443
- // functions
1444
- function deepEqual(a, b) {
1445
- if (a === b) {
1446
- return true;
1447
- }
1448
- if (typeof a !== typeof b) {
1449
- return false;
1450
- }
1451
- if (typeof a === 'function' && a.toString() === b.toString()) {
1452
- return true;
1453
- }
1454
- let length;
1455
- let i;
1456
- let keys;
1457
- if (a && b && typeof a === 'object') {
1458
- if (Array.isArray(a)) {
1459
- length = a.length;
1460
- if (length !== b.length) return false;
1461
- for (i = length; i-- !== 0;) {
1462
- if (!deepEqual(a[i], b[i])) {
1463
- return false;
1464
- }
1465
- }
1466
- return true;
1467
- }
1468
- keys = Object.keys(a);
1469
- length = keys.length;
1470
- if (length !== Object.keys(b).length) {
1471
- return false;
1472
- }
1473
- for (i = length; i-- !== 0;) {
1474
- if (!{}.hasOwnProperty.call(b, keys[i])) {
1475
- return false;
1476
- }
1477
- }
1478
- for (i = length; i-- !== 0;) {
1479
- const key = keys[i];
1480
- if (key === '_owner' && a.$$typeof) {
1481
- continue;
1482
- }
1483
- if (!deepEqual(a[key], b[key])) {
1484
- return false;
1485
- }
1486
- }
1487
- return true;
1488
- }
1489
- return a !== a && b !== b;
1490
- }
1491
-
1492
- function getDPR(element) {
1493
- if (typeof window === 'undefined') {
1494
- return 1;
1495
- }
1496
- const win = element.ownerDocument.defaultView || window;
1497
- return win.devicePixelRatio || 1;
1498
- }
1499
-
1500
- function roundByDPR(element, value) {
1501
- const dpr = getDPR(element);
1502
- return Math.round(value * dpr) / dpr;
1503
- }
1504
-
1505
- function useLatestRef(value) {
1506
- const ref = React__namespace.useRef(value);
1507
- index(() => {
1508
- ref.current = value;
1509
- });
1510
- return ref;
1511
- }
1512
-
1513
- /**
1514
- * Provides data to position a floating element.
1515
- * @see https://floating-ui.com/docs/useFloating
1516
- */
1517
- function useFloating(options) {
1518
- if (options === void 0) {
1519
- options = {};
1520
- }
1521
- const {
1522
- placement = 'bottom',
1523
- strategy = 'absolute',
1524
- middleware = [],
1525
- platform,
1526
- elements: {
1527
- reference: externalReference,
1528
- floating: externalFloating
1529
- } = {},
1530
- transform = true,
1531
- whileElementsMounted,
1532
- open
1533
- } = options;
1534
- const [data, setData] = React__namespace.useState({
1535
- x: 0,
1536
- y: 0,
1537
- strategy,
1538
- placement,
1539
- middlewareData: {},
1540
- isPositioned: false
1541
- });
1542
- const [latestMiddleware, setLatestMiddleware] = React__namespace.useState(middleware);
1543
- if (!deepEqual(latestMiddleware, middleware)) {
1544
- setLatestMiddleware(middleware);
1545
- }
1546
- const [_reference, _setReference] = React__namespace.useState(null);
1547
- const [_floating, _setFloating] = React__namespace.useState(null);
1548
- const setReference = React__namespace.useCallback(node => {
1549
- if (node !== referenceRef.current) {
1550
- referenceRef.current = node;
1551
- _setReference(node);
1552
- }
1553
- }, []);
1554
- const setFloating = React__namespace.useCallback(node => {
1555
- if (node !== floatingRef.current) {
1556
- floatingRef.current = node;
1557
- _setFloating(node);
1558
- }
1559
- }, []);
1560
- const referenceEl = externalReference || _reference;
1561
- const floatingEl = externalFloating || _floating;
1562
- const referenceRef = React__namespace.useRef(null);
1563
- const floatingRef = React__namespace.useRef(null);
1564
- const dataRef = React__namespace.useRef(data);
1565
- const hasWhileElementsMounted = whileElementsMounted != null;
1566
- const whileElementsMountedRef = useLatestRef(whileElementsMounted);
1567
- const platformRef = useLatestRef(platform);
1568
- const openRef = useLatestRef(open);
1569
- const update = React__namespace.useCallback(() => {
1570
- if (!referenceRef.current || !floatingRef.current) {
1571
- return;
1572
- }
1573
- const config = {
1574
- placement,
1575
- strategy,
1576
- middleware: latestMiddleware
1577
- };
1578
- if (platformRef.current) {
1579
- config.platform = platformRef.current;
1580
- }
1581
- computePosition(referenceRef.current, floatingRef.current, config).then(data => {
1582
- const fullData = {
1583
- ...data,
1584
- // The floating element's position may be recomputed while it's closed
1585
- // but still mounted (such as when transitioning out). To ensure
1586
- // `isPositioned` will be `false` initially on the next open, avoid
1587
- // setting it to `true` when `open === false` (must be specified).
1588
- isPositioned: openRef.current !== false
1589
- };
1590
- if (isMountedRef.current && !deepEqual(dataRef.current, fullData)) {
1591
- dataRef.current = fullData;
1592
- ReactDOM__namespace.flushSync(() => {
1593
- setData(fullData);
1594
- });
1595
- }
1596
- });
1597
- }, [latestMiddleware, placement, strategy, platformRef, openRef]);
1598
- index(() => {
1599
- if (open === false && dataRef.current.isPositioned) {
1600
- dataRef.current.isPositioned = false;
1601
- setData(data => ({
1602
- ...data,
1603
- isPositioned: false
1604
- }));
1605
- }
1606
- }, [open]);
1607
- const isMountedRef = React__namespace.useRef(false);
1608
- index(() => {
1609
- isMountedRef.current = true;
1610
- return () => {
1611
- isMountedRef.current = false;
1612
- };
1613
- }, []);
1614
- index(() => {
1615
- if (referenceEl) referenceRef.current = referenceEl;
1616
- if (floatingEl) floatingRef.current = floatingEl;
1617
- if (referenceEl && floatingEl) {
1618
- if (whileElementsMountedRef.current) {
1619
- return whileElementsMountedRef.current(referenceEl, floatingEl, update);
1620
- }
1621
- update();
1622
- }
1623
- }, [referenceEl, floatingEl, update, whileElementsMountedRef, hasWhileElementsMounted]);
1624
- const refs = React__namespace.useMemo(() => ({
1625
- reference: referenceRef,
1626
- floating: floatingRef,
1627
- setReference,
1628
- setFloating
1629
- }), [setReference, setFloating]);
1630
- const elements = React__namespace.useMemo(() => ({
1631
- reference: referenceEl,
1632
- floating: floatingEl
1633
- }), [referenceEl, floatingEl]);
1634
- const floatingStyles = React__namespace.useMemo(() => {
1635
- const initialStyles = {
1636
- position: strategy,
1637
- left: 0,
1638
- top: 0
1639
- };
1640
- if (!elements.floating) {
1641
- return initialStyles;
1642
- }
1643
- const x = roundByDPR(elements.floating, data.x);
1644
- const y = roundByDPR(elements.floating, data.y);
1645
- if (transform) {
1646
- return {
1647
- ...initialStyles,
1648
- transform: "translate(" + x + "px, " + y + "px)",
1649
- ...(getDPR(elements.floating) >= 1.5 && {
1650
- willChange: 'transform'
1651
- })
1652
- };
1653
- }
1654
- return {
1655
- position: strategy,
1656
- left: x,
1657
- top: y
1658
- };
1659
- }, [strategy, transform, elements.floating, data.x, data.y]);
1660
- return React__namespace.useMemo(() => ({
1661
- ...data,
1662
- update,
1663
- refs,
1664
- elements,
1665
- floatingStyles
1666
- }), [data, update, refs, elements, floatingStyles]);
1667
- }
1668
-
1669
- /**
1670
- * Modifies the placement by translating the floating element along the
1671
- * specified axes.
1672
- * A number (shorthand for `mainAxis` or distance), or an axes configuration
1673
- * object may be passed.
1674
- * @see https://floating-ui.com/docs/offset
1675
- */
1676
- const offset = (options, deps) => {
1677
- const result = offset$1(options);
1678
- return {
1679
- name: result.name,
1680
- fn: result.fn,
1681
- options: [options, deps]
1682
- };
1683
- };
1684
-
1685
- /**
1686
- * Optimizes the visibility of the floating element by shifting it in order to
1687
- * keep it in view when it will overflow the clipping boundary.
1688
- * @see https://floating-ui.com/docs/shift
1689
- */
1690
- const shift = (options, deps) => {
1691
- const result = shift$1(options);
1692
- return {
1693
- name: result.name,
1694
- fn: result.fn,
1695
- options: [options, deps]
1696
- };
1697
- };
1698
-
1699
- /**
1700
- * Built-in `limiter` that will stop `shift()` at a certain point.
1701
- */
1702
- const limitShift = (options, deps) => {
1703
- const result = limitShift$1(options);
1704
- return {
1705
- fn: result.fn,
1706
- options: [options, deps]
1707
- };
1708
- };
1709
-
1710
- /**
1711
- * Optimizes the visibility of the floating element by flipping the `placement`
1712
- * in order to keep it in view when the preferred placement(s) will overflow the
1713
- * clipping boundary. Alternative to `autoPlacement`.
1714
- * @see https://floating-ui.com/docs/flip
1715
- */
1716
- const flip = (options, deps) => {
1717
- const result = flip$1(options);
1718
- return {
1719
- name: result.name,
1720
- fn: result.fn,
1721
- options: [options, deps]
1722
- };
1723
- };
1724
-
1725
- /**
1726
- * Provides data that allows you to change the size of the floating element —
1727
- * for instance, prevent it from overflowing the clipping boundary or match the
1728
- * width of the reference element.
1729
- * @see https://floating-ui.com/docs/size
1730
- */
1731
- const size = (options, deps) => {
1732
- const result = size$1(options);
1733
- return {
1734
- name: result.name,
1735
- fn: result.fn,
1736
- options: [options, deps]
1737
- };
1738
- };
1739
28
 
1740
29
  function useFloatingRootContext(options) {
1741
30
  const {
@@ -1747,7 +36,7 @@ function useFloatingRootContext(options) {
1747
36
  const nested = useScrollLock.useFloatingParentNodeId() != null;
1748
37
  if (process.env.NODE_ENV !== 'production') {
1749
38
  const optionDomReference = elements.reference;
1750
- if (optionDomReference && !useScrollLock.isElement(optionDomReference)) {
39
+ if (optionDomReference && !floatingUi_utils.isElement(optionDomReference)) {
1751
40
  console.error('Cannot pass a virtual element to the `elements.reference` option,', 'as it must be a real DOM element. Use `context.setPositionReference()`', 'instead.');
1752
41
  }
1753
42
  }
@@ -1771,7 +60,7 @@ function useFloatingRootContext(options) {
1771
60
  // Only sync elements that are defined to avoid overwriting existing ones
1772
61
  if (elements.reference !== undefined) {
1773
62
  valuesToSync.referenceElement = elements.reference;
1774
- valuesToSync.domReferenceElement = useScrollLock.isElement(elements.reference) ? elements.reference : null;
63
+ valuesToSync.domReferenceElement = floatingUi_utils.isElement(elements.reference) ? elements.reference : null;
1775
64
  }
1776
65
  if (elements.floating !== undefined) {
1777
66
  valuesToSync.floatingElement = elements.floating;
@@ -1784,17 +73,16 @@ function useFloatingRootContext(options) {
1784
73
  }
1785
74
 
1786
75
  /**
1787
- * Base UI's private `useFloating` path. The caller must supply the root store, so this skips the
1788
- * internal root-context hook used by the public Floating UI-compatible API.
76
+ * Provides data to position a floating element and context to add interactions.
77
+ * @see https://floating-ui.com/docs/useFloating
1789
78
  */
1790
- function useBaseUIFloating(options) {
1791
- return useFloatingWithStore(options, options.rootContext);
1792
- }
1793
- function useFloatingWithStore(options, store) {
79
+ function useFloating(options = {}) {
1794
80
  const {
1795
81
  nodeId,
1796
82
  externalTree
1797
83
  } = options;
84
+ const internalStore = useFloatingRootContext(options);
85
+ const store = options.rootContext || internalStore;
1798
86
  const referenceElement = store.useState('referenceElement');
1799
87
  const floatingElement = store.useState('floatingElement');
1800
88
  const domReferenceElement = store.useState('domReferenceElement');
@@ -1810,7 +98,7 @@ function useFloatingWithStore(options, store) {
1810
98
  floating: floatingElement,
1811
99
  domReference: domReferenceElement
1812
100
  }), [referenceElement, floatingElement, domReferenceElement]);
1813
- const position = useFloating({
101
+ const position = floatingUi_reactDom.useFloating({
1814
102
  ...options,
1815
103
  elements: {
1816
104
  ...storeElements,
@@ -1819,13 +107,13 @@ function useFloatingWithStore(options, store) {
1819
107
  })
1820
108
  }
1821
109
  });
1822
- const localDomReferenceElement = useScrollLock.isElement(localDomReference) ? localDomReference : null;
110
+ const localDomReferenceElement = floatingUi_utils.isElement(localDomReference) ? localDomReference : null;
1823
111
  const syncedFloatingElement = localFloatingElement === undefined ? store.state.floatingElement : localFloatingElement;
1824
112
  store.useSyncedValue('referenceElement', localDomReference ?? null);
1825
113
  store.useSyncedValue('domReferenceElement', localDomReference === undefined ? domReferenceElement : localDomReferenceElement);
1826
114
  store.useSyncedValue('floatingElement', syncedFloatingElement);
1827
115
  const setPositionReference = React__namespace.useCallback(node => {
1828
- const computedPositionReference = useScrollLock.isElement(node) ? {
116
+ const computedPositionReference = floatingUi_utils.isElement(node) ? {
1829
117
  getBoundingClientRect: () => node.getBoundingClientRect(),
1830
118
  getClientRects: () => node.getClientRects(),
1831
119
  contextElement: node
@@ -1836,18 +124,18 @@ function useFloatingWithStore(options, store) {
1836
124
  position.refs.setReference(computedPositionReference);
1837
125
  }, [position.refs]);
1838
126
  const setReference = React__namespace.useCallback(node => {
1839
- if (useScrollLock.isElement(node) || node === null) {
127
+ if (floatingUi_utils.isElement(node) || node === null) {
1840
128
  domReferenceRef.current = node;
1841
129
  setLocalDomReference(node);
1842
130
  }
1843
131
 
1844
132
  // Backwards-compatibility for passing a virtual element to `reference`
1845
133
  // after it has set the DOM reference.
1846
- if (useScrollLock.isElement(position.refs.reference.current) || position.refs.reference.current === null ||
134
+ if (floatingUi_utils.isElement(position.refs.reference.current) || position.refs.reference.current === null ||
1847
135
  // Don't allow setting virtual elements using the old technique back to
1848
136
  // `null` to support `positionReference` + an unstable `reference`
1849
137
  // callback ref.
1850
- node !== null && !useScrollLock.isElement(node)) {
138
+ node !== null && !floatingUi_utils.isElement(node)) {
1851
139
  position.refs.setReference(node);
1852
140
  }
1853
141
  }, [position.refs, setLocalDomReference]);
@@ -1900,13 +188,6 @@ function useFloatingWithStore(options, store) {
1900
188
  }
1901
189
 
1902
190
  const ESCAPE = 'Escape';
1903
-
1904
- // WebKit fires zero-delta `mousemove`/`pointermove` events when the list scrolls
1905
- // beneath a stationary pointer, moving the highlight during keyboard navigation.
1906
- // https://github.com/mui/base-ui/issues/4002
1907
- function isStationaryWebKitPointer(event) {
1908
- return useScrollLock.webkit && event.movementX === 0 && event.movementY === 0;
1909
- }
1910
191
  function doSwitch(orientation, vertical, horizontal) {
1911
192
  switch (orientation) {
1912
193
  case 'vertical':
@@ -2203,7 +484,7 @@ function useListNavigation(context, props) {
2203
484
  useScrollLock.stopEvent(event);
2204
485
  }
2205
486
  store.setOpen(false, useScrollLock.createChangeEventDetails(useScrollLock.listNavigation, event.nativeEvent));
2206
- if (useScrollLock.isHTMLElement(domReferenceElement)) {
487
+ if (floatingUi_utils.isHTMLElement(domReferenceElement)) {
2207
488
  if (virtual) {
2208
489
  tree?.events.emit('virtualfocus', domReferenceElement);
2209
490
  } else {
@@ -2313,9 +594,6 @@ function useListNavigation(context, props) {
2313
594
  }),
2314
595
  // Safari
2315
596
  onMouseMove(event) {
2316
- if (isStationaryWebKitPointer(event)) {
2317
- return;
2318
- }
2319
597
  forceSyncFocusRef.current = true;
2320
598
  forceScrollIntoViewRef.current = false;
2321
599
  if (focusItemOnHover) {
@@ -2372,17 +650,14 @@ function useListNavigation(context, props) {
2372
650
  }
2373
651
  useScrollLock.stopEvent(event);
2374
652
  store.setOpen(false, useScrollLock.createChangeEventDetails(useScrollLock.focusOut, event.nativeEvent));
2375
- if (useScrollLock.isHTMLElement(domReferenceElement)) {
653
+ if (floatingUi_utils.isHTMLElement(domReferenceElement)) {
2376
654
  domReferenceElement.focus();
2377
655
  }
2378
656
  return;
2379
657
  }
2380
658
  commonOnKeyDown(event);
2381
659
  },
2382
- onPointerMove(event) {
2383
- if (isStationaryWebKitPointer(event)) {
2384
- return;
2385
- }
660
+ onPointerMove() {
2386
661
  isPointerModalityRef.current = true;
2387
662
  }
2388
663
  };
@@ -2503,19 +778,18 @@ function useTypeahead(context, props) {
2503
778
  const prevIndexRef = React__namespace.useRef(selectedIndex ?? activeIndex ?? -1);
2504
779
  const matchIndexRef = React__namespace.useRef(null);
2505
780
  const onKeyDown = useScrollLock.useStableCallback(event => {
2506
- function getElement(index) {
2507
- return elementsRef?.current[index];
781
+ function isVisible(index) {
782
+ const element = elementsRef?.current[index];
783
+ return !element || useScrollLock.isElementVisible(element);
2508
784
  }
2509
785
  function isItemAvailable(index) {
2510
- const element = getElement(index);
2511
- if (element && !useScrollLock.isElementVisible(element) || element?.matches(':disabled')) {
786
+ if (!isVisible(index)) {
2512
787
  return false;
2513
788
  }
2514
- // Visibility and native disabled state are handled above; pass an empty
2515
- // element list so `isListIndexDisabled` resolves only the explicit
2516
- // `disabledIndices` (array/predicate) and skips its own fallbacks.
2517
- // Consumers that don't pass `disabledIndices` keep matching every visible
2518
- // item except native disabled elements provided through `elementsRef`.
789
+ // Visibility is handled above; pass an empty element list so `isListIndexDisabled`
790
+ // resolves only the explicit `disabledIndices` (array/predicate) and skips its own
791
+ // visibility/attribute fallbacks. Consumers that don't opt in keep matching every
792
+ // visible item.
2519
793
  return disabledIndices == null || !useScrollLock.isListIndexDisabled(useRenderElement.EMPTY_ARRAY, index, disabledIndices);
2520
794
  }
2521
795
  function getMatchingIndex(list, string, startIndex = 0) {
@@ -2623,6 +897,12 @@ function useTypeahead(context, props) {
2623
897
  stringRef.current = '';
2624
898
  }
2625
899
  }, [open, selectedIndex, timeout]);
900
+ useScrollLock.useIsoLayoutEffect(() => {
901
+ // Sync arrow key navigation but not typeahead navigation.
902
+ if (open && stringRef.current === '') {
903
+ prevIndexRef.current = selectedIndex ?? activeIndex ?? -1;
904
+ }
905
+ }, [open, selectedIndex, activeIndex]);
2626
906
  const sharedProps = React__namespace.useMemo(() => ({
2627
907
  onKeyDown,
2628
908
  onBlur
@@ -2662,12 +942,6 @@ function findItemIndex(itemValues, selectedValue, comparer) {
2662
942
  return compareItemEquality(itemValue, selectedValue, comparer);
2663
943
  });
2664
944
  }
2665
- function findSelectionIndex(itemValues, selectedValue, comparer, multiple) {
2666
- // Only unwrap in multiple mode: an array can itself be a valid single-select value.
2667
- const lastValue = multiple && Array.isArray(selectedValue) ? selectedValue[selectedValue.length - 1] : selectedValue;
2668
- const index = findItemIndex(itemValues, lastValue, comparer);
2669
- return index === -1 ? null : index;
2670
- }
2671
945
  function removeItem(selectedValues, itemValue, comparer) {
2672
946
  return selectedValues.filter(selectedValue => !compareItemEquality(itemValue, selectedValue, comparer));
2673
947
  }
@@ -2790,6 +1064,38 @@ function resolveMultipleLabels(values, items, itemToStringLabel) {
2790
1064
  }, []);
2791
1065
  }
2792
1066
 
1067
+ let FieldControlDataAttributes = /*#__PURE__*/function (FieldControlDataAttributes) {
1068
+ /**
1069
+ * Present when the field is disabled.
1070
+ */
1071
+ FieldControlDataAttributes["disabled"] = "data-disabled";
1072
+ /**
1073
+ * Present when the field is in a valid state.
1074
+ */
1075
+ FieldControlDataAttributes["valid"] = "data-valid";
1076
+ /**
1077
+ * Present when the field is in an invalid state.
1078
+ */
1079
+ FieldControlDataAttributes["invalid"] = "data-invalid";
1080
+ /**
1081
+ * Present when the field has been touched.
1082
+ */
1083
+ FieldControlDataAttributes["touched"] = "data-touched";
1084
+ /**
1085
+ * Present when the field's value has changed.
1086
+ */
1087
+ FieldControlDataAttributes["dirty"] = "data-dirty";
1088
+ /**
1089
+ * Present when the field is filled.
1090
+ */
1091
+ FieldControlDataAttributes["filled"] = "data-filled";
1092
+ /**
1093
+ * Present when the field control is focused.
1094
+ */
1095
+ FieldControlDataAttributes["focused"] = "data-focused";
1096
+ return FieldControlDataAttributes;
1097
+ }({});
1098
+
2793
1099
  const DEFAULT_VALIDITY_STATE = {
2794
1100
  badInput: false,
2795
1101
  customError: false,
@@ -2821,11 +1127,11 @@ const fieldValidityMapping = {
2821
1127
  }
2822
1128
  if (value) {
2823
1129
  return {
2824
- 'data-valid': ''
1130
+ [FieldControlDataAttributes.valid]: ''
2825
1131
  };
2826
1132
  }
2827
1133
  return {
2828
- 'data-invalid': ''
1134
+ [FieldControlDataAttributes.invalid]: ''
2829
1135
  };
2830
1136
  }
2831
1137
  };
@@ -2842,22 +1148,29 @@ const DEFAULT_FIELD_ROOT_CONTEXT = {
2842
1148
  },
2843
1149
  setValidityData: useRenderElement.NOOP,
2844
1150
  disabled: undefined,
1151
+ touched: DEFAULT_FIELD_STATE_ATTRIBUTES.touched,
2845
1152
  setTouched: useRenderElement.NOOP,
1153
+ dirty: DEFAULT_FIELD_STATE_ATTRIBUTES.dirty,
2846
1154
  setDirty: useRenderElement.NOOP,
1155
+ filled: DEFAULT_FIELD_STATE_ATTRIBUTES.filled,
2847
1156
  setFilled: useRenderElement.NOOP,
1157
+ focused: DEFAULT_FIELD_STATE_ATTRIBUTES.focused,
2848
1158
  setFocused: useRenderElement.NOOP,
1159
+ validate: () => null,
2849
1160
  validationMode: 'onSubmit',
1161
+ validationDebounceTime: 0,
2850
1162
  shouldValidateOnChange: () => false,
2851
1163
  state: DEFAULT_FIELD_ROOT_STATE,
1164
+ markedDirtyRef: {
1165
+ current: false
1166
+ },
2852
1167
  registerFieldControl: useRenderElement.NOOP,
2853
1168
  validation: {
2854
1169
  getValidationProps: (_disabled, props = useRenderElement.EMPTY_OBJECT) => props,
2855
1170
  inputRef: {
2856
1171
  current: null
2857
1172
  },
2858
- registeredInputs: new Map(),
2859
1173
  registerInput: useRenderElement.NOOP,
2860
- getInputControl: () => null,
2861
1174
  commit: async () => {},
2862
1175
  change: useRenderElement.NOOP
2863
1176
  }
@@ -2876,16 +1189,14 @@ function useRegisterFieldControl(controlRef, id, value, getFormValueOverride, en
2876
1189
  const {
2877
1190
  registerFieldControl
2878
1191
  } = useFieldRootContext();
2879
- const sourceRef = useRenderElement.useRefWithInit(() => Symbol());
2880
-
2881
- // Re-register without unregistering first: re-registration with the same id updates the
2882
- // form's fields Map entry in place, while a delete + re-add would move the field to the
2883
- // end of the Map every time its value changes.
1192
+ const sourceRef = React__namespace.useRef(null);
1193
+ if (!sourceRef.current) {
1194
+ sourceRef.current = Symbol();
1195
+ }
2884
1196
  useScrollLock.useIsoLayoutEffect(() => {
2885
1197
  const source = sourceRef.current;
2886
- if (!enabled) {
2887
- registerFieldControl(source, undefined);
2888
- return;
1198
+ if (!source || !enabled) {
1199
+ return undefined;
2889
1200
  }
2890
1201
  const registration = {
2891
1202
  controlRef,
@@ -2895,19 +1206,13 @@ function useRegisterFieldControl(controlRef, id, value, getFormValueOverride, en
2895
1206
  value
2896
1207
  };
2897
1208
  registerFieldControl(source, registration);
2898
- }, [controlRef, enabled, getFormValueOverride, id, name, registerFieldControl, sourceRef, value]);
2899
- useScrollLock.useIsoLayoutEffect(() => {
2900
- const source = sourceRef.current;
2901
1209
  return () => {
2902
1210
  registerFieldControl(source, undefined);
2903
1211
  };
2904
- }, [registerFieldControl, sourceRef]);
1212
+ }, [controlRef, enabled, getFormValueOverride, id, name, registerFieldControl, value]);
2905
1213
  }
2906
1214
 
2907
1215
  const FormContext = /*#__PURE__*/React__namespace.createContext({
2908
- elementRef: {
2909
- current: null
2910
- },
2911
1216
  formRef: {
2912
1217
  current: {
2913
1218
  fields: new Map()
@@ -2955,7 +1260,7 @@ function useLabelableId(params = {}) {
2955
1260
  } = useLabelableContext();
2956
1261
  const defaultId = useScrollLock.useBaseUiId(id);
2957
1262
  const controlIdForEffect = implicit ? controlId : undefined;
2958
- const controlSourceRef = useRenderElement.useRefWithInit(() => Symbol());
1263
+ const controlSourceRef = useRenderElement.useRefWithInit(() => Symbol('labelable-control'));
2959
1264
  const hasRegisteredRef = React__namespace.useRef(false);
2960
1265
  const hadExplicitIdRef = React__namespace.useRef(id != null);
2961
1266
  const unregisterControlId = useScrollLock.useStableCallback(() => {
@@ -2972,7 +1277,7 @@ function useLabelableId(params = {}) {
2972
1277
  let nextId;
2973
1278
  if (implicit) {
2974
1279
  const elem = controlRef?.current;
2975
- if (useScrollLock.isElement(elem) && elem.closest('label') != null) {
1280
+ if (floatingUi_utils.isElement(elem) && elem.closest('label') != null) {
2976
1281
  nextId = id ?? null;
2977
1282
  } else {
2978
1283
  nextId = controlIdForEffect ?? defaultId;
@@ -3004,22 +1309,9 @@ function areArraysEqual(array1, array2, itemComparer = (a, b) => a === b) {
3004
1309
  return array1.length === array2.length && array1.every((value, index) => itemComparer(value, array2[index]));
3005
1310
  }
3006
1311
 
3007
- // Tolerance around the element bounds so a fast click whose pointer drifts slightly
3008
- // during press-release isn't mistaken for a drag-off-and-release cancellation.
3009
- // Matches typical OS/browser drag-initiation thresholds.
3010
- const BOUNDARY_OFFSET = 5;
3011
-
3012
- /**
3013
- * Determines if a mouse event occurred within the bounds of an element
3014
- * (including its pseudo-elements), with a small tolerance for pointer drift.
3015
- */
3016
- function isMouseWithinBounds(event, element) {
3017
- const bounds = getPseudoElementBounds(element);
3018
- return event.clientX >= bounds.left - BOUNDARY_OFFSET && event.clientX <= bounds.right + BOUNDARY_OFFSET && event.clientY >= bounds.top - BOUNDARY_OFFSET && event.clientY <= bounds.bottom + BOUNDARY_OFFSET;
3019
- }
3020
1312
  function getPseudoElementBounds(element) {
3021
1313
  const elementRect = element.getBoundingClientRect();
3022
- const win = useScrollLock.getWindow(element);
1314
+ const win = floatingUi_utils.getWindow(element);
3023
1315
 
3024
1316
  // Avoid "Not implemented: window.getComputedStyle(elt, pseudoElt)" in jsdom.
3025
1317
  if (useScrollLock.jsdom) {
@@ -3063,7 +1355,12 @@ function resolveAriaLabelledBy(fieldLabelId, localLabelId) {
3063
1355
  const CompositeListContext = /*#__PURE__*/React__namespace.createContext({
3064
1356
  register: () => {},
3065
1357
  unregister: () => {},
3066
- subscribeMapChange: () => () => {},
1358
+ subscribeMapChange: () => {
1359
+ return () => {};
1360
+ },
1361
+ elementsRef: {
1362
+ current: []
1363
+ },
3067
1364
  nextIndexRef: {
3068
1365
  current: 0
3069
1366
  }
@@ -3076,6 +1373,7 @@ function useCompositeListContext() {
3076
1373
  /* eslint-disable no-bitwise */
3077
1374
  /**
3078
1375
  * Provides context for a list of items in a composite component.
1376
+ * @internal
3079
1377
  */
3080
1378
  function CompositeList(props) {
3081
1379
  const {
@@ -3085,146 +1383,114 @@ function CompositeList(props) {
3085
1383
  onMapChange: onMapChangeProp
3086
1384
  } = props;
3087
1385
  const onMapChange = useScrollLock.useStableCallback(onMapChangeProp);
3088
- const [, setMapTick] = React__namespace.useState(false);
1386
+ const nextIndexRef = React__namespace.useRef(0);
3089
1387
  const listeners = useRenderElement.useRefWithInit(createListeners).current;
1388
+
1389
+ // We use a stable `map` to avoid O(n^2) re-allocation costs for large lists.
1390
+ // `mapTick` is our re-render trigger mechanism. We also need to update the
1391
+ // elements and label refs, but there's a lot of async work going on and sometimes
1392
+ // the effect that handles `onMapChange` gets called after those refs have been
1393
+ // filled, and we don't want to lose those values by setting their lengths to `0`.
1394
+ // We also need to have them at the proper length because floating-ui uses that
1395
+ // information for list navigation.
1396
+
3090
1397
  const map = useRenderElement.useRefWithInit(createMap).current;
3091
- const nextIndexRef = React__namespace.useRef(0);
3092
- const isDirtyRef = React__namespace.useRef(true);
3093
- const itemsRef = React__namespace.useRef([]);
3094
- const mutationObserverRef = React__namespace.useRef(null);
3095
-
3096
- // Item effects can run without their parent rendering. Schedule one synchronous
3097
- // parent update for the whole commit so refs are rebuilt before paint and while
3098
- // the originating React event is still inside `act()` in tests.
3099
- const scheduleMapUpdate = useScrollLock.useStableCallback(() => {
3100
- if (isDirtyRef.current) {
3101
- return;
3102
- }
3103
- isDirtyRef.current = true;
3104
- setMapTick(tick => !tick);
3105
- });
3106
- const register = useScrollLock.useStableCallback((node, registration) => {
3107
- map.set(node, registration);
3108
- scheduleMapUpdate();
1398
+ // `mapTick` uses a counter rather than objects for low precision-loss risk and better memory efficiency
1399
+ const [mapTick, setMapTick] = React__namespace.useState(0);
1400
+ const lastTickRef = React__namespace.useRef(mapTick);
1401
+ const register = useScrollLock.useStableCallback((node, metadata) => {
1402
+ map.set(node, metadata ?? null);
1403
+ lastTickRef.current += 1;
1404
+ setMapTick(lastTickRef.current);
3109
1405
  });
3110
1406
  const unregister = useScrollLock.useStableCallback(node => {
3111
1407
  map.delete(node);
3112
- scheduleMapUpdate();
1408
+ lastTickRef.current += 1;
1409
+ setMapTick(lastTickRef.current);
3113
1410
  });
3114
- const syncRefs = useScrollLock.useStableCallback(items => {
3115
- const nextMap = new Map();
3116
- elementsRef.current.length = 0;
3117
- if (labelsRef) {
3118
- labelsRef.current.length = 0;
3119
- }
3120
- items.forEach(item => {
3121
- nextMap.set(item.element, {
3122
- ...(item.registration.metadata ?? {}),
3123
- index: item.index
1411
+ const sortedMap = React__namespace.useMemo(() => {
1412
+ const newMap = new Map();
1413
+ // Filter out disconnected elements before sorting to avoid inconsistent
1414
+ // compareDocumentPosition results when elements are detached from the DOM.
1415
+ const sortedNodes = Array.from(map.keys()).filter(node => node.isConnected).sort(sortByDocumentPosition);
1416
+ sortedNodes.forEach((node, index) => {
1417
+ const metadata = map.get(node) ?? {};
1418
+ newMap.set(node, {
1419
+ ...metadata,
1420
+ index
3124
1421
  });
3125
- elementsRef.current[item.index] = item.element;
3126
- if (labelsRef) {
3127
- labelsRef.current[item.index] = item.registration.label !== undefined ? item.registration.label : item.registration.textRef?.current?.textContent ?? item.element.textContent;
3128
- }
3129
1422
  });
3130
- nextIndexRef.current = elementsRef.current.length;
3131
- return nextMap;
3132
- });
3133
- function observe(sortedNodes) {
3134
- mutationObserverRef.current?.disconnect();
3135
- mutationObserverRef.current = null;
3136
-
3137
- // A single item can't reorder.
3138
- if (typeof MutationObserver !== 'function' || sortedNodes.length < 2) {
3139
- return;
1423
+ return newMap;
1424
+ }, [map, mapTick]);
1425
+ useScrollLock.useIsoLayoutEffect(() => {
1426
+ if (typeof MutationObserver !== 'function' || sortedMap.size === 0) {
1427
+ return undefined;
3140
1428
  }
3141
1429
  const mutationObserver = new MutationObserver(entries => {
3142
- // Only verify the order after a move: a node that was removed and later
3143
- // re-added within the same batch. Additions and removals alone can't
3144
- // change the relative order of the remaining items, and items that mount
3145
- // or unmount re-sort through `register`/`unregister`.
3146
- if (!hasMovedNode(entries)) {
3147
- return;
1430
+ const diff = new Set();
1431
+ const updateDiff = node => diff.has(node) ? diff.delete(node) : diff.add(node);
1432
+ entries.forEach(entry => {
1433
+ entry.removedNodes.forEach(updateDiff);
1434
+ entry.addedNodes.forEach(updateDiff);
1435
+ });
1436
+ if (diff.size === 0) {
1437
+ lastTickRef.current += 1;
1438
+ setMapTick(lastTickRef.current);
3148
1439
  }
3149
- let previousConnectedNode = null;
3150
-
3151
- // If any connected node now appears before the previous connected node,
3152
- // wrappers/items moved and the index map needs to be rebuilt.
3153
- for (const node of sortedNodes) {
3154
- if (!node.isConnected) {
3155
- continue;
3156
- }
3157
- if (previousConnectedNode && sortByDocumentPosition(previousConnectedNode, node) > 0) {
3158
- mutationObserver.disconnect();
3159
- scheduleMapUpdate();
3160
- return;
3161
- }
3162
- previousConnectedNode = node;
1440
+ });
1441
+ sortedMap.forEach((_, node) => {
1442
+ if (node.parentElement) {
1443
+ mutationObserver.observe(node.parentElement, {
1444
+ childList: true
1445
+ });
3163
1446
  }
3164
1447
  });
3165
- mutationObserverRef.current = mutationObserver;
3166
-
3167
- // A reorder that changes item indexes must invert at least one adjacent pair
3168
- // from the previous sorted order. Observing each pair's common parent catches
3169
- // both direct item moves and ancestor wrapper moves at the boundary.
3170
- const roots = new Set();
3171
- for (let i = 1; i < sortedNodes.length; i += 1) {
3172
- const root = getCommonAncestor(sortedNodes[i - 1], sortedNodes[i]);
3173
- if (root) {
3174
- roots.add(root);
1448
+ return () => {
1449
+ mutationObserver.disconnect();
1450
+ };
1451
+ }, [sortedMap]);
1452
+ useScrollLock.useIsoLayoutEffect(() => {
1453
+ const shouldUpdateLengths = lastTickRef.current === mapTick;
1454
+ if (shouldUpdateLengths) {
1455
+ if (elementsRef.current.length !== sortedMap.size) {
1456
+ elementsRef.current.length = sortedMap.size;
3175
1457
  }
1458
+ if (labelsRef && labelsRef.current.length !== sortedMap.size) {
1459
+ labelsRef.current.length = sortedMap.size;
1460
+ }
1461
+ nextIndexRef.current = sortedMap.size;
3176
1462
  }
3177
- roots.forEach(root => mutationObserver.observe(root, {
3178
- childList: true
3179
- }));
3180
- }
3181
- const flush = useScrollLock.useStableCallback(() => {
3182
- const [items, automaticNodes] = getCompositeListSnapshot(map);
3183
- const nextMap = syncRefs(items);
3184
- observe(automaticNodes);
3185
- itemsRef.current = items;
3186
- isDirtyRef.current = false;
3187
- listeners.forEach(listener => listener(nextMap));
3188
- onMapChange(nextMap);
3189
- });
1463
+ onMapChange(sortedMap);
1464
+ }, [onMapChange, sortedMap, elementsRef, labelsRef, mapTick]);
3190
1465
  useScrollLock.useIsoLayoutEffect(() => {
3191
- // Re-copy the last committed snapshot when the ref objects change or Strict Mode replays
3192
- // effects without reattaching callback refs.
3193
- if (!isDirtyRef.current) {
3194
- syncRefs(itemsRef.current);
3195
- }
3196
1466
  return () => {
3197
1467
  elementsRef.current = [];
3198
- if (labelsRef) {
3199
- labelsRef.current = [];
3200
- }
3201
1468
  };
3202
- }, [elementsRef, labelsRef, syncRefs]);
3203
- useScrollLock.useIsoLayoutEffect(() => {
3204
- if (isDirtyRef.current) {
3205
- flush();
3206
- }
3207
- });
1469
+ }, [elementsRef]);
3208
1470
  useScrollLock.useIsoLayoutEffect(() => {
3209
1471
  return () => {
3210
- mutationObserverRef.current?.disconnect();
3211
- // React 18 Strict Mode replays effects without replaying callback refs.
3212
- // Mark the retained map dirty so the replay rebuilds refs and observation.
3213
- isDirtyRef.current = true;
1472
+ if (labelsRef) {
1473
+ labelsRef.current = [];
1474
+ }
3214
1475
  };
3215
- }, []);
1476
+ }, [labelsRef]);
3216
1477
  const subscribeMapChange = useScrollLock.useStableCallback(fn => {
3217
1478
  listeners.add(fn);
3218
1479
  return () => {
3219
1480
  listeners.delete(fn);
3220
1481
  };
3221
1482
  });
1483
+ useScrollLock.useIsoLayoutEffect(() => {
1484
+ listeners.forEach(l => l(sortedMap));
1485
+ }, [listeners, sortedMap]);
3222
1486
  const contextValue = React__namespace.useMemo(() => ({
3223
1487
  register,
3224
1488
  unregister,
3225
1489
  subscribeMapChange,
1490
+ elementsRef,
1491
+ labelsRef,
3226
1492
  nextIndexRef
3227
- }), [register, unregister, subscribeMapChange, nextIndexRef]);
1493
+ }), [register, unregister, subscribeMapChange, elementsRef, labelsRef, nextIndexRef]);
3228
1494
  return /*#__PURE__*/jsxRuntime.jsx(CompositeListContext.Provider, {
3229
1495
  value: contextValue,
3230
1496
  children: children
@@ -3236,66 +1502,15 @@ function createMap() {
3236
1502
  function createListeners() {
3237
1503
  return new Set();
3238
1504
  }
3239
- function getCompositeListSnapshot(map) {
3240
- const reservedIndices = new Set();
3241
- const items = [];
3242
- const automaticItems = [];
3243
- map.forEach((registration, node) => {
3244
- if (!node.isConnected) {
3245
- return;
3246
- }
3247
- const index = registration.index;
3248
- const item = {
3249
- index: index ?? -1,
3250
- element: node,
3251
- registration
3252
- };
3253
- if (index === null) {
3254
- automaticItems.push(item);
3255
- } else if (index >= 0) {
3256
- reservedIndices.add(index);
3257
- items.push(item);
3258
- }
3259
- });
3260
- let nextAutomaticIndex = 0;
3261
- automaticItems.sort((a, b) => sortByDocumentPosition(a.element, b.element));
3262
- automaticItems.forEach(item => {
3263
- while (reservedIndices.has(nextAutomaticIndex)) {
3264
- nextAutomaticIndex += 1;
3265
- }
3266
- item.index = nextAutomaticIndex;
3267
- items.push(item);
3268
- nextAutomaticIndex += 1;
3269
- });
3270
- if (reservedIndices.size > 0) {
3271
- items.sort((a, b) => a.index - b.index);
3272
- }
3273
- return [items, automaticItems.map(item => item.element)];
3274
- }
3275
- function getCommonAncestor(firstNode, lastNode) {
3276
- let ancestor = firstNode.parentElement;
3277
-
3278
- // The `parentElement` walk cannot cross shadow boundaries, so the native
3279
- // `contains` is sufficient here.
3280
- while (ancestor && !ancestor.contains(lastNode)) {
3281
- ancestor = ancestor.parentElement;
1505
+ function sortByDocumentPosition(a, b) {
1506
+ const position = a.compareDocumentPosition(b);
1507
+ if (position & Node.DOCUMENT_POSITION_FOLLOWING || position & Node.DOCUMENT_POSITION_CONTAINED_BY) {
1508
+ return -1;
3282
1509
  }
3283
- return ancestor;
3284
- }
3285
- function hasMovedNode(entries) {
3286
- for (const entry of entries) {
3287
- for (let i = 0; i < entry.removedNodes.length; i += 1) {
3288
- if (entry.removedNodes[i].isConnected) {
3289
- return true;
3290
- }
3291
- }
1510
+ if (position & Node.DOCUMENT_POSITION_PRECEDING || position & Node.DOCUMENT_POSITION_CONTAINS) {
1511
+ return 1;
3292
1512
  }
3293
- return false;
3294
- }
3295
- function sortByDocumentPosition(a, b) {
3296
- // `DOCUMENT_POSITION_CONTAINED_BY` is always reported alongside `FOLLOWING`, and `CONTAINS`
3297
- // alongside `PRECEDING`, so testing `FOLLOWING` alone orders siblings and nested items alike.
3298
- return a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
1513
+ return 0;
3299
1514
  }
3300
1515
 
3301
1516
  /**
@@ -3320,17 +1535,17 @@ const baseArrow = options => ({
3320
1535
  element,
3321
1536
  padding = 0,
3322
1537
  offsetParent = 'real'
3323
- } = useScrollLock.evaluate(options, state) || {};
1538
+ } = floatingUi_utils.evaluate(options, state) || {};
3324
1539
  if (element == null) {
3325
1540
  return {};
3326
1541
  }
3327
- const paddingObject = useScrollLock.getPaddingObject(padding);
1542
+ const paddingObject = floatingUi_utils.getPaddingObject(padding);
3328
1543
  const coords = {
3329
1544
  x,
3330
1545
  y
3331
1546
  };
3332
- const axis = useScrollLock.getAlignmentAxis(placement);
3333
- const length = useScrollLock.getAxisLength(axis);
1547
+ const axis = floatingUi_utils.getAlignmentAxis(placement);
1548
+ const length = floatingUi_utils.getAxisLength(axis);
3334
1549
  const arrowDimensions = await platform.getDimensions(element);
3335
1550
  const isYAxis = axis === 'y';
3336
1551
  const minProp = isYAxis ? 'top' : 'left';
@@ -3358,13 +1573,13 @@ const baseArrow = options => ({
3358
1573
  const min = minPadding;
3359
1574
  const max = clientSize - arrowDimensions[length] - maxPadding;
3360
1575
  const center = clientSize / 2 - arrowDimensions[length] / 2 + centerToReference;
3361
- const offset = useScrollLock.clamp(min, center, max);
1576
+ const offset = floatingUi_utils.clamp(min, center, max);
3362
1577
 
3363
1578
  // If the reference is small enough that the arrow's padding causes it to
3364
1579
  // to point to nothing for an aligned placement, adjust the offset of the
3365
1580
  // floating element itself. To ensure `shift()` continues to take action,
3366
1581
  // a single reset is performed when this is true.
3367
- const shouldAddOffset = !middlewareData.arrow && useScrollLock.getAlignment(placement) != null && center !== offset && rects.reference[length] / 2 - (center < min ? minPadding : maxPadding) - arrowDimensions[length] / 2 < 0;
1582
+ const shouldAddOffset = !middlewareData.arrow && floatingUi_utils.getAlignment(placement) != null && center !== offset && rects.reference[length] / 2 - (center < min ? minPadding : maxPadding) - arrowDimensions[length] / 2 < 0;
3368
1583
  // eslint-disable-next-line no-nested-ternary
3369
1584
  const alignmentOffset = shouldAddOffset ? center < min ? center - min : center - max : 0;
3370
1585
  return {
@@ -3392,6 +1607,7 @@ const arrow = (options, deps) => ({
3392
1607
  options: [options, deps]
3393
1608
  });
3394
1609
 
1610
+ const nativeHideFn = floatingUi_reactDom.hide().fn;
3395
1611
  const hide = {
3396
1612
  name: 'hide',
3397
1613
  async fn(state) {
@@ -3402,15 +1618,10 @@ const hide = {
3402
1618
  y
3403
1619
  } = state.rects.reference;
3404
1620
  const anchorHidden = width === 0 && height === 0 && x === 0 && y === 0;
3405
- // Mirrors Floating UI's `hide()` referenceHidden strategy. Floating UI injects
3406
- // `detectOverflow` into the middleware platform before invoking middleware.
3407
- const overflow = await state.platform.detectOverflow(state, {
3408
- elementContext: 'reference'
3409
- });
3410
- const referenceHidden = overflow.top - height >= 0 || overflow.right - width >= 0 || overflow.bottom - height >= 0 || overflow.left - width >= 0;
1621
+ const nativeHideResult = await nativeHideFn(state);
3411
1622
  return {
3412
1623
  data: {
3413
- referenceHidden: referenceHidden || anchorHidden
1624
+ referenceHidden: nativeHideResult.data?.referenceHidden || anchorHidden
3414
1625
  }
3415
1626
  };
3416
1627
  }
@@ -3420,13 +1631,75 @@ const DEFAULT_SIDES = {
3420
1631
  sideX: 'left',
3421
1632
  sideY: 'top'
3422
1633
  };
1634
+ const adaptiveOrigin = {
1635
+ name: 'adaptiveOrigin',
1636
+ async fn(state) {
1637
+ const {
1638
+ x: rawX,
1639
+ y: rawY,
1640
+ rects: {
1641
+ floating: floatRect
1642
+ },
1643
+ elements: {
1644
+ floating
1645
+ },
1646
+ platform,
1647
+ strategy,
1648
+ placement
1649
+ } = state;
1650
+ const win = floatingUi_utils.getWindow(floating);
1651
+ const styles = win.getComputedStyle(floating);
1652
+ const hasTransition = styles.transitionDuration !== '0s' && styles.transitionDuration !== '';
1653
+ if (!hasTransition) {
1654
+ return {
1655
+ x: rawX,
1656
+ y: rawY,
1657
+ data: DEFAULT_SIDES
1658
+ };
1659
+ }
1660
+ const offsetParent = await platform.getOffsetParent?.(floating);
1661
+ let offsetDimensions = {
1662
+ width: 0,
1663
+ height: 0
1664
+ };
3423
1665
 
3424
- // Self-contained stand-in for Floating UI's `Middleware` type. Referencing the real type in
3425
- // store state makes `tsc` declaration emit reference `Platform`/`detectOverflow` from
3426
- // `@floating-ui/core` internals, which fails as non-portable (TS2883) in consuming builds.
1666
+ // For fixed strategy, prefer visualViewport if available
1667
+ if (strategy === 'fixed' && win?.visualViewport) {
1668
+ offsetDimensions = {
1669
+ width: win.visualViewport.width,
1670
+ height: win.visualViewport.height
1671
+ };
1672
+ } else if (offsetParent === win) {
1673
+ const doc = useScrollLock.ownerDocument(floating);
1674
+ offsetDimensions = {
1675
+ width: doc.documentElement.clientWidth,
1676
+ height: doc.documentElement.clientHeight
1677
+ };
1678
+ } else if (await platform.isElement?.(offsetParent)) {
1679
+ offsetDimensions = await platform.getDimensions(offsetParent);
1680
+ }
1681
+ const currentSide = floatingUi_utils.getSide(placement);
1682
+ let x = rawX;
1683
+ let y = rawY;
1684
+ if (currentSide === 'left') {
1685
+ x = offsetDimensions.width - (rawX + floatRect.width);
1686
+ }
1687
+ if (currentSide === 'top') {
1688
+ y = offsetDimensions.height - (rawY + floatRect.height);
1689
+ }
1690
+ const sideX = currentSide === 'left' ? 'right' : DEFAULT_SIDES.sideX;
1691
+ const sideY = currentSide === 'top' ? 'bottom' : DEFAULT_SIDES.sideY;
1692
+ return {
1693
+ x,
1694
+ y,
1695
+ data: {
1696
+ sideX,
1697
+ sideY
1698
+ }
1699
+ };
1700
+ }
1701
+ };
3427
1702
 
3428
- const AVAILABLE_WIDTH_VAR = '--available-width';
3429
- const AVAILABLE_HEIGHT_VAR = '--available-height';
3430
1703
  function getLogicalSide(sideParam, renderedSide, isRtl) {
3431
1704
  const isLogicalSideParam = sideParam === 'inline-start' || sideParam === 'inline-end';
3432
1705
  const logicalRight = isRtl ? 'inline-start' : 'inline-end';
@@ -3444,8 +1717,8 @@ function getOffsetData(state, sideParam, isRtl) {
3444
1717
  placement
3445
1718
  } = state;
3446
1719
  const data = {
3447
- side: getLogicalSide(sideParam, useScrollLock.getSide(placement), isRtl),
3448
- align: useScrollLock.getAlignment(placement) || 'center',
1720
+ side: getLogicalSide(sideParam, floatingUi_utils.getSide(placement), isRtl),
1721
+ align: floatingUi_utils.getAlignment(placement) || 'center',
3449
1722
  anchor: {
3450
1723
  width: rects.reference.width,
3451
1724
  height: rects.reference.height
@@ -3462,9 +1735,6 @@ function getOffsetData(state, sideParam, isRtl) {
3462
1735
  * `useFloating` hook.
3463
1736
  */
3464
1737
  function useAnchorPositioning(params) {
3465
- return useAnchorPositioningWithHook(params, useBaseUIFloating);
3466
- }
3467
- function useAnchorPositioningWithHook(params, useFloatingHook) {
3468
1738
  const {
3469
1739
  // Public parameters
3470
1740
  anchor,
@@ -3484,7 +1754,7 @@ function useAnchorPositioningWithHook(params, useFloatingHook) {
3484
1754
  floatingRootContext,
3485
1755
  mounted,
3486
1756
  collisionAvoidance,
3487
- shift: shift$1,
1757
+ shiftCrossAxis = false,
3488
1758
  nodeId,
3489
1759
  adaptiveOrigin,
3490
1760
  lazyFlip = false,
@@ -3497,8 +1767,6 @@ function useAnchorPositioningWithHook(params, useFloatingHook) {
3497
1767
  const collisionAvoidanceSide = collisionAvoidance.side || 'flip';
3498
1768
  const collisionAvoidanceAlign = collisionAvoidance.align || 'flip';
3499
1769
  const collisionAvoidanceFallbackAxisSide = collisionAvoidance.fallbackAxisSide || 'end';
3500
- const shiftCrossAxis = shift$1?.crossAxis ?? false;
3501
- const shiftRootBoundary = shift$1?.rootBoundary;
3502
1770
  const anchorFn = typeof anchor === 'function' ? anchor : undefined;
3503
1771
  const anchorFnCallback = useScrollLock.useStableCallback(anchorFn);
3504
1772
  const anchorDep = anchorFn ? anchorFnCallback : anchor;
@@ -3516,32 +1784,30 @@ function useAnchorPositioningWithHook(params, useFloatingHook) {
3516
1784
  }[sideParam];
3517
1785
  const placement = align === 'center' ? side : `${side}-${align}`;
3518
1786
  let collisionPadding = collisionPaddingParam;
3519
- if (typeof collisionPadding === 'number') {
3520
- collisionPadding = {
3521
- top: collisionPadding,
3522
- right: collisionPadding,
3523
- bottom: collisionPadding,
3524
- left: collisionPadding
3525
- };
3526
- } else if (collisionPadding) {
3527
- collisionPadding = {
3528
- top: collisionPadding.top || 0,
3529
- right: collisionPadding.right || 0,
3530
- bottom: collisionPadding.bottom || 0,
3531
- left: collisionPadding.left || 0
3532
- };
3533
- }
3534
1787
 
3535
1788
  // Create a bias to the preferred side.
3536
1789
  // On iOS, when the mobile software keyboard opens, the input is exactly centered
3537
1790
  // in the viewport, but this can cause it to flip to the top undesirably.
3538
- // The bias is only applied to `flip()` so it doesn't shift the resting position
3539
- // computed by `shift()` and `size()` away from the requested `collisionPadding`.
3540
1791
  const bias = 1;
3541
1792
  const biasTop = sideParam === 'bottom' ? bias : 0;
3542
1793
  const biasBottom = sideParam === 'top' ? bias : 0;
3543
1794
  const biasLeft = sideParam === 'right' ? bias : 0;
3544
1795
  const biasRight = sideParam === 'left' ? bias : 0;
1796
+ if (typeof collisionPadding === 'number') {
1797
+ collisionPadding = {
1798
+ top: collisionPadding + biasTop,
1799
+ right: collisionPadding + biasRight,
1800
+ bottom: collisionPadding + biasBottom,
1801
+ left: collisionPadding + biasLeft
1802
+ };
1803
+ } else if (collisionPadding) {
1804
+ collisionPadding = {
1805
+ top: (collisionPadding.top || 0) + biasTop,
1806
+ right: (collisionPadding.right || 0) + biasRight,
1807
+ bottom: (collisionPadding.bottom || 0) + biasBottom,
1808
+ left: (collisionPadding.left || 0) + biasLeft
1809
+ };
1810
+ }
3545
1811
  const commonCollisionProps = {
3546
1812
  boundary: collisionBoundary === 'clipping-ancestors' ? 'clippingAncestors' : collisionBoundary,
3547
1813
  padding: collisionPadding
@@ -3561,7 +1827,7 @@ function useAnchorPositioningWithHook(params, useFloatingHook) {
3561
1827
  if (inlineMiddleware) {
3562
1828
  middleware.push(inlineMiddleware);
3563
1829
  }
3564
- middleware.push(offset(state => {
1830
+ middleware.push(floatingUi_reactDom.offset(state => {
3565
1831
  const data = getOffsetData(state, sideParam, isRtl);
3566
1832
  const sideAxis = typeof sideOffsetRef.current === 'function' ? sideOffsetRef.current(data) : sideOffsetRef.current;
3567
1833
  const alignAxis = typeof alignOffsetRef.current === 'function' ? alignOffsetRef.current(data) : alignOffsetRef.current;
@@ -3573,42 +1839,51 @@ function useAnchorPositioningWithHook(params, useFloatingHook) {
3573
1839
  }, [sideOffsetDep, alignOffsetDep, isRtl, sideParam]));
3574
1840
  const shiftDisabled = collisionAvoidanceAlign === 'none' && collisionAvoidanceSide !== 'shift';
3575
1841
  const crossAxisShiftEnabled = !shiftDisabled && (sticky || shiftCrossAxis || collisionAvoidanceSide === 'shift');
3576
- const flipMiddleware = collisionAvoidanceSide === 'none' ? null : flip({
1842
+ const flipMiddleware = collisionAvoidanceSide === 'none' ? null : floatingUi_reactDom.flip({
3577
1843
  ...commonCollisionProps,
3578
1844
  // Ensure the popup flips if it's been limited by its --available-height and it resizes.
3579
1845
  // Since the size() padding is smaller than the flip() padding, flip() will take precedence.
3580
1846
  padding: {
3581
- top: collisionPadding.top + bias + biasTop,
3582
- right: collisionPadding.right + bias + biasRight,
3583
- bottom: collisionPadding.bottom + bias + biasBottom,
3584
- left: collisionPadding.left + bias + biasLeft
1847
+ top: collisionPadding.top + bias,
1848
+ right: collisionPadding.right + bias,
1849
+ bottom: collisionPadding.bottom + bias,
1850
+ left: collisionPadding.left + bias
3585
1851
  },
3586
1852
  mainAxis: !shiftCrossAxis && collisionAvoidanceSide === 'flip',
3587
1853
  crossAxis: collisionAvoidanceAlign === 'flip' ? 'alignment' : false,
3588
1854
  fallbackAxisSideDirection: collisionAvoidanceFallbackAxisSide
3589
1855
  });
3590
- const shiftMiddleware = shiftDisabled ? null : shift({
3591
- ...commonCollisionProps,
3592
- // Use the Layout Viewport to avoid shifting around when pinch-zooming.
3593
- rootBoundary: shiftRootBoundary,
3594
- mainAxis: collisionAvoidanceAlign !== 'none',
3595
- crossAxis: crossAxisShiftEnabled,
3596
- limiter: sticky || shiftCrossAxis ? undefined : limitShift(limitData => {
3597
- if (!arrowRef.current) {
3598
- return {};
3599
- }
3600
- const {
3601
- width,
3602
- height
3603
- } = arrowRef.current.getBoundingClientRect();
3604
- const sideAxis = useScrollLock.getSideAxis(useScrollLock.getSide(limitData.placement));
3605
- const arrowSize = sideAxis === 'y' ? width : height;
3606
- const offsetAmount = sideAxis === 'y' ? collisionPadding.left + collisionPadding.right : collisionPadding.top + collisionPadding.bottom;
3607
- return {
3608
- offset: arrowSize / 2 + offsetAmount / 2
3609
- };
3610
- })
3611
- }, [commonCollisionProps, sticky, shiftCrossAxis, shiftRootBoundary, collisionPadding, collisionAvoidanceAlign]);
1856
+ const shiftMiddleware = shiftDisabled ? null : floatingUi_reactDom.shift(data => {
1857
+ const html = useScrollLock.ownerDocument(data.elements.floating).documentElement;
1858
+ return {
1859
+ ...commonCollisionProps,
1860
+ // Use the Layout Viewport to avoid shifting around when pinch-zooming
1861
+ // for context menus.
1862
+ rootBoundary: shiftCrossAxis ? {
1863
+ x: 0,
1864
+ y: 0,
1865
+ width: html.clientWidth,
1866
+ height: html.clientHeight
1867
+ } : undefined,
1868
+ mainAxis: collisionAvoidanceAlign !== 'none',
1869
+ crossAxis: crossAxisShiftEnabled,
1870
+ limiter: sticky || shiftCrossAxis ? undefined : floatingUi_reactDom.limitShift(limitData => {
1871
+ if (!arrowRef.current) {
1872
+ return {};
1873
+ }
1874
+ const {
1875
+ width,
1876
+ height
1877
+ } = arrowRef.current.getBoundingClientRect();
1878
+ const sideAxis = floatingUi_utils.getSideAxis(floatingUi_utils.getSide(limitData.placement));
1879
+ const arrowSize = sideAxis === 'y' ? width : height;
1880
+ const offsetAmount = sideAxis === 'y' ? collisionPadding.left + collisionPadding.right : collisionPadding.top + collisionPadding.bottom;
1881
+ return {
1882
+ offset: arrowSize / 2 + offsetAmount / 2
1883
+ };
1884
+ })
1885
+ };
1886
+ }, [commonCollisionProps, sticky, shiftCrossAxis, collisionPadding, collisionAvoidanceAlign]);
3612
1887
 
3613
1888
  // https://floating-ui.com/docs/flip#combining-with-shift
3614
1889
  if (collisionAvoidanceSide === 'shift' || collisionAvoidanceAlign === 'shift' || align === 'center') {
@@ -3616,7 +1891,7 @@ function useAnchorPositioningWithHook(params, useFloatingHook) {
3616
1891
  } else {
3617
1892
  middleware.push(flipMiddleware, shiftMiddleware);
3618
1893
  }
3619
- middleware.push(size({
1894
+ middleware.push(floatingUi_reactDom.size({
3620
1895
  ...commonCollisionProps,
3621
1896
  apply({
3622
1897
  elements: {
@@ -3630,11 +1905,11 @@ function useAnchorPositioningWithHook(params, useFloatingHook) {
3630
1905
  return;
3631
1906
  }
3632
1907
  const floatingStyle = floating.style;
3633
- floatingStyle.setProperty(AVAILABLE_WIDTH_VAR, `${availableWidth}px`);
3634
- floatingStyle.setProperty(AVAILABLE_HEIGHT_VAR, `${availableHeight}px`);
1908
+ floatingStyle.setProperty('--available-width', `${availableWidth}px`);
1909
+ floatingStyle.setProperty('--available-height', `${availableHeight}px`);
3635
1910
 
3636
1911
  // Snap anchor dimensions to device pixels to ensure the popup's visual width matches the anchor's one.
3637
- const dpr = useScrollLock.getWindow(floating).devicePixelRatio || 1;
1912
+ const dpr = floatingUi_utils.getWindow(floating).devicePixelRatio || 1;
3638
1913
  const {
3639
1914
  x,
3640
1915
  y,
@@ -3662,8 +1937,8 @@ function useAnchorPositioningWithHook(params, useFloatingHook) {
3662
1937
  rects,
3663
1938
  y
3664
1939
  } = state;
3665
- const currentRenderedSide = useScrollLock.getSide(renderedPlacement);
3666
- const currentRenderedAxis = useScrollLock.getSideAxis(currentRenderedSide);
1940
+ const currentRenderedSide = floatingUi_utils.getSide(renderedPlacement);
1941
+ const currentRenderedAxis = floatingUi_utils.getSideAxis(currentRenderedSide);
3667
1942
  const arrowEl = arrowRef.current;
3668
1943
  const arrowX = middlewareData.arrow?.x || 0;
3669
1944
  const arrowY = middlewareData.arrow?.y || 0;
@@ -3713,13 +1988,13 @@ function useAnchorPositioningWithHook(params, useFloatingHook) {
3713
1988
  context,
3714
1989
  isPositioned,
3715
1990
  floatingStyles: originalFloatingStyles
3716
- } = useFloatingHook({
1991
+ } = useFloating({
3717
1992
  rootContext: floatingRootContext,
3718
1993
  open: keepMounted ? mounted : undefined,
3719
1994
  placement,
3720
1995
  middleware,
3721
1996
  strategy: positionMethod,
3722
- whileElementsMounted: keepMounted ? undefined : (...args) => autoUpdate(...args, autoUpdateOptions),
1997
+ whileElementsMounted: keepMounted ? undefined : (...args) => floatingUi_reactDom.autoUpdate(...args, autoUpdateOptions),
3723
1998
  nodeId,
3724
1999
  externalTree
3725
2000
  });
@@ -3732,41 +2007,14 @@ function useAnchorPositioningWithHook(params, useFloatingHook) {
3732
2007
  // This ensures the popup is inside the viewport initially before it gets positioned.
3733
2008
  const resolvedPosition = isPositioned ? positionMethod : 'fixed';
3734
2009
  const floatingStyles = React__namespace.useMemo(() => {
3735
- let base;
3736
- if (!isPositioned) {
3737
- // Until a position for the current open is computed, ignore any coordinates retained from a
3738
- // previous open (or from a pass that measured the hidden popup as 0x0). Rendering the
3739
- // full-size popup at such stale coordinates can overflow the layout viewport, which makes
3740
- // mobile Chrome zoom the page out and reflow everything the popup is anchored to.
3741
- base = {
3742
- position: resolvedPosition,
3743
- top: 0,
3744
- left: 0
3745
- };
3746
- } else if (adaptiveOrigin) {
3747
- base = {
3748
- position: resolvedPosition,
3749
- [sideX]: x,
3750
- [sideY]: y
3751
- };
3752
- } else {
3753
- base = {
3754
- ...originalFloatingStyles,
3755
- position: resolvedPosition
3756
- };
3757
- }
3758
-
3759
- // Seed the available size vars so consumer `max-height: min(x, var(--available-height))` rules
3760
- // resolve to a valid length on the first positioning pass, before `size()` writes the real
3761
- // values. Without a fallback the unresolved `var()` invalidates the whole declaration, so the
3762
- // popup is measured unconstrained while `flip()` picks its side, against the full content
3763
- // height rather than the capped one. Seeded unconditionally (not only while `!isPositioned`):
3764
- // the keys must stay present with a constant value so React's per-property style diff never
3765
- // rewrites them after mount, preserving the px values `size()` sets imperatively. Moving them
3766
- // into the `!isPositioned` branch makes React remove them once positioned, wiping `size()`'s
3767
- // values and leaving the popup unconstrained.
3768
- base[AVAILABLE_WIDTH_VAR] = '100vw';
3769
- base[AVAILABLE_HEIGHT_VAR] = '100vh';
2010
+ const base = adaptiveOrigin ? {
2011
+ position: resolvedPosition,
2012
+ [sideX]: x,
2013
+ [sideY]: y
2014
+ } : {
2015
+ position: resolvedPosition,
2016
+ ...originalFloatingStyles
2017
+ };
3770
2018
  if (!isPositioned) {
3771
2019
  base.opacity = 0;
3772
2020
  }
@@ -3804,23 +2052,23 @@ function useAnchorPositioningWithHook(params, useFloatingHook) {
3804
2052
  }, [mounted, refs, anchorDep, anchorValueRef]);
3805
2053
  React__namespace.useEffect(() => {
3806
2054
  if (keepMounted && mounted && elements.reference && elements.floating) {
3807
- return autoUpdate(elements.reference, elements.floating, update, autoUpdateOptions);
2055
+ return floatingUi_reactDom.autoUpdate(elements.reference, elements.floating, update, autoUpdateOptions);
3808
2056
  }
3809
2057
  return undefined;
3810
2058
  }, [keepMounted, mounted, elements, update, autoUpdateOptions]);
3811
- const renderedSide = useScrollLock.getSide(renderedPlacement);
2059
+ const renderedSide = floatingUi_utils.getSide(renderedPlacement);
3812
2060
  const logicalRenderedSide = getLogicalSide(sideParam, renderedSide, isRtl);
3813
- const renderedAlign = useScrollLock.getAlignment(renderedPlacement) || 'center';
2061
+ const renderedAlign = floatingUi_utils.getAlignment(renderedPlacement) || 'center';
3814
2062
  const anchorHidden = Boolean(middlewareData.hide?.referenceHidden);
3815
2063
 
3816
2064
  // Locks the flip (makes it "sticky") so it doesn't prefer a given placement
3817
2065
  // and flips back lazily, not eagerly. Ideal for filtered lists that change
3818
2066
  // the size of the popup dynamically to avoid unwanted flipping when typing.
3819
2067
  useScrollLock.useIsoLayoutEffect(() => {
3820
- if (lazyFlip && mounted && isPositioned && renderedSide !== side) {
2068
+ if (lazyFlip && mounted && isPositioned) {
3821
2069
  setMountSide(renderedSide);
3822
2070
  }
3823
- }, [lazyFlip, mounted, isPositioned, renderedSide, side]);
2071
+ }, [lazyFlip, mounted, isPositioned, renderedSide]);
3824
2072
  const arrowStyles = React__namespace.useMemo(() => ({
3825
2073
  position: 'absolute',
3826
2074
  top: middlewareData.arrow?.y,
@@ -3905,57 +2153,64 @@ function useAnchoredPopupScrollLock(enabled, touchOpen, positionerElement, refer
3905
2153
  useScrollLock.useScrollLock(enabled && (!touchOpen || touchOpenShouldLockScroll), referenceElement);
3906
2154
  }
3907
2155
 
2156
+ let IndexGuessBehavior = /*#__PURE__*/function (IndexGuessBehavior) {
2157
+ IndexGuessBehavior[IndexGuessBehavior["None"] = 0] = "None";
2158
+ IndexGuessBehavior[IndexGuessBehavior["GuessFromOrder"] = 1] = "GuessFromOrder";
2159
+ return IndexGuessBehavior;
2160
+ }({});
2161
+
3908
2162
  /**
3909
2163
  * Used to register a list item and its index (DOM position) in the `CompositeList`.
3910
2164
  */
3911
2165
  function useCompositeListItem(params = {}) {
3912
2166
  const {
3913
- guess,
3914
2167
  label,
3915
2168
  metadata,
3916
2169
  textRef,
2170
+ indexGuessBehavior,
3917
2171
  index: externalIndex
3918
2172
  } = params;
3919
2173
  const {
3920
2174
  register,
3921
2175
  unregister,
3922
2176
  subscribeMapChange,
2177
+ elementsRef,
2178
+ labelsRef,
3923
2179
  nextIndexRef
3924
2180
  } = useCompositeListContext();
3925
-
3926
- // Guess the index from the render order. This avoids a re-render after mount for
3927
- // flat lists rendered in DOM order; when the guess is wrong (grouped or out-of-order
3928
- // rendering), the commit flush corrects it before paint.
3929
2181
  const indexRef = React__namespace.useRef(-1);
3930
- const [internalIndex, setInternalIndex] = React__namespace.useState(externalIndex == null && guess ? () => {
2182
+ const [index, setIndex] = React__namespace.useState(externalIndex ?? (indexGuessBehavior === IndexGuessBehavior.GuessFromOrder ? () => {
3931
2183
  if (indexRef.current === -1) {
3932
2184
  const newIndex = nextIndexRef.current;
3933
2185
  nextIndexRef.current += 1;
3934
2186
  indexRef.current = newIndex;
3935
2187
  }
3936
2188
  return indexRef.current;
3937
- } : -1);
3938
- const index = externalIndex ?? internalIndex;
2189
+ } : -1));
3939
2190
  const componentRef = React__namespace.useRef(null);
3940
-
3941
- // Deliberately identity-sensitive: nested items sharing one DOM node rely on ref attachment
3942
- // order to decide which registration wins, and republishing from an effect instead would let
3943
- // an inner item's later update silently take ownership from the outer one.
3944
2191
  const ref = React__namespace.useCallback(node => {
3945
- const previousNode = componentRef.current;
3946
- if (previousNode) {
3947
- unregister(previousNode);
3948
- }
3949
2192
  componentRef.current = node;
2193
+ if (index !== -1 && node !== null) {
2194
+ elementsRef.current[index] = node;
2195
+ if (labelsRef) {
2196
+ const isLabelDefined = label !== undefined;
2197
+ labelsRef.current[index] = isLabelDefined ? label : textRef?.current?.textContent ?? node.textContent;
2198
+ }
2199
+ }
2200
+ }, [index, elementsRef, labelsRef, label, textRef]);
2201
+ useScrollLock.useIsoLayoutEffect(() => {
2202
+ if (externalIndex != null) {
2203
+ return undefined;
2204
+ }
2205
+ const node = componentRef.current;
3950
2206
  if (node) {
3951
- register(node, {
3952
- metadata: metadata ?? null,
3953
- index: externalIndex ?? null,
3954
- label,
3955
- textRef
3956
- });
2207
+ register(node, metadata);
2208
+ return () => {
2209
+ unregister(node);
2210
+ };
3957
2211
  }
3958
- }, [externalIndex, register, unregister, metadata, label, textRef]);
2212
+ return undefined;
2213
+ }, [externalIndex, register, unregister, metadata]);
3959
2214
  useScrollLock.useIsoLayoutEffect(() => {
3960
2215
  if (externalIndex != null) {
3961
2216
  return undefined;
@@ -3963,10 +2218,10 @@ function useCompositeListItem(params = {}) {
3963
2218
  return subscribeMapChange(map => {
3964
2219
  const i = componentRef.current ? map.get(componentRef.current)?.index : null;
3965
2220
  if (i != null) {
3966
- setInternalIndex(i);
2221
+ setIndex(i);
3967
2222
  }
3968
2223
  });
3969
- }, [externalIndex, subscribeMapChange]);
2224
+ }, [externalIndex, subscribeMapChange, setIndex]);
3970
2225
  return {
3971
2226
  ref,
3972
2227
  index
@@ -3976,22 +2231,21 @@ function useCompositeListItem(params = {}) {
3976
2231
  exports.CompositeList = CompositeList;
3977
2232
  exports.DEFAULT_FIELD_ROOT_CONTEXT = DEFAULT_FIELD_ROOT_CONTEXT;
3978
2233
  exports.DEFAULT_FIELD_STATE_ATTRIBUTES = DEFAULT_FIELD_STATE_ATTRIBUTES;
3979
- exports.DEFAULT_SIDES = DEFAULT_SIDES;
3980
2234
  exports.DEFAULT_VALIDITY_STATE = DEFAULT_VALIDITY_STATE;
3981
2235
  exports.FieldRootContext = FieldRootContext;
2236
+ exports.IndexGuessBehavior = IndexGuessBehavior;
3982
2237
  exports.LabelableContext = LabelableContext;
2238
+ exports.adaptiveOrigin = adaptiveOrigin;
3983
2239
  exports.areArraysEqual = areArraysEqual;
3984
2240
  exports.compareItemEquality = compareItemEquality;
3985
2241
  exports.defaultItemEquality = defaultItemEquality;
3986
2242
  exports.fieldValidityMapping = fieldValidityMapping;
3987
2243
  exports.findItemIndex = findItemIndex;
3988
- exports.findSelectionIndex = findSelectionIndex;
3989
2244
  exports.getDefaultLabelId = getDefaultLabelId;
3990
2245
  exports.getDisabledMountTransitionStyles = getDisabledMountTransitionStyles;
2246
+ exports.getPseudoElementBounds = getPseudoElementBounds;
3991
2247
  exports.hasNullItemLabel = hasNullItemLabel;
3992
2248
  exports.isGroupedItems = isGroupedItems;
3993
- exports.isMouseWithinBounds = isMouseWithinBounds;
3994
- exports.platform = platform;
3995
2249
  exports.removeItem = removeItem;
3996
2250
  exports.resolveAriaLabelledBy = resolveAriaLabelledBy;
3997
2251
  exports.resolveMultipleLabels = resolveMultipleLabels;
@@ -4008,7 +2262,6 @@ exports.useFormContext = useFormContext;
4008
2262
  exports.useLabelableContext = useLabelableContext;
4009
2263
  exports.useLabelableId = useLabelableId;
4010
2264
  exports.useListNavigation = useListNavigation;
4011
- exports.useOnFirstRender = useOnFirstRender;
4012
2265
  exports.usePositioner = usePositioner;
4013
2266
  exports.useRegisterFieldControl = useRegisterFieldControl;
4014
2267
  exports.useTypeahead = useTypeahead;