@jobber/components 9.3.0 → 9.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/dist/Autocomplete/index.cjs +0 -1
  2. package/dist/Autocomplete/index.mjs +0 -1
  3. package/dist/Card/index.cjs +7 -7
  4. package/dist/Card/index.mjs +7 -7
  5. package/dist/Chip/index.cjs +0 -1
  6. package/dist/Chip/index.mjs +0 -1
  7. package/dist/Chips/InternalChipDismissible/hooks/index.cjs +0 -1
  8. package/dist/Chips/InternalChipDismissible/hooks/index.mjs +0 -1
  9. package/dist/Chips/InternalChipDismissible/index.cjs +0 -1
  10. package/dist/Chips/InternalChipDismissible/index.mjs +0 -1
  11. package/dist/Chips/index.cjs +0 -1
  12. package/dist/Chips/index.mjs +0 -1
  13. package/dist/ComboboxChipRemove-cjs.js +181 -184
  14. package/dist/ComboboxChipRemove-es.js +4 -7
  15. package/dist/ConfirmationModal/index.cjs +0 -1
  16. package/dist/ConfirmationModal/index.mjs +0 -1
  17. package/dist/DataDump/DataDump.d.ts +1 -1
  18. package/dist/DataDump/DataDump.messages.d.ts +6 -0
  19. package/dist/DataDump/index.cjs +9 -9
  20. package/dist/DataDump/index.mjs +9 -9
  21. package/dist/DataDump-cjs.js +11 -1
  22. package/dist/DataDump-es.js +11 -1
  23. package/dist/DataList/components/DataListActions/index.cjs +0 -1
  24. package/dist/DataList/components/DataListActions/index.mjs +0 -1
  25. package/dist/DataList/components/DataListBulkActions/index.cjs +0 -1
  26. package/dist/DataList/components/DataListBulkActions/index.mjs +0 -1
  27. package/dist/DataList/components/DataListFilters/components/DataListSort/index.cjs +0 -1
  28. package/dist/DataList/components/DataListFilters/components/DataListSort/index.mjs +0 -1
  29. package/dist/DataList/components/DataListFilters/index.cjs +0 -1
  30. package/dist/DataList/components/DataListFilters/index.mjs +0 -1
  31. package/dist/DataList/components/DataListHeader/index.cjs +0 -1
  32. package/dist/DataList/components/DataListHeader/index.mjs +0 -1
  33. package/dist/DataList/components/DataListItem/index.cjs +0 -1
  34. package/dist/DataList/components/DataListItem/index.mjs +0 -1
  35. package/dist/DataList/components/DataListItemActions/index.cjs +0 -1
  36. package/dist/DataList/components/DataListItemActions/index.mjs +0 -1
  37. package/dist/DataList/components/DataListItemActionsOverflow/index.cjs +0 -1
  38. package/dist/DataList/components/DataListItemActionsOverflow/index.mjs +0 -1
  39. package/dist/DataList/components/DataListItems/index.cjs +0 -1
  40. package/dist/DataList/components/DataListItems/index.mjs +0 -1
  41. package/dist/DataList/components/DataListLayout/index.cjs +0 -1
  42. package/dist/DataList/components/DataListLayout/index.mjs +0 -1
  43. package/dist/DataList/components/DataListLayoutActions/index.cjs +0 -1
  44. package/dist/DataList/components/DataListLayoutActions/index.mjs +0 -1
  45. package/dist/DataList/index.cjs +0 -1
  46. package/dist/DataList/index.mjs +0 -1
  47. package/dist/DataTable/DataTable.messages.d.ts +22 -0
  48. package/dist/DataTable/index.cjs +2 -2
  49. package/dist/DataTable/index.mjs +2 -2
  50. package/dist/DataTable-cjs.js +34 -5
  51. package/dist/DataTable-es.js +34 -5
  52. package/dist/DatePicker/index.cjs +0 -2
  53. package/dist/DatePicker/index.mjs +0 -2
  54. package/dist/DatePicker-cjs.js +19 -18
  55. package/dist/DatePicker-es.js +2 -1
  56. package/dist/Dialog/index.cjs +11 -6
  57. package/dist/Dialog/index.mjs +11 -6
  58. package/dist/DrawerDescription-cjs.js +7 -8
  59. package/dist/DrawerDescription-es.js +1 -2
  60. package/dist/DrawerTitle-cjs.js +4 -4
  61. package/dist/DrawerTitle-es.js +1 -1
  62. package/dist/FeatureSwitch/FeatureSwitch.messages.d.ts +10 -0
  63. package/dist/FeatureSwitch/index.cjs +2 -0
  64. package/dist/FeatureSwitch/index.mjs +2 -0
  65. package/dist/FeatureSwitch-cjs.js +15 -2
  66. package/dist/FeatureSwitch-es.js +15 -2
  67. package/dist/FieldDescription-cjs.js +49 -49
  68. package/dist/FieldDescription-es.js +2 -2
  69. package/dist/FilterPicker/components/FilterPickerActivator/index.cjs +0 -1
  70. package/dist/FilterPicker/components/FilterPickerActivator/index.mjs +0 -1
  71. package/dist/FilterPicker/components/FilterPickerContent/index.cjs +0 -1
  72. package/dist/FilterPicker/components/FilterPickerContent/index.mjs +0 -1
  73. package/dist/FilterPicker/components/FilterPickerTrigger/index.cjs +0 -1
  74. package/dist/FilterPicker/components/FilterPickerTrigger/index.mjs +0 -1
  75. package/dist/FilterPicker/index.cjs +0 -1
  76. package/dist/FilterPicker/index.mjs +0 -1
  77. package/dist/FormatFile/FormatFile.messages.d.ts +18 -0
  78. package/dist/FormatFile/index.cjs +2 -3
  79. package/dist/FormatFile/index.mjs +2 -3
  80. package/dist/FormatFile-cjs.js +24 -2
  81. package/dist/FormatFile-es.js +24 -2
  82. package/dist/Gallery/index.cjs +0 -1
  83. package/dist/Gallery/index.mjs +0 -1
  84. package/dist/HelperText-cjs.js +3 -2
  85. package/dist/HelperText-es.js +3 -2
  86. package/dist/InputDate/index.cjs +0 -2
  87. package/dist/InputDate/index.mjs +0 -2
  88. package/dist/InputNumber/InputNumber.d.ts +75 -5
  89. package/dist/InputNumber/index.cjs +27 -3
  90. package/dist/InputNumber/index.d.ts +2 -2
  91. package/dist/InputNumber/index.mjs +27 -3
  92. package/dist/{primitives/InputNumberExperimental → InputNumber}/types.d.ts +48 -35
  93. package/dist/InputNumber-cjs.js +267 -4986
  94. package/dist/InputNumber-es.js +268 -4987
  95. package/dist/LightBox/index.cjs +0 -1
  96. package/dist/LightBox/index.mjs +0 -1
  97. package/dist/Menu/index.cjs +7 -7
  98. package/dist/Menu/index.mjs +7 -7
  99. package/dist/Menu-cjs.js +5 -1
  100. package/dist/Menu-es.js +5 -2
  101. package/dist/MenuSubmenuTrigger-cjs.js +142 -143
  102. package/dist/MenuSubmenuTrigger-es.js +5 -6
  103. package/dist/Modal/index.cjs +0 -1
  104. package/dist/Modal/index.mjs +0 -1
  105. package/dist/NumberFieldInput-cjs.js +63 -63
  106. package/dist/NumberFieldInput-es.js +5 -5
  107. package/dist/Page/index.cjs +18 -19
  108. package/dist/Page/index.mjs +18 -19
  109. package/dist/Page-cjs.js +6 -3
  110. package/dist/Page-es.js +6 -3
  111. package/dist/Popover/index.cjs +0 -1
  112. package/dist/Popover/index.mjs +0 -1
  113. package/dist/ProgressBar/ProgressBar.messages.d.ts +6 -0
  114. package/dist/ProgressBar/index.cjs +2 -0
  115. package/dist/ProgressBar/index.mjs +2 -0
  116. package/dist/ProgressBar-cjs.js +13 -1
  117. package/dist/ProgressBar-es.js +13 -1
  118. package/dist/ScrollAreaViewport-cjs.js +119 -121
  119. package/dist/ScrollAreaViewport-es.js +3 -5
  120. package/dist/Select/index.cjs +3 -9
  121. package/dist/Select/index.mjs +3 -9
  122. package/dist/SelectGroupLabel-cjs.js +117 -107
  123. package/dist/SelectGroupLabel-es.js +20 -12
  124. package/dist/Toast/Toast.messages.d.ts +6 -0
  125. package/dist/Toast/index.cjs +3 -1
  126. package/dist/Toast/index.mjs +3 -1
  127. package/dist/Toast/showToast.d.ts +12 -1
  128. package/dist/Tooltip/index.cjs +0 -1
  129. package/dist/Tooltip/index.mjs +0 -1
  130. package/dist/dialogReturnFocus-cjs.js +4 -1
  131. package/dist/dialogReturnFocus-es.js +4 -1
  132. package/dist/docs/DataDump/DataDump.md +1 -1
  133. package/dist/docs/InputNumber/InputNumber.md +564 -56
  134. package/dist/docs/Page/Page.md +1 -1
  135. package/dist/docs/index.md +0 -1
  136. package/dist/floating-ui.react-cjs.js +34 -35
  137. package/dist/floating-ui.react-dom-cjs.js +64 -65
  138. package/dist/floating-ui.react-dom-es.js +1 -2
  139. package/dist/floating-ui.react-es.js +1 -2
  140. package/dist/floating-ui.utils-cjs.js +183 -0
  141. package/dist/floating-ui.utils-es.js +165 -1
  142. package/dist/index.cjs +10 -15
  143. package/dist/index.mjs +10 -15
  144. package/dist/primitives/BottomSheet/index.cjs +2 -5
  145. package/dist/primitives/BottomSheet/index.mjs +2 -5
  146. package/dist/primitives/ComboboxPrimitive/index.cjs +3 -7
  147. package/dist/primitives/ComboboxPrimitive/index.mjs +3 -7
  148. package/dist/primitives/HelperText/HelperText.d.ts +4 -1
  149. package/dist/primitives/HelperText/index.cjs +1 -1
  150. package/dist/primitives/HelperText/index.mjs +1 -1
  151. package/dist/primitives/SelectPrimitive/index.cjs +3 -9
  152. package/dist/primitives/SelectPrimitive/index.mjs +3 -9
  153. package/dist/primitives/index.cjs +2 -16
  154. package/dist/primitives/index.d.ts +0 -2
  155. package/dist/primitives/index.mjs +2 -15
  156. package/dist/scrollEdges-cjs.js +6 -2
  157. package/dist/scrollEdges-es.js +5 -2
  158. package/dist/sharedHelpers/i18n/renderWithLocale.d.ts +11 -0
  159. package/dist/showToast-cjs.js +20 -6
  160. package/dist/showToast-es.js +20 -6
  161. package/dist/styles.css +573 -902
  162. package/dist/unstyledPrimitives/index.cjs +105 -111
  163. package/dist/unstyledPrimitives/index.mjs +5 -11
  164. package/dist/useCompositeListItem-cjs.js +516 -90
  165. package/dist/useCompositeListItem-es.js +407 -6
  166. package/dist/useLabel-cjs.js +10 -10
  167. package/dist/useLabel-es.js +3 -3
  168. package/dist/useRenderElement-es.js +1 -1
  169. package/dist/useScrollLock-cjs.js +1332 -203
  170. package/dist/useScrollLock-es.js +1068 -5
  171. package/dist/utils/meta/meta.json +12 -0
  172. package/package.json +2 -3
  173. package/dist/InputNumber/InputNumber.types.d.ts +0 -20
  174. package/dist/InputNumberExperimental-cjs.js +0 -277
  175. package/dist/InputNumberExperimental-es.js +0 -275
  176. package/dist/clamp-cjs.js +0 -7
  177. package/dist/clamp-es.js +0 -5
  178. package/dist/clsx-cjs.js +0 -5
  179. package/dist/clsx-es.js +0 -3
  180. package/dist/docs/InputNumberExperimental/InputNumberExperimental.md +0 -578
  181. package/dist/floating-ui.utils.dom-cjs.js +0 -185
  182. package/dist/floating-ui.utils.dom-es.js +0 -165
  183. package/dist/isElementDisabled-cjs.js +0 -40
  184. package/dist/isElementDisabled-es.js +0 -18
  185. package/dist/primitives/InputNumberExperimental/InputNumberExperimental.d.ts +0 -77
  186. package/dist/primitives/InputNumberExperimental/index.cjs +0 -30
  187. package/dist/primitives/InputNumberExperimental/index.d.ts +0 -2
  188. package/dist/primitives/InputNumberExperimental/index.mjs +0 -24
  189. package/dist/resolveAriaLabelledBy-cjs.js +0 -200
  190. package/dist/resolveAriaLabelledBy-es.js +0 -166
  191. package/dist/useButton-cjs.js +0 -1164
  192. package/dist/useButton-es.js +0 -1071
  193. package/dist/useLabelableId-cjs.js +0 -278
  194. package/dist/useLabelableId-es.js +0 -247
@@ -1,12 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  var React = require('react');
4
- var useButton = require('./useButton-cjs.js');
5
- var floatingUi_utils_dom = require('./floating-ui.utils.dom-cjs.js');
6
4
  var useScrollLock = require('./useScrollLock-cjs.js');
5
+ var floatingUi_utils = require('./floating-ui.utils-cjs.js');
7
6
  var useRenderElement = require('./useRenderElement-cjs.js');
8
7
  var jsxRuntime = require('react/jsx-runtime');
9
- var floatingUi_utils = require('./floating-ui.utils-cjs.js');
10
8
  var floatingUi_reactDom = require('./floating-ui.react-dom-cjs.js');
11
9
 
12
10
  function _interopNamespaceDefault(e) {
@@ -34,11 +32,11 @@ function useFloatingRootContext(options) {
34
32
  onOpenChange,
35
33
  elements = {}
36
34
  } = options;
37
- const floatingId = useButton.useId();
35
+ const floatingId = useScrollLock.useId();
38
36
  const nested = useScrollLock.useFloatingParentNodeId() != null;
39
37
  if (process.env.NODE_ENV !== 'production') {
40
38
  const optionDomReference = elements.reference;
41
- if (optionDomReference && !floatingUi_utils_dom.isElement(optionDomReference)) {
39
+ if (optionDomReference && !floatingUi_utils.isElement(optionDomReference)) {
42
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.');
43
41
  }
44
42
  }
@@ -53,7 +51,7 @@ function useFloatingRootContext(options) {
53
51
  syncOnly: false,
54
52
  nested
55
53
  })).current;
56
- useButton.useIsoLayoutEffect(() => {
54
+ useScrollLock.useIsoLayoutEffect(() => {
57
55
  const valuesToSync = {
58
56
  open,
59
57
  floatingId
@@ -62,7 +60,7 @@ function useFloatingRootContext(options) {
62
60
  // Only sync elements that are defined to avoid overwriting existing ones
63
61
  if (elements.reference !== undefined) {
64
62
  valuesToSync.referenceElement = elements.reference;
65
- valuesToSync.domReferenceElement = floatingUi_utils_dom.isElement(elements.reference) ? elements.reference : null;
63
+ valuesToSync.domReferenceElement = floatingUi_utils.isElement(elements.reference) ? elements.reference : null;
66
64
  }
67
65
  if (elements.floating !== undefined) {
68
66
  valuesToSync.floatingElement = elements.floating;
@@ -109,13 +107,13 @@ function useFloating(options = {}) {
109
107
  })
110
108
  }
111
109
  });
112
- const localDomReferenceElement = floatingUi_utils_dom.isElement(localDomReference) ? localDomReference : null;
110
+ const localDomReferenceElement = floatingUi_utils.isElement(localDomReference) ? localDomReference : null;
113
111
  const syncedFloatingElement = localFloatingElement === undefined ? store.state.floatingElement : localFloatingElement;
114
112
  store.useSyncedValue('referenceElement', localDomReference ?? null);
115
113
  store.useSyncedValue('domReferenceElement', localDomReference === undefined ? domReferenceElement : localDomReferenceElement);
116
114
  store.useSyncedValue('floatingElement', syncedFloatingElement);
117
115
  const setPositionReference = React__namespace.useCallback(node => {
118
- const computedPositionReference = floatingUi_utils_dom.isElement(node) ? {
116
+ const computedPositionReference = floatingUi_utils.isElement(node) ? {
119
117
  getBoundingClientRect: () => node.getBoundingClientRect(),
120
118
  getClientRects: () => node.getClientRects(),
121
119
  contextElement: node
@@ -126,18 +124,18 @@ function useFloating(options = {}) {
126
124
  position.refs.setReference(computedPositionReference);
127
125
  }, [position.refs]);
128
126
  const setReference = React__namespace.useCallback(node => {
129
- if (floatingUi_utils_dom.isElement(node) || node === null) {
127
+ if (floatingUi_utils.isElement(node) || node === null) {
130
128
  domReferenceRef.current = node;
131
129
  setLocalDomReference(node);
132
130
  }
133
131
 
134
132
  // Backwards-compatibility for passing a virtual element to `reference`
135
133
  // after it has set the DOM reference.
136
- if (floatingUi_utils_dom.isElement(position.refs.reference.current) || position.refs.reference.current === null ||
134
+ if (floatingUi_utils.isElement(position.refs.reference.current) || position.refs.reference.current === null ||
137
135
  // Don't allow setting virtual elements using the old technique back to
138
136
  // `null` to support `positionReference` + an unstable `reference`
139
137
  // callback ref.
140
- node !== null && !floatingUi_utils_dom.isElement(node)) {
138
+ node !== null && !floatingUi_utils.isElement(node)) {
141
139
  position.refs.setReference(node);
142
140
  }
143
141
  }, [position.refs, setLocalDomReference]);
@@ -168,12 +166,12 @@ function useFloating(options = {}) {
168
166
  nodeId,
169
167
  rootStore: store
170
168
  }), [position, refs, elements, nodeId, store, open, floatingId]);
171
- useButton.useIsoLayoutEffect(() => {
169
+ useScrollLock.useIsoLayoutEffect(() => {
172
170
  if (domReferenceElement) {
173
171
  domReferenceRef.current = domReferenceElement;
174
172
  }
175
173
  }, [domReferenceElement]);
176
- useButton.useIsoLayoutEffect(() => {
174
+ useScrollLock.useIsoLayoutEffect(() => {
177
175
  store.context.dataRef.current.floatingContext = context;
178
176
  const node = tree?.nodesRef.current.find(n => n.id === nodeId);
179
177
  if (node) {
@@ -272,14 +270,14 @@ function useListNavigation(context, props) {
272
270
  const dataRef = store.context.dataRef;
273
271
  const floatingFocusElement = useScrollLock.getFloatingFocusElement(floatingElement);
274
272
  const typeableComboboxReference = useScrollLock.isTypeableCombobox(domReferenceElement);
275
- const floatingFocusElementRef = useButton.useValueAsRef(floatingFocusElement);
273
+ const floatingFocusElementRef = useScrollLock.useValueAsRef(floatingFocusElement);
276
274
  const parentId = useScrollLock.useFloatingParentNodeId();
277
275
  const tree = useScrollLock.useFloatingTree(externalTree);
278
276
  const focusItemOnOpenRef = React__namespace.useRef(focusItemOnOpen);
279
277
  const indexRef = React__namespace.useRef(selectedIndex ?? -1);
280
278
  const keyRef = React__namespace.useRef(null);
281
279
  const isPointerModalityRef = React__namespace.useRef(true);
282
- const onNavigate = useButton.useStableCallback(event => {
280
+ const onNavigate = useScrollLock.useStableCallback(event => {
283
281
  onNavigateProp(indexRef.current === -1 ? null : indexRef.current, event);
284
282
  });
285
283
  const previousMountedRef = React__namespace.useRef(!!floatingElement);
@@ -287,13 +285,13 @@ function useListNavigation(context, props) {
287
285
  const forceSyncFocusRef = React__namespace.useRef(false);
288
286
  const forceScrollIntoViewRef = React__namespace.useRef(false);
289
287
  const cancelQueuedFocusRef = React__namespace.useRef(null);
290
- const disabledIndicesRef = useButton.useValueAsRef(disabledIndices);
291
- const latestOpenRef = useButton.useValueAsRef(open);
292
- const selectedIndexRef = useButton.useValueAsRef(selectedIndex);
293
- const resetOnPointerLeaveRef = useButton.useValueAsRef(resetOnPointerLeave);
294
- const focusFrame = useButton.useAnimationFrame();
295
- const waitForListPopulatedFrame = useButton.useAnimationFrame();
296
- const focusItem = useButton.useStableCallback(() => {
288
+ const disabledIndicesRef = useScrollLock.useValueAsRef(disabledIndices);
289
+ const latestOpenRef = useScrollLock.useValueAsRef(open);
290
+ const selectedIndexRef = useScrollLock.useValueAsRef(selectedIndex);
291
+ const resetOnPointerLeaveRef = useScrollLock.useValueAsRef(resetOnPointerLeave);
292
+ const focusFrame = useScrollLock.useAnimationFrame();
293
+ const waitForListPopulatedFrame = useScrollLock.useAnimationFrame();
294
+ const focusItem = useScrollLock.useStableCallback(() => {
297
295
  function runFocus(item) {
298
296
  if (virtual) {
299
297
  tree?.events.emit('virtualfocus', item);
@@ -331,13 +329,13 @@ function useListNavigation(context, props) {
331
329
  }
332
330
  });
333
331
  });
334
- useButton.useIsoLayoutEffect(() => {
332
+ useScrollLock.useIsoLayoutEffect(() => {
335
333
  dataRef.current.orientation = orientation;
336
334
  }, [dataRef, orientation]);
337
335
 
338
336
  // Sync `selectedIndex` to be the `activeIndex` upon opening the floating
339
337
  // element. Also, reset `activeIndex` upon closing the floating element.
340
- useButton.useIsoLayoutEffect(() => {
338
+ useScrollLock.useIsoLayoutEffect(() => {
341
339
  if (!enabled) {
342
340
  return;
343
341
  }
@@ -360,7 +358,7 @@ function useListNavigation(context, props) {
360
358
 
361
359
  // Sync `activeIndex` to be the focused item while the floating element is
362
360
  // open.
363
- useButton.useIsoLayoutEffect(() => {
361
+ useScrollLock.useIsoLayoutEffect(() => {
364
362
  if (!enabled) {
365
363
  return;
366
364
  }
@@ -417,7 +415,7 @@ function useListNavigation(context, props) {
417
415
 
418
416
  // Ensure the parent floating element has focus when a nested child closes
419
417
  // to allow arrow key navigation to work after the pointer leaves the child.
420
- useButton.useIsoLayoutEffect(() => {
418
+ useScrollLock.useIsoLayoutEffect(() => {
421
419
  if (!enabled || floatingElement || !tree || virtual || !previousMountedRef.current) {
422
420
  return;
423
421
  }
@@ -426,26 +424,26 @@ function useListNavigation(context, props) {
426
424
  // `floatingElement` is null here (see the guard above), so resolve the owner document from an
427
425
  // in-DOM element for realm-safety (shadow DOM/iframes): the reference element, falling back to
428
426
  // the parent floating element when the reference is virtual (`domReferenceElement` is null).
429
- const activeEl = useButton.activeElement(useButton.ownerDocument(domReferenceElement ?? parent ?? null));
430
- const treeContainsActiveEl = nodes.some(node => node.context && useButton.contains(node.context.elements.floating, activeEl));
427
+ const activeEl = useScrollLock.activeElement(useScrollLock.ownerDocument(domReferenceElement ?? parent ?? null));
428
+ const treeContainsActiveEl = nodes.some(node => node.context && useScrollLock.contains(node.context.elements.floating, activeEl));
431
429
  if (parent && !treeContainsActiveEl && isPointerModalityRef.current) {
432
430
  parent.focus({
433
431
  preventScroll: true
434
432
  });
435
433
  }
436
434
  }, [enabled, floatingElement, domReferenceElement, tree, parentId, virtual]);
437
- useButton.useIsoLayoutEffect(() => {
435
+ useScrollLock.useIsoLayoutEffect(() => {
438
436
  previousOpenRef.current = open;
439
437
  previousMountedRef.current = !!floatingElement;
440
438
  });
441
- useButton.useIsoLayoutEffect(() => {
439
+ useScrollLock.useIsoLayoutEffect(() => {
442
440
  if (!open) {
443
441
  keyRef.current = null;
444
442
  focusItemOnOpenRef.current = focusItemOnOpen;
445
443
  }
446
444
  }, [open, focusItemOnOpen]);
447
445
  const hasActiveIndex = activeIndex != null;
448
- const syncCurrentTarget = useButton.useStableCallback(event => {
446
+ const syncCurrentTarget = useScrollLock.useStableCallback(event => {
449
447
  if (!latestOpenRef.current) {
450
448
  return;
451
449
  }
@@ -455,13 +453,13 @@ function useListNavigation(context, props) {
455
453
  onNavigate(event);
456
454
  }
457
455
  });
458
- const getParentOrientation = useButton.useStableCallback(() => {
456
+ const getParentOrientation = useScrollLock.useStableCallback(() => {
459
457
  return parentOrientation ?? tree?.nodesRef.current.find(node => node.id === parentId)?.context?.dataRef?.current.orientation;
460
458
  });
461
- const getMinEnabledIndex = useButton.useStableCallback(() => {
459
+ const getMinEnabledIndex = useScrollLock.useStableCallback(() => {
462
460
  return useScrollLock.getMinListIndex(listRef, disabledIndicesRef.current);
463
461
  });
464
- const commonOnKeyDown = useButton.useStableCallback(event => {
462
+ const commonOnKeyDown = useScrollLock.useStableCallback(event => {
465
463
  isPointerModalityRef.current = false;
466
464
  forceSyncFocusRef.current = true;
467
465
 
@@ -483,10 +481,10 @@ function useListNavigation(context, props) {
483
481
  // If the nested list's close key is also the parent navigation key,
484
482
  // let the parent navigate. Otherwise, stop propagating the event.
485
483
  if (!isMainOrientationKey(event.key, getParentOrientation())) {
486
- useButton.stopEvent(event);
484
+ useScrollLock.stopEvent(event);
487
485
  }
488
- store.setOpen(false, useButton.createChangeEventDetails(useButton.listNavigation, event.nativeEvent));
489
- if (floatingUi_utils_dom.isHTMLElement(domReferenceElement)) {
486
+ store.setOpen(false, useScrollLock.createChangeEventDetails(useScrollLock.listNavigation, event.nativeEvent));
487
+ if (floatingUi_utils.isHTMLElement(domReferenceElement)) {
490
488
  if (virtual) {
491
489
  tree?.events.emit('virtualfocus', domReferenceElement);
492
490
  } else {
@@ -500,12 +498,12 @@ function useListNavigation(context, props) {
500
498
  const maxIndex = useScrollLock.getMaxListIndex(listRef, disabledIndices);
501
499
  if (!typeableComboboxReference) {
502
500
  if (event.key === 'Home') {
503
- useButton.stopEvent(event);
501
+ useScrollLock.stopEvent(event);
504
502
  indexRef.current = minIndex;
505
503
  onNavigate(event);
506
504
  }
507
505
  if (event.key === 'End') {
508
- useButton.stopEvent(event);
506
+ useScrollLock.stopEvent(event);
509
507
  indexRef.current = maxIndex;
510
508
  onNavigate(event);
511
509
  }
@@ -524,10 +522,10 @@ function useListNavigation(context, props) {
524
522
  }
525
523
  }
526
524
  if (isMainOrientationKey(event.key, orientation)) {
527
- useButton.stopEvent(event);
525
+ useScrollLock.stopEvent(event);
528
526
 
529
527
  // Reset the index if no item is focused.
530
- if (open && !virtual && useButton.activeElement(event.currentTarget.ownerDocument) === event.currentTarget) {
528
+ if (open && !virtual && useScrollLock.activeElement(event.currentTarget.ownerDocument) === event.currentTarget) {
531
529
  indexRef.current = isMainOrientationToEndKey(event.key, orientation, rtl) ? minIndex : maxIndex;
532
530
  onNavigate(event);
533
531
  return;
@@ -620,8 +618,8 @@ function useListNavigation(context, props) {
620
618
  onNavigate(event);
621
619
  if (!virtual) {
622
620
  const floatingFocusEl = floatingFocusElementRef.current;
623
- const activeEl = useButton.activeElement(useButton.ownerDocument(floatingFocusEl));
624
- if (floatingFocusEl && useButton.contains(floatingFocusEl, activeEl)) {
621
+ const activeEl = useScrollLock.activeElement(useScrollLock.ownerDocument(floatingFocusEl));
622
+ if (floatingFocusEl && useScrollLock.contains(floatingFocusEl, activeEl)) {
625
623
  floatingFocusEl.focus({
626
624
  preventScroll: true
627
625
  });
@@ -646,13 +644,13 @@ function useListNavigation(context, props) {
646
644
  // If the event originated from within a nested element (e.g., a Dialog opened from
647
645
  // within the menu), don't close the menu. The nested element has its own focus
648
646
  // management and should handle the Tab key.
649
- const target = useButton.getTarget(event.nativeEvent);
650
- if (target && !useButton.contains(floatingFocusElementRef.current, target)) {
647
+ const target = useScrollLock.getTarget(event.nativeEvent);
648
+ if (target && !useScrollLock.contains(floatingFocusElementRef.current, target)) {
651
649
  return;
652
650
  }
653
- useButton.stopEvent(event);
654
- store.setOpen(false, useButton.createChangeEventDetails(useButton.focusOut, event.nativeEvent));
655
- if (floatingUi_utils_dom.isHTMLElement(domReferenceElement)) {
651
+ useScrollLock.stopEvent(event);
652
+ store.setOpen(false, useScrollLock.createChangeEventDetails(useScrollLock.focusOut, event.nativeEvent));
653
+ if (floatingUi_utils.isHTMLElement(domReferenceElement)) {
656
654
  domReferenceElement.focus();
657
655
  }
658
656
  return;
@@ -666,17 +664,17 @@ function useListNavigation(context, props) {
666
664
  }, [ariaActiveDescendantProp, commonOnKeyDown, floatingFocusElementRef, orientation, typeableComboboxReference, store, open, virtual, domReferenceElement]);
667
665
  const trigger = React__namespace.useMemo(() => {
668
666
  function openOnNavigationKeyDown(event) {
669
- store.setOpen(true, useButton.createChangeEventDetails(useButton.listNavigation, event.nativeEvent, event.currentTarget));
667
+ store.setOpen(true, useScrollLock.createChangeEventDetails(useScrollLock.listNavigation, event.nativeEvent, event.currentTarget));
670
668
  }
671
669
  function checkVirtualMouse(event) {
672
- if (focusItemOnOpen === 'auto' && useButton.isVirtualClick(event.nativeEvent)) {
670
+ if (focusItemOnOpen === 'auto' && useScrollLock.isVirtualClick(event.nativeEvent)) {
673
671
  focusItemOnOpenRef.current = !virtual;
674
672
  }
675
673
  }
676
674
  function checkVirtualPointer(event) {
677
675
  // `pointerdown` fires first, reset the state then perform the checks.
678
676
  focusItemOnOpenRef.current = focusItemOnOpen;
679
- if (focusItemOnOpen === 'auto' && useButton.isVirtualPointerEvent(event.nativeEvent)) {
677
+ if (focusItemOnOpen === 'auto' && useScrollLock.isVirtualPointerEvent(event.nativeEvent)) {
680
678
  focusItemOnOpenRef.current = true;
681
679
  }
682
680
  }
@@ -704,7 +702,7 @@ function useListNavigation(context, props) {
704
702
  }
705
703
  if (nested) {
706
704
  if (isParentCrossOpenKey) {
707
- useButton.stopEvent(event);
705
+ useScrollLock.stopEvent(event);
708
706
  if (currentOpen) {
709
707
  indexRef.current = getMinEnabledIndex();
710
708
  onNavigate(event);
@@ -718,7 +716,7 @@ function useListNavigation(context, props) {
718
716
  if (selectedIndexRef.current != null) {
719
717
  indexRef.current = selectedIndexRef.current;
720
718
  }
721
- useButton.stopEvent(event);
719
+ useScrollLock.stopEvent(event);
722
720
  if (!currentOpen && openOnArrowKeyDown) {
723
721
  openOnNavigationKeyDown(event);
724
722
  } else {
@@ -775,11 +773,11 @@ function useTypeahead(context, props) {
775
773
  } = props;
776
774
  const store = 'rootStore' in context ? context.rootStore : context;
777
775
  const open = store.useState('open');
778
- const timeout = useButton.useTimeout();
776
+ const timeout = useScrollLock.useTimeout();
779
777
  const stringRef = React__namespace.useRef('');
780
778
  const prevIndexRef = React__namespace.useRef(selectedIndex ?? activeIndex ?? -1);
781
779
  const matchIndexRef = React__namespace.useRef(null);
782
- const onKeyDown = useButton.useStableCallback(event => {
780
+ const onKeyDown = useScrollLock.useStableCallback(event => {
783
781
  function isVisible(index) {
784
782
  const element = elementsRef?.current[index];
785
783
  return !element || useScrollLock.isElementVisible(element);
@@ -813,7 +811,7 @@ function useTypeahead(context, props) {
813
811
  const listContent = listRef.current;
814
812
  if (stringRef.current.length > 0 && event.key === ' ') {
815
813
  // Space should continue the in-progress typeahead session.
816
- useButton.stopEvent(event);
814
+ useScrollLock.stopEvent(event);
817
815
  onTyping?.(true);
818
816
  }
819
817
  if (stringRef.current.length > 0 && stringRef.current[0] !== ' ') {
@@ -829,7 +827,7 @@ function useTypeahead(context, props) {
829
827
  return;
830
828
  }
831
829
  if (open && event.key !== ' ') {
832
- useButton.stopEvent(event);
830
+ useScrollLock.stopEvent(event);
833
831
  onTyping?.(true);
834
832
  }
835
833
 
@@ -872,11 +870,11 @@ function useTypeahead(context, props) {
872
870
  onTyping?.(false);
873
871
  }
874
872
  });
875
- const onBlur = useButton.useStableCallback(event => {
873
+ const onBlur = useScrollLock.useStableCallback(event => {
876
874
  const next = event.relatedTarget;
877
875
  const currentDomReferenceElement = store.select('domReferenceElement');
878
876
  const currentFloatingElement = store.select('floatingElement');
879
- const withinComposite = useButton.contains(currentDomReferenceElement, next) || useButton.contains(currentFloatingElement, next);
877
+ const withinComposite = useScrollLock.contains(currentDomReferenceElement, next) || useScrollLock.contains(currentFloatingElement, next);
880
878
 
881
879
  // Keep the session if focus moves within the composite (reference <-> floating).
882
880
  if (withinComposite) {
@@ -889,7 +887,7 @@ function useTypeahead(context, props) {
889
887
  prevIndexRef.current = matchIndexRef.current;
890
888
  onTyping?.(false);
891
889
  });
892
- useButton.useIsoLayoutEffect(() => {
890
+ useScrollLock.useIsoLayoutEffect(() => {
893
891
  if (!open && selectedIndex !== null) {
894
892
  return;
895
893
  }
@@ -899,7 +897,7 @@ function useTypeahead(context, props) {
899
897
  stringRef.current = '';
900
898
  }
901
899
  }, [open, selectedIndex, timeout]);
902
- useButton.useIsoLayoutEffect(() => {
900
+ useScrollLock.useIsoLayoutEffect(() => {
903
901
  // Sync arrow key navigation but not typeahead navigation.
904
902
  if (open && stringRef.current === '') {
905
903
  prevIndexRef.current = selectedIndex ?? activeIndex ?? -1;
@@ -915,12 +913,408 @@ function useTypeahead(context, props) {
915
913
  } : {}, [enabled, sharedProps]);
916
914
  }
917
915
 
916
+ const defaultItemEquality = (itemValue, selectedValue) => Object.is(itemValue, selectedValue);
917
+ function compareItemEquality(itemValue, selectedValue, comparer) {
918
+ if (itemValue == null || selectedValue == null) {
919
+ return Object.is(itemValue, selectedValue);
920
+ }
921
+ return comparer(itemValue, selectedValue);
922
+ }
923
+ function selectedValueIncludes(selectedValues, itemValue, comparer) {
924
+ if (!selectedValues || selectedValues.length === 0) {
925
+ return false;
926
+ }
927
+ return selectedValues.some(selectedValue => {
928
+ if (selectedValue === undefined) {
929
+ return false;
930
+ }
931
+ return compareItemEquality(itemValue, selectedValue, comparer);
932
+ });
933
+ }
934
+ function findItemIndex(itemValues, selectedValue, comparer) {
935
+ if (!itemValues || itemValues.length === 0) {
936
+ return -1;
937
+ }
938
+ return itemValues.findIndex(itemValue => {
939
+ if (itemValue === undefined) {
940
+ return false;
941
+ }
942
+ return compareItemEquality(itemValue, selectedValue, comparer);
943
+ });
944
+ }
945
+ function removeItem(selectedValues, itemValue, comparer) {
946
+ return selectedValues.filter(selectedValue => !compareItemEquality(itemValue, selectedValue, comparer));
947
+ }
948
+
949
+ function serializeValue(value) {
950
+ if (value == null) {
951
+ return '';
952
+ }
953
+ if (typeof value === 'string') {
954
+ return value;
955
+ }
956
+ try {
957
+ return JSON.stringify(value);
958
+ } catch {
959
+ return String(value);
960
+ }
961
+ }
962
+
963
+ function isGroupedItems(items) {
964
+ return items != null && items.length > 0 && typeof items[0] === 'object' && items[0] != null && 'items' in items[0];
965
+ }
966
+
967
+ /**
968
+ * Checks if the items array contains an item with a null value that has a non-null label.
969
+ */
970
+ function hasNullItemLabel(items) {
971
+ if (!Array.isArray(items)) {
972
+ return items != null && 'null' in items;
973
+ }
974
+ const arrayItems = items;
975
+ if (isGroupedItems(arrayItems)) {
976
+ for (const group of arrayItems) {
977
+ for (const item of group.items) {
978
+ if (item && item.value == null && item.label != null) {
979
+ return true;
980
+ }
981
+ }
982
+ }
983
+ return false;
984
+ }
985
+ for (const item of arrayItems) {
986
+ if (item && item.value == null && item.label != null) {
987
+ return true;
988
+ }
989
+ }
990
+ return false;
991
+ }
992
+ function stringifyAsLabel(item, itemToStringLabel) {
993
+ if (itemToStringLabel && item != null) {
994
+ return itemToStringLabel(item) ?? '';
995
+ }
996
+ if (item && typeof item === 'object') {
997
+ if ('label' in item && item.label != null) {
998
+ return String(item.label);
999
+ }
1000
+ if ('value' in item) {
1001
+ return String(item.value);
1002
+ }
1003
+ }
1004
+ return serializeValue(item);
1005
+ }
1006
+ function stringifyAsValue(item, itemToStringValue) {
1007
+ if (itemToStringValue && item != null) {
1008
+ return itemToStringValue(item) ?? '';
1009
+ }
1010
+ if (item && typeof item === 'object' && 'value' in item && 'label' in item) {
1011
+ return serializeValue(item.value);
1012
+ }
1013
+ return serializeValue(item);
1014
+ }
1015
+ function resolveSelectedLabel(value, items, itemToStringLabel) {
1016
+ function fallback() {
1017
+ return stringifyAsLabel(value, itemToStringLabel);
1018
+ }
1019
+ if (itemToStringLabel && value != null) {
1020
+ return itemToStringLabel(value);
1021
+ }
1022
+
1023
+ // Custom object with explicit label takes precedence
1024
+ if (value && typeof value === 'object' && 'label' in value && value.label != null) {
1025
+ return value.label;
1026
+ }
1027
+
1028
+ // Items provided as plain record map
1029
+ if (items && !Array.isArray(items)) {
1030
+ return items[value] ?? fallback();
1031
+ }
1032
+
1033
+ // Items provided as array (flat or grouped)
1034
+ if (Array.isArray(items)) {
1035
+ const arrayItems = items;
1036
+ const flatItems = isGroupedItems(arrayItems) ? arrayItems.flatMap(group => group.items) : arrayItems;
1037
+ if (value == null || typeof value !== 'object') {
1038
+ const match = flatItems.find(item => item.value === value);
1039
+ if (match && match.label != null) {
1040
+ return match.label;
1041
+ }
1042
+ return fallback();
1043
+ }
1044
+
1045
+ // Object without explicit label: try matching by its `value` property
1046
+ if ('value' in value) {
1047
+ const match = flatItems.find(item => item && item.value === value.value);
1048
+ if (match && match.label != null) {
1049
+ return match.label;
1050
+ }
1051
+ }
1052
+ }
1053
+ return fallback();
1054
+ }
1055
+ function resolveMultipleLabels(values, items, itemToStringLabel) {
1056
+ return values.reduce((acc, value, index) => {
1057
+ if (index > 0) {
1058
+ acc.push(', ');
1059
+ }
1060
+ acc.push(/*#__PURE__*/jsxRuntime.jsx(React__namespace.Fragment, {
1061
+ children: resolveSelectedLabel(value, items, itemToStringLabel)
1062
+ }, index));
1063
+ return acc;
1064
+ }, []);
1065
+ }
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
+
1099
+ const DEFAULT_VALIDITY_STATE = {
1100
+ badInput: false,
1101
+ customError: false,
1102
+ patternMismatch: false,
1103
+ rangeOverflow: false,
1104
+ rangeUnderflow: false,
1105
+ stepMismatch: false,
1106
+ tooLong: false,
1107
+ tooShort: false,
1108
+ typeMismatch: false,
1109
+ valid: null,
1110
+ valueMissing: false
1111
+ };
1112
+ const DEFAULT_FIELD_STATE_ATTRIBUTES = {
1113
+ valid: null,
1114
+ touched: false,
1115
+ dirty: false,
1116
+ filled: false,
1117
+ focused: false
1118
+ };
1119
+ const DEFAULT_FIELD_ROOT_STATE = {
1120
+ disabled: false,
1121
+ ...DEFAULT_FIELD_STATE_ATTRIBUTES
1122
+ };
1123
+ const fieldValidityMapping = {
1124
+ valid(value) {
1125
+ if (value === null) {
1126
+ return null;
1127
+ }
1128
+ if (value) {
1129
+ return {
1130
+ [FieldControlDataAttributes.valid]: ''
1131
+ };
1132
+ }
1133
+ return {
1134
+ [FieldControlDataAttributes.invalid]: ''
1135
+ };
1136
+ }
1137
+ };
1138
+
1139
+ const DEFAULT_FIELD_ROOT_CONTEXT = {
1140
+ invalid: undefined,
1141
+ name: undefined,
1142
+ validityData: {
1143
+ state: DEFAULT_VALIDITY_STATE,
1144
+ errors: [],
1145
+ error: '',
1146
+ value: '',
1147
+ initialValue: null
1148
+ },
1149
+ setValidityData: useRenderElement.NOOP,
1150
+ disabled: undefined,
1151
+ touched: DEFAULT_FIELD_STATE_ATTRIBUTES.touched,
1152
+ setTouched: useRenderElement.NOOP,
1153
+ dirty: DEFAULT_FIELD_STATE_ATTRIBUTES.dirty,
1154
+ setDirty: useRenderElement.NOOP,
1155
+ filled: DEFAULT_FIELD_STATE_ATTRIBUTES.filled,
1156
+ setFilled: useRenderElement.NOOP,
1157
+ focused: DEFAULT_FIELD_STATE_ATTRIBUTES.focused,
1158
+ setFocused: useRenderElement.NOOP,
1159
+ validate: () => null,
1160
+ validationMode: 'onSubmit',
1161
+ validationDebounceTime: 0,
1162
+ shouldValidateOnChange: () => false,
1163
+ state: DEFAULT_FIELD_ROOT_STATE,
1164
+ markedDirtyRef: {
1165
+ current: false
1166
+ },
1167
+ registerFieldControl: useRenderElement.NOOP,
1168
+ validation: {
1169
+ getValidationProps: (_disabled, props = useRenderElement.EMPTY_OBJECT) => props,
1170
+ inputRef: {
1171
+ current: null
1172
+ },
1173
+ registerInput: useRenderElement.NOOP,
1174
+ commit: async () => {},
1175
+ change: useRenderElement.NOOP
1176
+ }
1177
+ };
1178
+ const FieldRootContext = /*#__PURE__*/React__namespace.createContext(DEFAULT_FIELD_ROOT_CONTEXT);
1179
+ if (process.env.NODE_ENV !== "production") FieldRootContext.displayName = "FieldRootContext";
1180
+ function useFieldRootContext(optional = true) {
1181
+ const context = React__namespace.useContext(FieldRootContext);
1182
+ if (context.setValidityData === useRenderElement.NOOP && !optional) {
1183
+ throw new Error(process.env.NODE_ENV !== "production" ? 'Base UI: FieldRootContext is missing. Field parts must be placed within <Field.Root>.' : useRenderElement.formatErrorMessage(28));
1184
+ }
1185
+ return context;
1186
+ }
1187
+
1188
+ function useRegisterFieldControl(controlRef, id, value, getFormValueOverride, enabled = true, name) {
1189
+ const {
1190
+ registerFieldControl
1191
+ } = useFieldRootContext();
1192
+ const sourceRef = React__namespace.useRef(null);
1193
+ if (!sourceRef.current) {
1194
+ sourceRef.current = Symbol();
1195
+ }
1196
+ useScrollLock.useIsoLayoutEffect(() => {
1197
+ const source = sourceRef.current;
1198
+ if (!source || !enabled) {
1199
+ return undefined;
1200
+ }
1201
+ const registration = {
1202
+ controlRef,
1203
+ getValue: getFormValueOverride,
1204
+ id,
1205
+ name,
1206
+ value
1207
+ };
1208
+ registerFieldControl(source, registration);
1209
+ return () => {
1210
+ registerFieldControl(source, undefined);
1211
+ };
1212
+ }, [controlRef, enabled, getFormValueOverride, id, name, registerFieldControl, value]);
1213
+ }
1214
+
1215
+ const FormContext = /*#__PURE__*/React__namespace.createContext({
1216
+ formRef: {
1217
+ current: {
1218
+ fields: new Map()
1219
+ }
1220
+ },
1221
+ errors: {},
1222
+ clearErrors: useRenderElement.NOOP,
1223
+ validationMode: 'onSubmit',
1224
+ submitAttemptedRef: {
1225
+ current: false
1226
+ }
1227
+ });
1228
+ if (process.env.NODE_ENV !== "production") FormContext.displayName = "FormContext";
1229
+ function useFormContext() {
1230
+ return React__namespace.useContext(FormContext);
1231
+ }
1232
+
1233
+ /**
1234
+ * A context for providing [labelable elements](https://html.spec.whatwg.org/multipage/forms.html#category-label)\
1235
+ * with an accessible name (label) and description.
1236
+ */
1237
+ const LabelableContext = /*#__PURE__*/React__namespace.createContext({
1238
+ controlId: undefined,
1239
+ registerControlId: useRenderElement.NOOP,
1240
+ labelId: undefined,
1241
+ setLabelId: useRenderElement.NOOP,
1242
+ messageIds: [],
1243
+ setMessageIds: useRenderElement.NOOP,
1244
+ getDescriptionProps: externalProps => externalProps
1245
+ });
1246
+ if (process.env.NODE_ENV !== "production") LabelableContext.displayName = "LabelableContext";
1247
+ function useLabelableContext() {
1248
+ return React__namespace.useContext(LabelableContext);
1249
+ }
1250
+
1251
+ function useLabelableId(params = {}) {
1252
+ const {
1253
+ id,
1254
+ implicit = false,
1255
+ controlRef
1256
+ } = params;
1257
+ const {
1258
+ controlId,
1259
+ registerControlId
1260
+ } = useLabelableContext();
1261
+ const defaultId = useScrollLock.useBaseUiId(id);
1262
+ const controlIdForEffect = implicit ? controlId : undefined;
1263
+ const controlSourceRef = useRenderElement.useRefWithInit(() => Symbol('labelable-control'));
1264
+ const hasRegisteredRef = React__namespace.useRef(false);
1265
+ const hadExplicitIdRef = React__namespace.useRef(id != null);
1266
+ const unregisterControlId = useScrollLock.useStableCallback(() => {
1267
+ if (!hasRegisteredRef.current || registerControlId === useRenderElement.NOOP) {
1268
+ return;
1269
+ }
1270
+ hasRegisteredRef.current = false;
1271
+ registerControlId(controlSourceRef.current, undefined);
1272
+ });
1273
+ useScrollLock.useIsoLayoutEffect(() => {
1274
+ if (registerControlId === useRenderElement.NOOP) {
1275
+ return undefined;
1276
+ }
1277
+ let nextId;
1278
+ if (implicit) {
1279
+ const elem = controlRef?.current;
1280
+ if (floatingUi_utils.isElement(elem) && elem.closest('label') != null) {
1281
+ nextId = id ?? null;
1282
+ } else {
1283
+ nextId = controlIdForEffect ?? defaultId;
1284
+ }
1285
+ } else if (id != null) {
1286
+ hadExplicitIdRef.current = true;
1287
+ nextId = id;
1288
+ } else if (hadExplicitIdRef.current) {
1289
+ nextId = defaultId;
1290
+ } else {
1291
+ unregisterControlId();
1292
+ return undefined;
1293
+ }
1294
+ if (nextId === undefined) {
1295
+ unregisterControlId();
1296
+ return undefined;
1297
+ }
1298
+ hasRegisteredRef.current = true;
1299
+ registerControlId(controlSourceRef.current, nextId);
1300
+ return undefined;
1301
+ }, [id, controlRef, controlIdForEffect, registerControlId, implicit, defaultId, controlSourceRef, unregisterControlId]);
1302
+ React__namespace.useEffect(() => {
1303
+ return unregisterControlId;
1304
+ }, [unregisterControlId]);
1305
+ return controlId ?? defaultId;
1306
+ }
1307
+
1308
+ function areArraysEqual(array1, array2, itemComparer = (a, b) => a === b) {
1309
+ return array1.length === array2.length && array1.every((value, index) => itemComparer(value, array2[index]));
1310
+ }
1311
+
918
1312
  function getPseudoElementBounds(element) {
919
1313
  const elementRect = element.getBoundingClientRect();
920
- const win = floatingUi_utils_dom.getWindow(element);
1314
+ const win = floatingUi_utils.getWindow(element);
921
1315
 
922
1316
  // Avoid "Not implemented: window.getComputedStyle(elt, pseudoElt)" in jsdom.
923
- if (useButton.jsdom) {
1317
+ if (useScrollLock.jsdom) {
924
1318
  return elementRect;
925
1319
  }
926
1320
  const beforeStyles = win.getComputedStyle(element, '::before');
@@ -951,6 +1345,13 @@ function getPseudoElementBounds(element) {
951
1345
  };
952
1346
  }
953
1347
 
1348
+ function getDefaultLabelId(id) {
1349
+ return id == null ? undefined : `${id}-label`;
1350
+ }
1351
+ function resolveAriaLabelledBy(fieldLabelId, localLabelId) {
1352
+ return fieldLabelId ?? localLabelId;
1353
+ }
1354
+
954
1355
  const CompositeListContext = /*#__PURE__*/React__namespace.createContext({
955
1356
  register: () => {},
956
1357
  unregister: () => {},
@@ -981,7 +1382,7 @@ function CompositeList(props) {
981
1382
  labelsRef,
982
1383
  onMapChange: onMapChangeProp
983
1384
  } = props;
984
- const onMapChange = useButton.useStableCallback(onMapChangeProp);
1385
+ const onMapChange = useScrollLock.useStableCallback(onMapChangeProp);
985
1386
  const nextIndexRef = React__namespace.useRef(0);
986
1387
  const listeners = useRenderElement.useRefWithInit(createListeners).current;
987
1388
 
@@ -997,12 +1398,12 @@ function CompositeList(props) {
997
1398
  // `mapTick` uses a counter rather than objects for low precision-loss risk and better memory efficiency
998
1399
  const [mapTick, setMapTick] = React__namespace.useState(0);
999
1400
  const lastTickRef = React__namespace.useRef(mapTick);
1000
- const register = useButton.useStableCallback((node, metadata) => {
1401
+ const register = useScrollLock.useStableCallback((node, metadata) => {
1001
1402
  map.set(node, metadata ?? null);
1002
1403
  lastTickRef.current += 1;
1003
1404
  setMapTick(lastTickRef.current);
1004
1405
  });
1005
- const unregister = useButton.useStableCallback(node => {
1406
+ const unregister = useScrollLock.useStableCallback(node => {
1006
1407
  map.delete(node);
1007
1408
  lastTickRef.current += 1;
1008
1409
  setMapTick(lastTickRef.current);
@@ -1021,7 +1422,7 @@ function CompositeList(props) {
1021
1422
  });
1022
1423
  return newMap;
1023
1424
  }, [map, mapTick]);
1024
- useButton.useIsoLayoutEffect(() => {
1425
+ useScrollLock.useIsoLayoutEffect(() => {
1025
1426
  if (typeof MutationObserver !== 'function' || sortedMap.size === 0) {
1026
1427
  return undefined;
1027
1428
  }
@@ -1048,7 +1449,7 @@ function CompositeList(props) {
1048
1449
  mutationObserver.disconnect();
1049
1450
  };
1050
1451
  }, [sortedMap]);
1051
- useButton.useIsoLayoutEffect(() => {
1452
+ useScrollLock.useIsoLayoutEffect(() => {
1052
1453
  const shouldUpdateLengths = lastTickRef.current === mapTick;
1053
1454
  if (shouldUpdateLengths) {
1054
1455
  if (elementsRef.current.length !== sortedMap.size) {
@@ -1061,25 +1462,25 @@ function CompositeList(props) {
1061
1462
  }
1062
1463
  onMapChange(sortedMap);
1063
1464
  }, [onMapChange, sortedMap, elementsRef, labelsRef, mapTick]);
1064
- useButton.useIsoLayoutEffect(() => {
1465
+ useScrollLock.useIsoLayoutEffect(() => {
1065
1466
  return () => {
1066
1467
  elementsRef.current = [];
1067
1468
  };
1068
1469
  }, [elementsRef]);
1069
- useButton.useIsoLayoutEffect(() => {
1470
+ useScrollLock.useIsoLayoutEffect(() => {
1070
1471
  return () => {
1071
1472
  if (labelsRef) {
1072
1473
  labelsRef.current = [];
1073
1474
  }
1074
1475
  };
1075
1476
  }, [labelsRef]);
1076
- const subscribeMapChange = useButton.useStableCallback(fn => {
1477
+ const subscribeMapChange = useScrollLock.useStableCallback(fn => {
1077
1478
  listeners.add(fn);
1078
1479
  return () => {
1079
1480
  listeners.delete(fn);
1080
1481
  };
1081
1482
  });
1082
- useButton.useIsoLayoutEffect(() => {
1483
+ useScrollLock.useIsoLayoutEffect(() => {
1083
1484
  listeners.forEach(l => l(sortedMap));
1084
1485
  }, [listeners, sortedMap]);
1085
1486
  const contextValue = React__namespace.useMemo(() => ({
@@ -1246,7 +1647,7 @@ const adaptiveOrigin = {
1246
1647
  strategy,
1247
1648
  placement
1248
1649
  } = state;
1249
- const win = floatingUi_utils_dom.getWindow(floating);
1650
+ const win = floatingUi_utils.getWindow(floating);
1250
1651
  const styles = win.getComputedStyle(floating);
1251
1652
  const hasTransition = styles.transitionDuration !== '0s' && styles.transitionDuration !== '';
1252
1653
  if (!hasTransition) {
@@ -1269,7 +1670,7 @@ const adaptiveOrigin = {
1269
1670
  height: win.visualViewport.height
1270
1671
  };
1271
1672
  } else if (offsetParent === win) {
1272
- const doc = useButton.ownerDocument(floating);
1673
+ const doc = useScrollLock.ownerDocument(floating);
1273
1674
  offsetDimensions = {
1274
1675
  width: doc.documentElement.clientWidth,
1275
1676
  height: doc.documentElement.clientHeight
@@ -1367,10 +1768,10 @@ function useAnchorPositioning(params) {
1367
1768
  const collisionAvoidanceAlign = collisionAvoidance.align || 'flip';
1368
1769
  const collisionAvoidanceFallbackAxisSide = collisionAvoidance.fallbackAxisSide || 'end';
1369
1770
  const anchorFn = typeof anchor === 'function' ? anchor : undefined;
1370
- const anchorFnCallback = useButton.useStableCallback(anchorFn);
1771
+ const anchorFnCallback = useScrollLock.useStableCallback(anchorFn);
1371
1772
  const anchorDep = anchorFn ? anchorFnCallback : anchor;
1372
- const anchorValueRef = useButton.useValueAsRef(anchor);
1373
- const mountedRef = useButton.useValueAsRef(mounted);
1773
+ const anchorValueRef = useScrollLock.useValueAsRef(anchor);
1774
+ const mountedRef = useScrollLock.useValueAsRef(mounted);
1374
1775
  const direction = useScrollLock.useDirection();
1375
1776
  const isRtl = direction === 'rtl';
1376
1777
  const side = mountSide || {
@@ -1418,8 +1819,8 @@ function useAnchorPositioning(params) {
1418
1819
  const arrowRef = React__namespace.useRef(null);
1419
1820
 
1420
1821
  // Keep these reactive if they're not functions
1421
- const sideOffsetRef = useButton.useValueAsRef(sideOffset);
1422
- const alignOffsetRef = useButton.useValueAsRef(alignOffset);
1822
+ const sideOffsetRef = useScrollLock.useValueAsRef(sideOffset);
1823
+ const alignOffsetRef = useScrollLock.useValueAsRef(alignOffset);
1423
1824
  const sideOffsetDep = typeof sideOffset !== 'function' ? sideOffset : 0;
1424
1825
  const alignOffsetDep = typeof alignOffset !== 'function' ? alignOffset : 0;
1425
1826
  const middleware = [];
@@ -1453,7 +1854,7 @@ function useAnchorPositioning(params) {
1453
1854
  fallbackAxisSideDirection: collisionAvoidanceFallbackAxisSide
1454
1855
  });
1455
1856
  const shiftMiddleware = shiftDisabled ? null : floatingUi_reactDom.shift(data => {
1456
- const html = useButton.ownerDocument(data.elements.floating).documentElement;
1857
+ const html = useScrollLock.ownerDocument(data.elements.floating).documentElement;
1457
1858
  return {
1458
1859
  ...commonCollisionProps,
1459
1860
  // Use the Layout Viewport to avoid shifting around when pinch-zooming
@@ -1508,7 +1909,7 @@ function useAnchorPositioning(params) {
1508
1909
  floatingStyle.setProperty('--available-height', `${availableHeight}px`);
1509
1910
 
1510
1911
  // Snap anchor dimensions to device pixels to ensure the popup's visual width matches the anchor's one.
1511
- const dpr = floatingUi_utils_dom.getWindow(floating).devicePixelRatio || 1;
1912
+ const dpr = floatingUi_utils.getWindow(floating).devicePixelRatio || 1;
1512
1913
  const {
1513
1914
  x,
1514
1915
  y,
@@ -1523,7 +1924,7 @@ function useAnchorPositioning(params) {
1523
1924
  }), arrow(state => ({
1524
1925
  // `transform-origin` calculations rely on an element existing. If the arrow hasn't been set,
1525
1926
  // we'll create a fake element.
1526
- element: arrowRef.current || useButton.ownerDocument(state.elements.floating).createElement('div'),
1927
+ element: arrowRef.current || useScrollLock.ownerDocument(state.elements.floating).createElement('div'),
1527
1928
  padding: arrowPadding,
1528
1929
  offsetParent: 'floating'
1529
1930
  }), [arrowPadding]), {
@@ -1560,7 +1961,7 @@ function useAnchorPositioning(params) {
1560
1961
  return {};
1561
1962
  }
1562
1963
  }, hide, adaptiveOrigin);
1563
- useButton.useIsoLayoutEffect(() => {
1964
+ useScrollLock.useIsoLayoutEffect(() => {
1564
1965
  // Ensure positioning doesn't run initially for `keepMounted` elements that
1565
1966
  // aren't initially open.
1566
1967
  if (!mounted && floatingRootContext) {
@@ -1620,7 +2021,7 @@ function useAnchorPositioning(params) {
1620
2021
  return base;
1621
2022
  }, [adaptiveOrigin, resolvedPosition, sideX, x, sideY, y, originalFloatingStyles, isPositioned]);
1622
2023
  const registeredPositionReferenceRef = React__namespace.useRef(null);
1623
- useButton.useIsoLayoutEffect(() => {
2024
+ useScrollLock.useIsoLayoutEffect(() => {
1624
2025
  if (!mounted) {
1625
2026
  return;
1626
2027
  }
@@ -1663,7 +2064,7 @@ function useAnchorPositioning(params) {
1663
2064
  // Locks the flip (makes it "sticky") so it doesn't prefer a given placement
1664
2065
  // and flips back lazily, not eagerly. Ideal for filtered lists that change
1665
2066
  // the size of the popup dynamically to avoid unwanted flipping when typing.
1666
- useButton.useIsoLayoutEffect(() => {
2067
+ useScrollLock.useIsoLayoutEffect(() => {
1667
2068
  if (lazyFlip && mounted && isPositioned) {
1668
2069
  setMountSide(renderedSide);
1669
2070
  }
@@ -1740,12 +2141,12 @@ const VIEWPORT_WIDTH_TOLERANCE_PX = 20;
1740
2141
  */
1741
2142
  function useAnchoredPopupScrollLock(enabled, touchOpen, positionerElement, referenceElement) {
1742
2143
  const [touchOpenShouldLockScroll, setTouchOpenShouldLockScroll] = React__namespace.useState(false);
1743
- useButton.useIsoLayoutEffect(() => {
2144
+ useScrollLock.useIsoLayoutEffect(() => {
1744
2145
  if (!enabled || !touchOpen || positionerElement == null) {
1745
2146
  setTouchOpenShouldLockScroll(false);
1746
2147
  return;
1747
2148
  }
1748
- const viewportWidth = useButton.ownerDocument(positionerElement).documentElement.clientWidth;
2149
+ const viewportWidth = useScrollLock.ownerDocument(positionerElement).documentElement.clientWidth;
1749
2150
  const popupWidth = positionerElement.offsetWidth;
1750
2151
  setTouchOpenShouldLockScroll(viewportWidth > 0 && popupWidth > 0 && popupWidth >= viewportWidth - VIEWPORT_WIDTH_TOLERANCE_PX);
1751
2152
  }, [enabled, touchOpen, positionerElement]);
@@ -1797,7 +2198,7 @@ function useCompositeListItem(params = {}) {
1797
2198
  }
1798
2199
  }
1799
2200
  }, [index, elementsRef, labelsRef, label, textRef]);
1800
- useButton.useIsoLayoutEffect(() => {
2201
+ useScrollLock.useIsoLayoutEffect(() => {
1801
2202
  if (externalIndex != null) {
1802
2203
  return undefined;
1803
2204
  }
@@ -1810,7 +2211,7 @@ function useCompositeListItem(params = {}) {
1810
2211
  }
1811
2212
  return undefined;
1812
2213
  }, [externalIndex, register, unregister, metadata]);
1813
- useButton.useIsoLayoutEffect(() => {
2214
+ useScrollLock.useIsoLayoutEffect(() => {
1814
2215
  if (externalIndex != null) {
1815
2216
  return undefined;
1816
2217
  }
@@ -1828,14 +2229,39 @@ function useCompositeListItem(params = {}) {
1828
2229
  }
1829
2230
 
1830
2231
  exports.CompositeList = CompositeList;
2232
+ exports.DEFAULT_FIELD_ROOT_CONTEXT = DEFAULT_FIELD_ROOT_CONTEXT;
2233
+ exports.DEFAULT_FIELD_STATE_ATTRIBUTES = DEFAULT_FIELD_STATE_ATTRIBUTES;
2234
+ exports.DEFAULT_VALIDITY_STATE = DEFAULT_VALIDITY_STATE;
2235
+ exports.FieldRootContext = FieldRootContext;
1831
2236
  exports.IndexGuessBehavior = IndexGuessBehavior;
2237
+ exports.LabelableContext = LabelableContext;
1832
2238
  exports.adaptiveOrigin = adaptiveOrigin;
2239
+ exports.areArraysEqual = areArraysEqual;
2240
+ exports.compareItemEquality = compareItemEquality;
2241
+ exports.defaultItemEquality = defaultItemEquality;
2242
+ exports.fieldValidityMapping = fieldValidityMapping;
2243
+ exports.findItemIndex = findItemIndex;
2244
+ exports.getDefaultLabelId = getDefaultLabelId;
1833
2245
  exports.getDisabledMountTransitionStyles = getDisabledMountTransitionStyles;
1834
2246
  exports.getPseudoElementBounds = getPseudoElementBounds;
2247
+ exports.hasNullItemLabel = hasNullItemLabel;
2248
+ exports.isGroupedItems = isGroupedItems;
2249
+ exports.removeItem = removeItem;
2250
+ exports.resolveAriaLabelledBy = resolveAriaLabelledBy;
2251
+ exports.resolveMultipleLabels = resolveMultipleLabels;
2252
+ exports.resolveSelectedLabel = resolveSelectedLabel;
2253
+ exports.selectedValueIncludes = selectedValueIncludes;
2254
+ exports.stringifyAsLabel = stringifyAsLabel;
2255
+ exports.stringifyAsValue = stringifyAsValue;
1835
2256
  exports.useAnchorPositioning = useAnchorPositioning;
1836
2257
  exports.useAnchoredPopupScrollLock = useAnchoredPopupScrollLock;
1837
2258
  exports.useCompositeListItem = useCompositeListItem;
2259
+ exports.useFieldRootContext = useFieldRootContext;
1838
2260
  exports.useFloatingRootContext = useFloatingRootContext;
2261
+ exports.useFormContext = useFormContext;
2262
+ exports.useLabelableContext = useLabelableContext;
2263
+ exports.useLabelableId = useLabelableId;
1839
2264
  exports.useListNavigation = useListNavigation;
1840
2265
  exports.usePositioner = usePositioner;
2266
+ exports.useRegisterFieldControl = useRegisterFieldControl;
1841
2267
  exports.useTypeahead = useTypeahead;