@jobber/components 7.10.0 → 7.11.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 (106) hide show
  1. package/dist/Autocomplete/index.cjs +1 -0
  2. package/dist/Autocomplete/index.mjs +1 -0
  3. package/dist/Card/index.cjs +3 -0
  4. package/dist/Card/index.mjs +3 -0
  5. package/dist/Chip/index.cjs +1 -0
  6. package/dist/Chip/index.mjs +1 -0
  7. package/dist/Chips/InternalChipDismissible/hooks/index.cjs +1 -0
  8. package/dist/Chips/InternalChipDismissible/hooks/index.mjs +1 -0
  9. package/dist/Chips/InternalChipDismissible/index.cjs +1 -0
  10. package/dist/Chips/InternalChipDismissible/index.mjs +1 -0
  11. package/dist/Chips/index.cjs +1 -0
  12. package/dist/Chips/index.mjs +1 -0
  13. package/dist/Combobox/components/ComboboxActivator/index.cjs +1 -0
  14. package/dist/Combobox/components/ComboboxActivator/index.mjs +1 -0
  15. package/dist/Combobox/components/ComboboxContent/index.cjs +1 -0
  16. package/dist/Combobox/components/ComboboxContent/index.mjs +1 -0
  17. package/dist/Combobox/components/ComboboxTrigger/index.cjs +1 -0
  18. package/dist/Combobox/components/ComboboxTrigger/index.mjs +1 -0
  19. package/dist/Combobox/index.cjs +1 -0
  20. package/dist/Combobox/index.mjs +1 -0
  21. package/dist/ConfirmationModal/index.cjs +1 -0
  22. package/dist/ConfirmationModal/index.mjs +1 -0
  23. package/dist/DataDump/index.cjs +3 -0
  24. package/dist/DataDump/index.mjs +3 -0
  25. package/dist/DataList/components/DataListActions/index.cjs +1 -0
  26. package/dist/DataList/components/DataListActions/index.mjs +1 -0
  27. package/dist/DataList/components/DataListBulkActions/index.cjs +1 -0
  28. package/dist/DataList/components/DataListBulkActions/index.mjs +1 -0
  29. package/dist/DataList/components/DataListFilters/components/DataListSort/index.cjs +1 -0
  30. package/dist/DataList/components/DataListFilters/components/DataListSort/index.mjs +1 -0
  31. package/dist/DataList/components/DataListFilters/index.cjs +1 -0
  32. package/dist/DataList/components/DataListFilters/index.mjs +1 -0
  33. package/dist/DataList/components/DataListHeader/index.cjs +1 -0
  34. package/dist/DataList/components/DataListHeader/index.mjs +1 -0
  35. package/dist/DataList/components/DataListItem/index.cjs +1 -0
  36. package/dist/DataList/components/DataListItem/index.mjs +1 -0
  37. package/dist/DataList/components/DataListItemActions/index.cjs +1 -0
  38. package/dist/DataList/components/DataListItemActions/index.mjs +1 -0
  39. package/dist/DataList/components/DataListItemActionsOverflow/index.cjs +1 -0
  40. package/dist/DataList/components/DataListItemActionsOverflow/index.mjs +1 -0
  41. package/dist/DataList/components/DataListItems/index.cjs +1 -0
  42. package/dist/DataList/components/DataListItems/index.mjs +1 -0
  43. package/dist/DataList/components/DataListLayout/index.cjs +1 -0
  44. package/dist/DataList/components/DataListLayout/index.mjs +1 -0
  45. package/dist/DataList/components/DataListLayoutActions/index.cjs +1 -0
  46. package/dist/DataList/components/DataListLayoutActions/index.mjs +1 -0
  47. package/dist/DataList/index.cjs +1 -0
  48. package/dist/DataList/index.mjs +1 -0
  49. package/dist/DatePicker/index.cjs +1 -0
  50. package/dist/DatePicker/index.mjs +1 -0
  51. package/dist/DrawerRoot-cjs.js +181 -968
  52. package/dist/DrawerRoot-es.js +5 -734
  53. package/dist/FormatFile/index.cjs +1 -0
  54. package/dist/FormatFile/index.mjs +1 -0
  55. package/dist/Gallery/index.cjs +1 -0
  56. package/dist/Gallery/index.mjs +1 -0
  57. package/dist/InputDate/index.cjs +1 -0
  58. package/dist/InputDate/index.mjs +1 -0
  59. package/dist/InputNumberExperimental-cjs.js +783 -0
  60. package/dist/InputNumberExperimental-es.js +763 -0
  61. package/dist/LightBox/index.cjs +1 -0
  62. package/dist/LightBox/index.mjs +1 -0
  63. package/dist/Menu/index.cjs +3 -0
  64. package/dist/Menu/index.mjs +3 -0
  65. package/dist/MenuSubmenuTrigger-cjs.js +202 -447
  66. package/dist/MenuSubmenuTrigger-es.js +7 -249
  67. package/dist/Modal/index.cjs +1 -0
  68. package/dist/Modal/index.mjs +1 -0
  69. package/dist/NumberFieldInput-cjs.js +1828 -0
  70. package/dist/NumberFieldInput-es.js +1788 -0
  71. package/dist/Page/index.cjs +3 -0
  72. package/dist/Page/index.mjs +3 -0
  73. package/dist/Popover/index.cjs +1 -0
  74. package/dist/Popover/index.mjs +1 -0
  75. package/dist/Tooltip/index.cjs +1 -0
  76. package/dist/Tooltip/index.mjs +1 -0
  77. package/dist/docs/Menu/Menu.md +197 -37
  78. package/dist/floating-ui.react-cjs.js +35 -34
  79. package/dist/floating-ui.react-dom-cjs.js +65 -64
  80. package/dist/floating-ui.react-dom-es.js +2 -1
  81. package/dist/floating-ui.react-es.js +2 -1
  82. package/dist/floating-ui.utils.dom-cjs.js +185 -0
  83. package/dist/floating-ui.utils.dom-es.js +165 -0
  84. package/dist/index.cjs +3 -0
  85. package/dist/index.esm-cjs.js +0 -183
  86. package/dist/index.esm-es.js +1 -165
  87. package/dist/index.mjs +3 -0
  88. package/dist/primitives/BottomSheet/index.cjs +3 -1
  89. package/dist/primitives/BottomSheet/index.mjs +3 -1
  90. package/dist/primitives/InputNumberExperimental/InputNumberExperimental.d.ts +20 -0
  91. package/dist/primitives/InputNumberExperimental/index.cjs +22 -0
  92. package/dist/primitives/InputNumberExperimental/index.d.ts +2 -0
  93. package/dist/primitives/InputNumberExperimental/index.mjs +16 -0
  94. package/dist/primitives/InputNumberExperimental/types.d.ts +147 -0
  95. package/dist/primitives/index.cjs +9 -1
  96. package/dist/primitives/index.d.ts +2 -0
  97. package/dist/primitives/index.mjs +8 -1
  98. package/dist/styles.css +499 -0
  99. package/dist/unstyledPrimitives/index.cjs +264 -2039
  100. package/dist/unstyledPrimitives/index.mjs +72 -1847
  101. package/dist/useBaseUiId-cjs.js +275 -0
  102. package/dist/useBaseUiId-es.js +251 -0
  103. package/dist/useValueChanged-cjs.js +820 -0
  104. package/dist/useValueChanged-es.js +736 -0
  105. package/package.json +2 -2
  106. package/rollup.config.mjs +13 -2
@@ -4,10 +4,14 @@ var DrawerRoot = require('../DrawerRoot-cjs.js');
4
4
  var MenuSubmenuTrigger = require('../MenuSubmenuTrigger-cjs.js');
5
5
  var React = require('react');
6
6
  var useRenderElement = require('../useRenderElement-cjs.js');
7
+ var useBaseUiId = require('../useBaseUiId-cjs.js');
8
+ var useValueChanged = require('../useValueChanged-cjs.js');
7
9
  var jsxRuntime = require('react/jsx-runtime');
8
- var index_esm = require('../index.esm-cjs.js');
10
+ var floatingUi_utils_dom = require('../floating-ui.utils.dom-cjs.js');
9
11
  var ReactDOM = require('react-dom');
12
+ var index_esm = require('../index.esm-cjs.js');
10
13
  var Separator = require('../Separator-cjs.js');
14
+ var NumberFieldInput = require('../NumberFieldInput-cjs.js');
11
15
  require('../floating-ui.react-dom-cjs.js');
12
16
 
13
17
  function _interopNamespaceDefault(e) {
@@ -46,7 +50,7 @@ const DialogDescription = /*#__PURE__*/React__namespace.forwardRef(function Dial
46
50
  const {
47
51
  store
48
52
  } = DrawerRoot.useDialogRootContext();
49
- const id = MenuSubmenuTrigger.useBaseUiId(idProp);
53
+ const id = useBaseUiId.useBaseUiId(idProp);
50
54
  store.useSyncedValueWithCleanup('descriptionElementId', id);
51
55
  return useRenderElement.useRenderElement('p', componentProps, {
52
56
  ref: forwardedRef,
@@ -65,7 +69,7 @@ if (process.env.NODE_ENV !== "production") DialogDescription.displayName = "Dial
65
69
  */
66
70
  const DrawerDescription = DialogDescription;
67
71
 
68
- const stateAttributesMapping$a = {
72
+ const stateAttributesMapping$8 = {
69
73
  active(value) {
70
74
  if (value) {
71
75
  return {
@@ -95,7 +99,7 @@ const DrawerIndent = /*#__PURE__*/React__namespace.forwardRef(function DrawerInd
95
99
  const active = providerContext?.active ?? false;
96
100
  const visualStateStore = providerContext?.visualStateStore;
97
101
  const indentRef = React__namespace.useRef(null);
98
- DrawerRoot.useIsoLayoutEffect(() => {
102
+ useValueChanged.useIsoLayoutEffect(() => {
99
103
  const element = indentRef.current;
100
104
  if (!element || !visualStateStore) {
101
105
  return undefined;
@@ -135,12 +139,12 @@ const DrawerIndent = /*#__PURE__*/React__namespace.forwardRef(function DrawerInd
135
139
  [DrawerRoot.DrawerBackdropCssVars.swipeProgress]: '0'
136
140
  }
137
141
  }, elementProps],
138
- stateAttributesMapping: stateAttributesMapping$a
142
+ stateAttributesMapping: stateAttributesMapping$8
139
143
  });
140
144
  });
141
145
  if (process.env.NODE_ENV !== "production") DrawerIndent.displayName = "DrawerIndent";
142
146
 
143
- const stateAttributesMapping$9 = {
147
+ const stateAttributesMapping$7 = {
144
148
  active(value) {
145
149
  if (value) {
146
150
  return {
@@ -174,28 +178,18 @@ const DrawerIndentBackground = /*#__PURE__*/React__namespace.forwardRef(function
174
178
  ref: forwardedRef,
175
179
  state,
176
180
  props: elementProps,
177
- stateAttributesMapping: stateAttributesMapping$9
181
+ stateAttributesMapping: stateAttributesMapping$7
178
182
  });
179
183
  });
180
184
  if (process.env.NODE_ENV !== "production") DrawerIndentBackground.displayName = "DrawerIndentBackground";
181
185
 
182
- /**
183
- * Returns a function that forces a rerender.
184
- */
185
- function useForcedRerendering() {
186
- const [, setState] = React__namespace.useState({});
187
- return React__namespace.useCallback(() => {
188
- setState({});
189
- }, []);
190
- }
191
-
192
186
  function DrawerProvider(props) {
193
187
  const {
194
188
  children
195
189
  } = props;
196
190
  const [openById, setOpenById] = React__namespace.useState(() => new Map());
197
191
  const [visualStateStore] = React__namespace.useState(createVisualStateStore);
198
- const setDrawerOpen = DrawerRoot.useStableCallback((drawerId, open) => {
192
+ const setDrawerOpen = useValueChanged.useStableCallback((drawerId, open) => {
199
193
  setOpenById(prev => {
200
194
  const prevOpen = prev.get(drawerId);
201
195
  if (prevOpen === open) {
@@ -206,7 +200,7 @@ function DrawerProvider(props) {
206
200
  return next;
207
201
  });
208
202
  });
209
- const removeDrawer = DrawerRoot.useStableCallback(drawerId => {
203
+ const removeDrawer = useValueChanged.useStableCallback(drawerId => {
210
204
  setOpenById(prev => {
211
205
  if (!prev.has(drawerId)) {
212
206
  return prev;
@@ -300,9 +294,9 @@ let DialogViewportDataAttributes = function (DialogViewportDataAttributes) {
300
294
  return DialogViewportDataAttributes;
301
295
  }({});
302
296
 
303
- const stateAttributesMapping$8 = {
297
+ const stateAttributesMapping$6 = {
304
298
  ...DrawerRoot.popupStateMapping,
305
- ...DrawerRoot.transitionStatusMapping,
299
+ ...useValueChanged.transitionStatusMapping,
306
300
  nested(value) {
307
301
  return value ? {
308
302
  [DialogViewportDataAttributes.nested]: ''
@@ -349,7 +343,7 @@ const DialogViewport = /*#__PURE__*/React__namespace.forwardRef(function DialogV
349
343
  enabled: shouldRender,
350
344
  state,
351
345
  ref: [forwardedRef, store.useStateSetter('viewportElement')],
352
- stateAttributesMapping: stateAttributesMapping$8,
346
+ stateAttributesMapping: stateAttributesMapping$6,
353
347
  props: [{
354
348
  role: 'presentation',
355
349
  hidden: !mounted,
@@ -390,7 +384,7 @@ class DialogHandle {
390
384
  console.warn(`Base UI: DialogHandle.open: No trigger found with id "${triggerId}". The dialog will open, but the trigger will not be associated with the dialog.`);
391
385
  }
392
386
  }
393
- this.store.setOpen(true, DrawerRoot.createChangeEventDetails(DrawerRoot.imperativeAction, undefined, triggerElement));
387
+ this.store.setOpen(true, useValueChanged.createChangeEventDetails(useValueChanged.imperativeAction, undefined, triggerElement));
394
388
  }
395
389
 
396
390
  /**
@@ -401,14 +395,14 @@ class DialogHandle {
401
395
  */
402
396
  openWithPayload(payload) {
403
397
  this.store.set('payload', payload);
404
- this.store.setOpen(true, DrawerRoot.createChangeEventDetails(DrawerRoot.imperativeAction, undefined, undefined));
398
+ this.store.setOpen(true, useValueChanged.createChangeEventDetails(useValueChanged.imperativeAction, undefined, undefined));
405
399
  }
406
400
 
407
401
  /**
408
402
  * Closes the dialog.
409
403
  */
410
404
  close() {
411
- this.store.setOpen(false, DrawerRoot.createChangeEventDetails(DrawerRoot.imperativeAction, undefined, undefined));
405
+ this.store.setOpen(false, useValueChanged.createChangeEventDetails(useValueChanged.imperativeAction, undefined, undefined));
412
406
  }
413
407
 
414
408
  /**
@@ -427,7 +421,7 @@ function createDialogHandle() {
427
421
  }
428
422
 
429
423
  function isScrollable(element, axis) {
430
- const style = index_esm.getComputedStyle(element);
424
+ const style = floatingUi_utils_dom.getComputedStyle(element);
431
425
  if (axis === 'vertical') {
432
426
  const overflowY = style.overflowY;
433
427
  return (overflowY === 'auto' || overflowY === 'scroll') && element.scrollHeight > element.clientHeight;
@@ -448,7 +442,7 @@ function hasScrollableAncestor(target, root, axes) {
448
442
  return false;
449
443
  }
450
444
  function findScrollableTouchTarget(target, root, axis = 'vertical') {
451
- let node = index_esm.isHTMLElement(target) ? target : null;
445
+ let node = floatingUi_utils_dom.isHTMLElement(target) ? target : null;
452
446
  while (node && node !== root) {
453
447
  if (isScrollable(node, axis)) {
454
448
  return node;
@@ -620,7 +614,7 @@ function useSwipeDismiss(options) {
620
614
  });
621
615
  const lastProgressDetailsRef = React__namespace.useRef(null);
622
616
  const isSwipingRef = React__namespace.useRef(false);
623
- const setSwiping = DrawerRoot.useStableCallback(nextSwiping => {
617
+ const setSwiping = useValueChanged.useStableCallback(nextSwiping => {
624
618
  if (isSwipingRef.current === nextSwiping) {
625
619
  return;
626
620
  }
@@ -646,8 +640,8 @@ function useSwipeDismiss(options) {
646
640
  });
647
641
  swipeThresholdRef.current = Math.max(0, value);
648
642
  }
649
- const updateSwipeProgress = DrawerRoot.useStableCallback((progress, details) => {
650
- const nextProgress = Number.isFinite(progress) ? DrawerRoot.clamp(progress, 0, 1) : 0;
643
+ const updateSwipeProgress = useValueChanged.useStableCallback((progress, details) => {
644
+ const nextProgress = Number.isFinite(progress) ? useValueChanged.clamp(progress, 0, 1) : 0;
651
645
  const progressChanged = nextProgress !== swipeProgressRef.current;
652
646
  let detailsChanged = false;
653
647
  if (details) {
@@ -763,7 +757,7 @@ function useSwipeDismiss(options) {
763
757
  return event.pointerType === 'touch';
764
758
  }
765
759
  function getTargetAtPoint(position, nativeEvent) {
766
- const doc = DrawerRoot.ownerDocument(elementRef.current);
760
+ const doc = useValueChanged.ownerDocument(elementRef.current);
767
761
  const elementAtPoint = getElementAtPoint(doc, position.x, position.y);
768
762
  const target = elementAtPoint ?? DrawerRoot.getTarget(nativeEvent);
769
763
  return target;
@@ -781,7 +775,7 @@ function useSwipeDismiss(options) {
781
775
  swipeFromScrollableRef.current = false;
782
776
  const touchLike = isTouchLikeEvent(event);
783
777
  const target = getTargetAtPoint(position, event.nativeEvent);
784
- const doc = DrawerRoot.ownerDocument(elementRef.current);
778
+ const doc = useValueChanged.ownerDocument(elementRef.current);
785
779
  const body = doc.body;
786
780
  const scrollableTarget = touchLike && body ? findGestureScrollableTouchTarget(target, body) : null;
787
781
  const ignoreScrollableTarget = startOptions?.ignoreScrollableTarget ?? false;
@@ -923,7 +917,7 @@ function useSwipeDismiss(options) {
923
917
  }
924
918
  return null;
925
919
  }
926
- const handleStart = DrawerRoot.useStableCallback(event => {
920
+ const handleStart = useValueChanged.useStableCallback(event => {
927
921
  if (!enabled) {
928
922
  return;
929
923
  }
@@ -1119,7 +1113,7 @@ function useSwipeDismiss(options) {
1119
1113
  direction: swipeDirectionDetails
1120
1114
  });
1121
1115
  }
1122
- const handleMove = DrawerRoot.useStableCallback(event => {
1116
+ const handleMove = useValueChanged.useStableCallback(event => {
1123
1117
  const currentPos = getPrimaryPointerPosition(event);
1124
1118
  if (!currentPos) {
1125
1119
  return;
@@ -1154,7 +1148,7 @@ function useSwipeDismiss(options) {
1154
1148
  const element = elementRef.current;
1155
1149
  if (pendingStartPos && element) {
1156
1150
  const target = getTargetAtPoint(currentPos, event.nativeEvent);
1157
- const doc = DrawerRoot.ownerDocument(element);
1151
+ const doc = useValueChanged.ownerDocument(element);
1158
1152
  const body = doc.body;
1159
1153
  const scrollTarget = body ? findGestureScrollableTouchTarget(target, body) : null;
1160
1154
  if (scrollTarget && (DrawerRoot.contains(element, scrollTarget) || DrawerRoot.contains(scrollTarget, element))) {
@@ -1204,7 +1198,7 @@ function useSwipeDismiss(options) {
1204
1198
  lastMovePosRef.current = currentPos;
1205
1199
  handleMoveCore(event, currentPos, movement);
1206
1200
  });
1207
- const handleEnd = DrawerRoot.useStableCallback(event => {
1201
+ const handleEnd = useValueChanged.useStableCallback(event => {
1208
1202
  if (!enabled) {
1209
1203
  return;
1210
1204
  }
@@ -1438,7 +1432,7 @@ const SWIPE_AREA_SWIPING_HOOK = {
1438
1432
  const SWIPE_AREA_DISABLED_HOOK = {
1439
1433
  [DrawerSwipeAreaDataAttributes.disabled]: ''
1440
1434
  };
1441
- const stateAttributesMapping$7 = {
1435
+ const stateAttributesMapping$5 = {
1442
1436
  open(value) {
1443
1437
  return value ? SWIPE_AREA_OPEN_HOOK : SWIPE_AREA_CLOSED_HOOK;
1444
1438
  },
@@ -1487,7 +1481,7 @@ const DrawerSwipeArea = /*#__PURE__*/React__namespace.forwardRef(function Drawer
1487
1481
  } = DrawerRoot.useDrawerRootContext();
1488
1482
  const providerContext = DrawerRoot.useDrawerProviderContext();
1489
1483
  const [swipeActive, setSwipeActive] = React__namespace.useState(false);
1490
- const releaseDismissTimeout = DrawerRoot.useTimeout();
1484
+ const releaseDismissTimeout = useValueChanged.useTimeout();
1491
1485
  const swipeAreaRef = React__namespace.useRef(null);
1492
1486
  const swipeStartEventRef = React__namespace.useRef(null);
1493
1487
  const openedBySwipeRef = React__namespace.useRef(false);
@@ -1498,13 +1492,13 @@ const DrawerSwipeArea = /*#__PURE__*/React__namespace.forwardRef(function Drawer
1498
1492
  const closedOffsetRef = React__namespace.useRef(null);
1499
1493
  const appliedSwipeStylesRef = React__namespace.useRef(false);
1500
1494
  const popupTransitionRef = React__namespace.useRef(null);
1501
- const swipeAreaId = MenuSubmenuTrigger.useBaseUiId(componentProps.id);
1495
+ const swipeAreaId = useBaseUiId.useBaseUiId(componentProps.id);
1502
1496
  const registerTrigger = DrawerRoot.useTriggerRegistration(swipeAreaId, store);
1503
1497
  const open = store.useState('open');
1504
1498
  const resolvedSwipeDirection = swipeDirectionProp ?? oppositeSwipeDirection[swipeDirection];
1505
1499
  const dismissDirection = oppositeSwipeDirection[resolvedSwipeDirection];
1506
1500
  const enabled = !disabled && (!open || swipeActive);
1507
- const resetDragDelta = DrawerRoot.useStableCallback(() => {
1501
+ const resetDragDelta = useValueChanged.useStableCallback(() => {
1508
1502
  dragDeltaRef.current.x = 0;
1509
1503
  dragDeltaRef.current.y = 0;
1510
1504
  });
@@ -1611,7 +1605,7 @@ const DrawerSwipeArea = /*#__PURE__*/React__namespace.forwardRef(function Drawer
1611
1605
  });
1612
1606
  appliedSwipeStylesRef.current = true;
1613
1607
  }
1614
- const clearSwipeStyles = DrawerRoot.useStableCallback(() => {
1608
+ const clearSwipeStyles = useValueChanged.useStableCallback(() => {
1615
1609
  const popupElement = store.context.popupRef.current;
1616
1610
  if (popupElement && appliedSwipeStylesRef.current) {
1617
1611
  popupElement.style.removeProperty(DrawerRoot.DrawerPopupCssVars.swipeMovementX);
@@ -1639,13 +1633,13 @@ const DrawerSwipeArea = /*#__PURE__*/React__namespace.forwardRef(function Drawer
1639
1633
  return;
1640
1634
  }
1641
1635
  openedBySwipeRef.current = true;
1642
- store.setOpen(true, DrawerRoot.createChangeEventDetails(DrawerRoot.swipe, event, swipeAreaRef.current ?? undefined));
1636
+ store.setOpen(true, useValueChanged.createChangeEventDetails(useValueChanged.swipe, event, swipeAreaRef.current ?? undefined));
1643
1637
  }
1644
1638
  function closeDrawer(event) {
1645
1639
  if (!store.select('open')) {
1646
1640
  return;
1647
1641
  }
1648
- store.setOpen(false, DrawerRoot.createChangeEventDetails(DrawerRoot.swipe, event, swipeAreaRef.current ?? undefined));
1642
+ store.setOpen(false, useValueChanged.createChangeEventDetails(useValueChanged.swipe, event, swipeAreaRef.current ?? undefined));
1649
1643
  }
1650
1644
  const swipe = useSwipeDismiss({
1651
1645
  enabled,
@@ -1743,7 +1737,7 @@ const DrawerSwipeArea = /*#__PURE__*/React__namespace.forwardRef(function Drawer
1743
1737
  return useRenderElement.useRenderElement('div', componentProps, {
1744
1738
  state,
1745
1739
  ref: [forwardedRef, swipeAreaRef, registerTrigger],
1746
- stateAttributesMapping: stateAttributesMapping$7,
1740
+ stateAttributesMapping: stateAttributesMapping$5,
1747
1741
  props: [{
1748
1742
  role: 'presentation',
1749
1743
  'aria-hidden': true,
@@ -1844,7 +1838,7 @@ const DrawerViewport = /*#__PURE__*/React__namespace.forwardRef(function DrawerV
1844
1838
  const [swipeRelease, setSwipeRelease] = React__namespace.useState(null);
1845
1839
  const pendingSwipeCloseSnapPointRef = React__namespace.useRef(undefined);
1846
1840
  const resetSwipeRef = React__namespace.useRef(null);
1847
- const controlledDismissFrame = DrawerRoot.useAnimationFrame();
1841
+ const controlledDismissFrame = useValueChanged.useAnimationFrame();
1848
1842
  const nestedSwipeActiveRef = React__namespace.useRef(false);
1849
1843
  const lastPointerTypeRef = React__namespace.useRef('');
1850
1844
  const ignoreNextTouchStartFromPenRef = React__namespace.useRef(false);
@@ -1884,7 +1878,7 @@ const DrawerViewport = /*#__PURE__*/React__namespace.forwardRef(function DrawerV
1884
1878
  if (!snapPointRange || activeSnapPointOffset === null) {
1885
1879
  return null;
1886
1880
  }
1887
- return DrawerRoot.clamp((activeSnapPointOffset - snapPointRange.minOffset) / snapPointRange.range, 0, 1);
1881
+ return useValueChanged.clamp((activeSnapPointOffset - snapPointRange.minOffset) / snapPointRange.range, 0, 1);
1888
1882
  }, [activeSnapPointOffset, snapPointRange]);
1889
1883
  const swipeDirections = React__namespace.useMemo(() => {
1890
1884
  if (snapPoints && snapPoints.length > 0 && (swipeDirection === 'down' || swipeDirection === 'up')) {
@@ -1892,15 +1886,15 @@ const DrawerViewport = /*#__PURE__*/React__namespace.forwardRef(function DrawerV
1892
1886
  }
1893
1887
  return [swipeDirection];
1894
1888
  }, [snapPoints, swipeDirection]);
1895
- const setSwipeDismissed = DrawerRoot.useStableCallback(dismissed => {
1889
+ const setSwipeDismissed = useValueChanged.useStableCallback(dismissed => {
1896
1890
  setSwipeDismissedElements(store.context.popupRef.current, store.context.backdropRef.current, dismissed);
1897
1891
  });
1898
- const clearSwipeRelease = DrawerRoot.useStableCallback(() => {
1892
+ const clearSwipeRelease = useValueChanged.useStableCallback(() => {
1899
1893
  setSwipeDismissed(false);
1900
- store.context.popupRef.current?.removeAttribute(DrawerRoot.TransitionStatusDataAttributes.endingStyle);
1894
+ store.context.popupRef.current?.removeAttribute(useValueChanged.TransitionStatusDataAttributes.endingStyle);
1901
1895
  setSwipeRelease(null);
1902
1896
  });
1903
- const applySwipeProgress = DrawerRoot.useStableCallback(({
1897
+ const applySwipeProgress = useValueChanged.useStableCallback(({
1904
1898
  resolvedProgress,
1905
1899
  shouldTrackProgress,
1906
1900
  notifyParent
@@ -1972,13 +1966,13 @@ const DrawerViewport = /*#__PURE__*/React__namespace.forwardRef(function DrawerV
1972
1966
  if (!Number.isFinite(directionalVelocity) || directionalVelocity <= MIN_SWIPE_RELEASE_VELOCITY) {
1973
1967
  return null;
1974
1968
  }
1975
- const clampedVelocity = DrawerRoot.clamp(directionalVelocity, MIN_SWIPE_RELEASE_VELOCITY, MAX_SWIPE_RELEASE_VELOCITY);
1976
- const durationMs = DrawerRoot.clamp(remainingDistance / clampedVelocity, MIN_SWIPE_RELEASE_DURATION_MS, MAX_SWIPE_RELEASE_DURATION_MS);
1969
+ const clampedVelocity = useValueChanged.clamp(directionalVelocity, MIN_SWIPE_RELEASE_VELOCITY, MAX_SWIPE_RELEASE_VELOCITY);
1970
+ const durationMs = useValueChanged.clamp(remainingDistance / clampedVelocity, MIN_SWIPE_RELEASE_DURATION_MS, MAX_SWIPE_RELEASE_DURATION_MS);
1977
1971
  if (!Number.isFinite(durationMs)) {
1978
1972
  return null;
1979
1973
  }
1980
1974
  const normalizedDuration = (durationMs - MIN_SWIPE_RELEASE_DURATION_MS) / (MAX_SWIPE_RELEASE_DURATION_MS - MIN_SWIPE_RELEASE_DURATION_MS);
1981
- const durationScalar = DrawerRoot.clamp(MIN_SWIPE_RELEASE_SCALAR + normalizedDuration * (MAX_SWIPE_RELEASE_SCALAR - MIN_SWIPE_RELEASE_SCALAR), MIN_SWIPE_RELEASE_SCALAR, MAX_SWIPE_RELEASE_SCALAR);
1975
+ const durationScalar = useValueChanged.clamp(MIN_SWIPE_RELEASE_SCALAR + normalizedDuration * (MAX_SWIPE_RELEASE_SCALAR - MIN_SWIPE_RELEASE_SCALAR), MIN_SWIPE_RELEASE_SCALAR, MAX_SWIPE_RELEASE_SCALAR);
1982
1976
  if (!Number.isFinite(durationScalar) || durationScalar <= 0) {
1983
1977
  return null;
1984
1978
  }
@@ -2014,13 +2008,13 @@ const DrawerViewport = /*#__PURE__*/React__namespace.forwardRef(function DrawerV
2014
2008
  if (!popupElement) {
2015
2009
  return;
2016
2010
  }
2017
- const doc = DrawerRoot.ownerDocument(popupElement);
2011
+ const doc = useValueChanged.ownerDocument(popupElement);
2018
2012
  const selection = doc.getSelection?.();
2019
2013
  if (!selection || selection.isCollapsed) {
2020
2014
  return;
2021
2015
  }
2022
- const anchorElement = index_esm.isElement(selection.anchorNode) ? selection.anchorNode : selection.anchorNode?.parentElement;
2023
- const focusElement = index_esm.isElement(selection.focusNode) ? selection.focusNode : selection.focusNode?.parentElement;
2016
+ const anchorElement = floatingUi_utils_dom.isElement(selection.anchorNode) ? selection.anchorNode : selection.anchorNode?.parentElement;
2017
+ const focusElement = floatingUi_utils_dom.isElement(selection.focusNode) ? selection.focusNode : selection.focusNode?.parentElement;
2024
2018
  if (!DrawerRoot.contains(popupElement, anchorElement) && !DrawerRoot.contains(popupElement, focusElement)) {
2025
2019
  return;
2026
2020
  }
@@ -2070,15 +2064,15 @@ const DrawerViewport = /*#__PURE__*/React__namespace.forwardRef(function DrawerV
2070
2064
  if (snapPointRange && popupHeight > 0) {
2071
2065
  if (details && Number.isFinite(details.deltaY)) {
2072
2066
  const baseOffset = activeSnapPointOffset ?? snapPointRange.minOffset;
2073
- const nextOffset = DrawerRoot.clamp(baseOffset + details.deltaY, 0, popupHeight);
2074
- resolvedProgress = DrawerRoot.clamp((nextOffset - snapPointRange.minOffset) / snapPointRange.range, 0, 1);
2067
+ const nextOffset = useValueChanged.clamp(baseOffset + details.deltaY, 0, popupHeight);
2068
+ resolvedProgress = useValueChanged.clamp((nextOffset - snapPointRange.minOffset) / snapPointRange.range, 0, 1);
2075
2069
  } else if (snapPointProgress !== null) {
2076
2070
  resolvedProgress = snapPointProgress;
2077
2071
  } else if (currentDirection === 'down' || currentDirection === 'up') {
2078
2072
  const displacement = progress * popupHeight;
2079
2073
  const baseOffset = activeSnapPointOffset ?? snapPointRange.minOffset;
2080
2074
  const nextOffset = currentDirection === 'down' ? baseOffset + displacement : baseOffset - displacement;
2081
- resolvedProgress = DrawerRoot.clamp((nextOffset - snapPointRange.minOffset) / snapPointRange.range, 0, 1);
2075
+ resolvedProgress = useValueChanged.clamp((nextOffset - snapPointRange.minOffset) / snapPointRange.range, 0, 1);
2082
2076
  }
2083
2077
  }
2084
2078
  applySwipeProgress({
@@ -2115,7 +2109,7 @@ const DrawerViewport = /*#__PURE__*/React__namespace.forwardRef(function DrawerV
2115
2109
  notifyParentSwipingChange?.(false);
2116
2110
  setSwipeDismissed(true);
2117
2111
  popupElement.style.removeProperty('transition');
2118
- popupElement.setAttribute(DrawerRoot.TransitionStatusDataAttributes.endingStyle, '');
2112
+ popupElement.setAttribute(useValueChanged.TransitionStatusDataAttributes.endingStyle, '');
2119
2113
  ReactDOM__namespace.flushSync(() => {
2120
2114
  setSwipeRelease(resolveSwipeRelease({
2121
2115
  direction: resolvedDirection,
@@ -2183,10 +2177,10 @@ const DrawerViewport = /*#__PURE__*/React__namespace.forwardRef(function DrawerV
2183
2177
  }
2184
2178
  }
2185
2179
  const currentOffset = activeSnapPointOffset ?? 0;
2186
- const dragTargetOffset = DrawerRoot.clamp(currentOffset + dragDelta, 0, popupHeight);
2187
- const velocityOffset = Number.isFinite(resolvedDirectionalVelocity) && Math.abs(resolvedDirectionalVelocity) >= SNAP_VELOCITY_THRESHOLD ? DrawerRoot.clamp(resolvedDirectionalVelocity, -MAX_SNAP_VELOCITY, MAX_SNAP_VELOCITY) * SNAP_VELOCITY_MULTIPLIER : 0;
2188
- const targetOffset = snapToSequentialPoints ? dragTargetOffset : DrawerRoot.clamp(dragTargetOffset + velocityOffset, 0, popupHeight);
2189
- const snapPointEventDetails = DrawerRoot.createChangeEventDetails(DrawerRoot.swipe, event);
2180
+ const dragTargetOffset = useValueChanged.clamp(currentOffset + dragDelta, 0, popupHeight);
2181
+ const velocityOffset = Number.isFinite(resolvedDirectionalVelocity) && Math.abs(resolvedDirectionalVelocity) >= SNAP_VELOCITY_THRESHOLD ? useValueChanged.clamp(resolvedDirectionalVelocity, -MAX_SNAP_VELOCITY, MAX_SNAP_VELOCITY) * SNAP_VELOCITY_MULTIPLIER : 0;
2182
+ const targetOffset = snapToSequentialPoints ? dragTargetOffset : useValueChanged.clamp(dragTargetOffset + velocityOffset, 0, popupHeight);
2183
+ const snapPointEventDetails = useValueChanged.createChangeEventDetails(useValueChanged.swipe, event);
2190
2184
  const closeFromSnapPoints = () => {
2191
2185
  pendingSwipeCloseSnapPointRef.current = activeSnapPoint;
2192
2186
  setActiveSnapPoint?.(null, snapPointEventDetails);
@@ -2221,7 +2215,7 @@ const DrawerViewport = /*#__PURE__*/React__namespace.forwardRef(function DrawerV
2221
2215
  const shouldAdvance = dragDirection !== 0 && velocityDirection !== 0 && velocityDirection === dragDirection && Math.abs(resolvedDirectionalVelocity) >= SNAP_VELOCITY_THRESHOLD;
2222
2216
  let effectiveTargetOffset = targetOffset;
2223
2217
  if (shouldAdvance) {
2224
- const adjacentIndex = DrawerRoot.clamp(currentIndex + dragDirection, 0, orderedSnapPoints.length - 1);
2218
+ const adjacentIndex = useValueChanged.clamp(currentIndex + dragDirection, 0, orderedSnapPoints.length - 1);
2225
2219
  if (adjacentIndex !== currentIndex) {
2226
2220
  const adjacentPoint = orderedSnapPoints[adjacentIndex];
2227
2221
  const shouldForceAdjacent = dragDirection > 0 ? targetOffset < adjacentPoint.offset : targetOffset > adjacentPoint.offset;
@@ -2274,12 +2268,12 @@ const DrawerViewport = /*#__PURE__*/React__namespace.forwardRef(function DrawerV
2274
2268
  backdropElement.style.setProperty(DrawerRoot.DrawerBackdropCssVars.swipeProgress, '0');
2275
2269
  backdropElement.style.removeProperty(DrawerRoot.DrawerPopupCssVars.height);
2276
2270
  }
2277
- const dismissEventDetails = DrawerRoot.createChangeEventDetails(DrawerRoot.swipe, event);
2271
+ const dismissEventDetails = useValueChanged.createChangeEventDetails(useValueChanged.swipe, event);
2278
2272
  store.setOpen(false, dismissEventDetails);
2279
2273
  if (dismissEventDetails.isCanceled) {
2280
2274
  const pendingSnapPoint = pendingSwipeCloseSnapPointRef.current;
2281
2275
  if (pendingSnapPoint !== undefined) {
2282
- setActiveSnapPoint?.(pendingSnapPoint, DrawerRoot.createChangeEventDetails(DrawerRoot.swipe, event));
2276
+ setActiveSnapPoint?.(pendingSnapPoint, useValueChanged.createChangeEventDetails(useValueChanged.swipe, event));
2283
2277
  }
2284
2278
  pendingSwipeCloseSnapPointRef.current = undefined;
2285
2279
  resetSwipeRef.current?.();
@@ -2301,7 +2295,7 @@ const DrawerViewport = /*#__PURE__*/React__namespace.forwardRef(function DrawerV
2301
2295
  // Parent rejected: revert animation and restore snap point.
2302
2296
  const pendingSnapPoint = pendingSwipeCloseSnapPointRef.current;
2303
2297
  if (pendingSnapPoint !== undefined) {
2304
- setActiveSnapPoint?.(pendingSnapPoint, DrawerRoot.createChangeEventDetails(DrawerRoot.swipe, savedEvent));
2298
+ setActiveSnapPoint?.(pendingSnapPoint, useValueChanged.createChangeEventDetails(useValueChanged.swipe, savedEvent));
2305
2299
  }
2306
2300
  pendingSwipeCloseSnapPointRef.current = undefined;
2307
2301
  clearSwipeRelease();
@@ -2327,8 +2321,8 @@ const DrawerViewport = /*#__PURE__*/React__namespace.forwardRef(function DrawerV
2327
2321
  return undefined;
2328
2322
  }
2329
2323
  const resolvedRootElement = rootElement;
2330
- const doc = DrawerRoot.ownerDocument(resolvedRootElement);
2331
- const win = index_esm.getWindow(doc);
2324
+ const doc = useValueChanged.ownerDocument(resolvedRootElement);
2325
+ const win = floatingUi_utils_dom.getWindow(doc);
2332
2326
  function handleNativeTouchMove(event) {
2333
2327
  if (ignoreTouchSwipeRef.current) {
2334
2328
  return;
@@ -2470,7 +2464,7 @@ const DrawerViewport = /*#__PURE__*/React__namespace.forwardRef(function DrawerV
2470
2464
  if (!open || !mounted || nestedDrawerOpen) {
2471
2465
  return;
2472
2466
  }
2473
- const doc = DrawerRoot.ownerDocument(event.currentTarget);
2467
+ const doc = useValueChanged.ownerDocument(event.currentTarget);
2474
2468
  const elementAtPoint = getElementAtPoint(doc, event.clientX, event.clientY);
2475
2469
  if (isSwipeIgnoredTarget(elementAtPoint) || isDrawerContentTarget(elementAtPoint)) {
2476
2470
  return;
@@ -2526,7 +2520,7 @@ const DrawerViewport = /*#__PURE__*/React__namespace.forwardRef(function DrawerV
2526
2520
  touchScrollStateRef.current = null;
2527
2521
  return;
2528
2522
  }
2529
- const doc = DrawerRoot.ownerDocument(event.currentTarget);
2523
+ const doc = useValueChanged.ownerDocument(event.currentTarget);
2530
2524
  const elementAtPoint = getElementAtPoint(doc, touch.clientX, touch.clientY);
2531
2525
  ignoreTouchSwipeRef.current = isSwipeIgnoredTarget(elementAtPoint);
2532
2526
  if (ignoreTouchSwipeRef.current) {
@@ -2534,7 +2528,7 @@ const DrawerViewport = /*#__PURE__*/React__namespace.forwardRef(function DrawerV
2534
2528
  return;
2535
2529
  }
2536
2530
  const rootElement = viewportElement ?? popupElementState;
2537
- const target = index_esm.isElement(event.target) ? event.target : null;
2531
+ const target = floatingUi_utils_dom.isElement(event.target) ? event.target : null;
2538
2532
  let scrollTarget = null;
2539
2533
  let hasCrossAxisScrollableContent = false;
2540
2534
  if (rootElement && target && DrawerRoot.contains(rootElement, target)) {
@@ -2626,14 +2620,14 @@ function isRangeInput(target, win) {
2626
2620
  return target instanceof win.HTMLInputElement && target.type === 'range';
2627
2621
  }
2628
2622
  function isTextSelectionControl(target) {
2629
- if (!index_esm.isElement(target)) {
2623
+ if (!floatingUi_utils_dom.isElement(target)) {
2630
2624
  return false;
2631
2625
  }
2632
2626
  return target.tagName === 'INPUT' || target.tagName === 'TEXTAREA';
2633
2627
  }
2634
2628
  function hasExpandedSelectionWithinTarget(selection, target) {
2635
- const anchorElement = index_esm.isElement(selection.anchorNode) ? selection.anchorNode : selection.anchorNode?.parentElement;
2636
- const focusElement = index_esm.isElement(selection.focusNode) ? selection.focusNode : selection.focusNode?.parentElement;
2629
+ const anchorElement = floatingUi_utils_dom.isElement(selection.anchorNode) ? selection.anchorNode : selection.anchorNode?.parentElement;
2630
+ const focusElement = floatingUi_utils_dom.isElement(selection.focusNode) ? selection.focusNode : selection.focusNode?.parentElement;
2637
2631
  return selection.containsNode(target, true) || DrawerRoot.contains(target, anchorElement) || DrawerRoot.contains(target, focusElement);
2638
2632
  }
2639
2633
  function shouldIgnoreSwipeForTextSelection(doc, rootElement) {
@@ -2662,7 +2656,7 @@ function isEventOnRangeInput(event, win) {
2662
2656
  return isRangeInput(event.target, win);
2663
2657
  }
2664
2658
  function isReactTouchEventOnRangeInput(event) {
2665
- return isEventOnRangeInput(event.nativeEvent, index_esm.getWindow(event.currentTarget));
2659
+ return isEventOnRangeInput(event.nativeEvent, floatingUi_utils_dom.getWindow(event.currentTarget));
2666
2660
  }
2667
2661
  function updateTouchScrollPosition(touchState, touch) {
2668
2662
  touchState.lastX = touch.clientX;
@@ -2809,9 +2803,9 @@ const MenuArrow = /*#__PURE__*/React__namespace.forwardRef(function MenuArrow(co
2809
2803
  });
2810
2804
  if (process.env.NODE_ENV !== "production") MenuArrow.displayName = "MenuArrow";
2811
2805
 
2812
- const stateAttributesMapping$6 = {
2806
+ const stateAttributesMapping$4 = {
2813
2807
  ...DrawerRoot.popupStateMapping,
2814
- ...DrawerRoot.transitionStatusMapping
2808
+ ...useValueChanged.transitionStatusMapping
2815
2809
  };
2816
2810
 
2817
2811
  /**
@@ -2841,12 +2835,12 @@ const MenuBackdrop = /*#__PURE__*/React__namespace.forwardRef(function MenuBackd
2841
2835
  return useRenderElement.useRenderElement('div', componentProps, {
2842
2836
  ref: contextMenuContext?.backdropRef ? [forwardedRef, contextMenuContext.backdropRef] : forwardedRef,
2843
2837
  state,
2844
- stateAttributesMapping: stateAttributesMapping$6,
2838
+ stateAttributesMapping: stateAttributesMapping$4,
2845
2839
  props: [{
2846
2840
  role: 'presentation',
2847
2841
  hidden: !mounted,
2848
2842
  style: {
2849
- pointerEvents: lastOpenChangeReason === DrawerRoot.triggerHover ? 'none' : undefined,
2843
+ pointerEvents: lastOpenChangeReason === useValueChanged.triggerHover ? 'none' : undefined,
2850
2844
  userSelect: 'none',
2851
2845
  WebkitUserSelect: 'none'
2852
2846
  }
@@ -2889,13 +2883,13 @@ const MenuCheckboxItem = /*#__PURE__*/React__namespace.forwardRef(function MenuC
2889
2883
  label
2890
2884
  });
2891
2885
  const menuPositionerContext = MenuSubmenuTrigger.useMenuPositionerContext(true);
2892
- const id = MenuSubmenuTrigger.useBaseUiId(idProp);
2886
+ const id = useBaseUiId.useBaseUiId(idProp);
2893
2887
  const {
2894
2888
  store
2895
2889
  } = MenuSubmenuTrigger.useMenuRootContext();
2896
2890
  const highlighted = store.useState('isActive', listItem.index);
2897
2891
  const itemProps = store.useState('itemProps');
2898
- const [checked, setChecked] = DrawerRoot.useControlled({
2892
+ const [checked, setChecked] = useValueChanged.useControlled({
2899
2893
  controlled: checkedProp,
2900
2894
  default: defaultChecked ?? false,
2901
2895
  name: 'MenuCheckboxItem',
@@ -2919,9 +2913,9 @@ const MenuCheckboxItem = /*#__PURE__*/React__namespace.forwardRef(function MenuC
2919
2913
  highlighted,
2920
2914
  checked
2921
2915
  }), [disabled, highlighted, checked]);
2922
- const handleClick = DrawerRoot.useStableCallback(event => {
2916
+ const handleClick = useValueChanged.useStableCallback(event => {
2923
2917
  const details = {
2924
- ...DrawerRoot.createChangeEventDetails(DrawerRoot.itemPress, event.nativeEvent),
2918
+ ...useValueChanged.createChangeEventDetails(useValueChanged.itemPress, event.nativeEvent),
2925
2919
  preventUnmountOnClose: () => {}
2926
2920
  };
2927
2921
  onCheckedChange?.(!checked, details);
@@ -2965,8 +2959,8 @@ const MenuCheckboxItemIndicator = /*#__PURE__*/React__namespace.forwardRef(funct
2965
2959
  const {
2966
2960
  transitionStatus,
2967
2961
  setMounted
2968
- } = DrawerRoot.useTransitionStatus(item.checked);
2969
- DrawerRoot.useOpenChangeComplete({
2962
+ } = useValueChanged.useTransitionStatus(item.checked);
2963
+ useValueChanged.useOpenChangeComplete({
2970
2964
  open: item.checked,
2971
2965
  ref: indicatorRef,
2972
2966
  onComplete() {
@@ -3015,12 +3009,12 @@ function usePreviousValue(value) {
3015
3009
  }
3016
3010
 
3017
3011
  function getCssDimensions(element) {
3018
- const css = index_esm.getComputedStyle(element);
3012
+ const css = floatingUi_utils_dom.getComputedStyle(element);
3019
3013
  // In testing environments, the `width` and `height` properties are empty
3020
3014
  // strings for SVG elements, returning NaN. Fallback to `0` in this case.
3021
3015
  let width = parseFloat(css.width) || 0;
3022
3016
  let height = parseFloat(css.height) || 0;
3023
- const hasOffset = index_esm.isHTMLElement(element);
3017
+ const hasOffset = floatingUi_utils_dom.isHTMLElement(element);
3024
3018
  const offsetWidth = hasOffset ? element.offsetWidth : width;
3025
3019
  const offsetHeight = hasOffset ? element.offsetHeight : height;
3026
3020
  const shouldFallback = index_esm.round(width) !== offsetWidth || index_esm.round(height) !== offsetHeight;
@@ -3051,14 +3045,14 @@ function usePopupAutoResize(parameters) {
3051
3045
  side,
3052
3046
  direction
3053
3047
  } = parameters;
3054
- const runOnceAnimationsFinish = DrawerRoot.useAnimationsFinished(popupElement, true, false);
3055
- const animationFrame = DrawerRoot.useAnimationFrame();
3048
+ const runOnceAnimationsFinish = useValueChanged.useAnimationsFinished(popupElement, true, false);
3049
+ const animationFrame = useValueChanged.useAnimationFrame();
3056
3050
  const committedDimensionsRef = React__namespace.useRef(null);
3057
3051
  const liveDimensionsRef = React__namespace.useRef(null);
3058
3052
  const isInitialRenderRef = React__namespace.useRef(true);
3059
3053
  const restoreAnchoringStylesRef = React__namespace.useRef(useRenderElement.NOOP);
3060
- const onMeasureLayout = DrawerRoot.useStableCallback(onMeasureLayoutParam);
3061
- const onMeasureLayoutComplete = DrawerRoot.useStableCallback(onMeasureLayoutCompleteParam);
3054
+ const onMeasureLayout = useValueChanged.useStableCallback(onMeasureLayoutParam);
3055
+ const onMeasureLayoutComplete = useValueChanged.useStableCallback(onMeasureLayoutCompleteParam);
3062
3056
  const anchoringStyles = React__namespace.useMemo(() => {
3063
3057
  // Ensure popup size transitions correctly when anchored to `bottom` (side=top) or `right` (side=left).
3064
3058
  let isOriginSide = side === 'top';
@@ -3076,7 +3070,7 @@ function usePopupAutoResize(parameters) {
3076
3070
  [isPhysicalLeft ? 'right' : 'left']: '0'
3077
3071
  } : useRenderElement.EMPTY_OBJECT;
3078
3072
  }, [side, direction]);
3079
- DrawerRoot.useIsoLayoutEffect(() => {
3073
+ useValueChanged.useIsoLayoutEffect(() => {
3080
3074
  // Reset the state when the popup is closed.
3081
3075
  if (!mounted || !enabled() || typeof ResizeObserver !== 'function') {
3082
3076
  restoreAnchoringStylesRef.current = useRenderElement.NOOP;
@@ -3234,22 +3228,22 @@ function usePopupViewport(parameters) {
3234
3228
  const [newTriggerOffset, setNewTriggerOffset] = React__namespace.useState(null);
3235
3229
  const currentContainerRef = React__namespace.useRef(null);
3236
3230
  const previousContainerRef = React__namespace.useRef(null);
3237
- const onAnimationsFinished = DrawerRoot.useAnimationsFinished(currentContainerRef, true, false);
3238
- const cleanupFrame = DrawerRoot.useAnimationFrame();
3231
+ const onAnimationsFinished = useValueChanged.useAnimationsFinished(currentContainerRef, true, false);
3232
+ const cleanupFrame = useValueChanged.useAnimationFrame();
3239
3233
  const [previousContentDimensions, setPreviousContentDimensions] = React__namespace.useState(null);
3240
3234
  const [showStartingStyleAttribute, setShowStartingStyleAttribute] = React__namespace.useState(false);
3241
- DrawerRoot.useIsoLayoutEffect(() => {
3235
+ useValueChanged.useIsoLayoutEffect(() => {
3242
3236
  store.set('hasViewport', true);
3243
3237
  return () => {
3244
3238
  store.set('hasViewport', false);
3245
3239
  };
3246
3240
  }, [store]);
3247
- const handleMeasureLayout = DrawerRoot.useStableCallback(() => {
3241
+ const handleMeasureLayout = useValueChanged.useStableCallback(() => {
3248
3242
  currentContainerRef.current?.style.setProperty('animation', 'none');
3249
3243
  currentContainerRef.current?.style.setProperty('transition', 'none');
3250
3244
  previousContainerRef.current?.style.setProperty('display', 'none');
3251
3245
  });
3252
- const handleMeasureLayoutComplete = DrawerRoot.useStableCallback(previousDimensions => {
3246
+ const handleMeasureLayoutComplete = useValueChanged.useStableCallback(previousDimensions => {
3253
3247
  currentContainerRef.current?.style.removeProperty('animation');
3254
3248
  currentContainerRef.current?.style.removeProperty('transition');
3255
3249
  previousContainerRef.current?.style.removeProperty('display');
@@ -3258,7 +3252,7 @@ function usePopupViewport(parameters) {
3258
3252
  }
3259
3253
  });
3260
3254
  const lastHandledTriggerRef = React__namespace.useRef(null);
3261
- DrawerRoot.useIsoLayoutEffect(() => {
3255
+ useValueChanged.useIsoLayoutEffect(() => {
3262
3256
  // When a trigger changes, set the captured children HTML to state,
3263
3257
  // so we can render both new and old content.
3264
3258
  if (activeTrigger && previousActiveTrigger && activeTrigger !== previousActiveTrigger && lastHandledTriggerRef.current !== activeTrigger && capturedNodeRef.current) {
@@ -3285,7 +3279,7 @@ function usePopupViewport(parameters) {
3285
3279
 
3286
3280
  // Capture a clone of the current content DOM subtree when not transitioning.
3287
3281
  // We can't store previous React nodes as they may be stateful; instead we capture DOM clones for visual continuity.
3288
- DrawerRoot.useIsoLayoutEffect(() => {
3282
+ useValueChanged.useIsoLayoutEffect(() => {
3289
3283
  // When a transition is in progress, we store the next content in capturedNodeRef.
3290
3284
  // This handles the case where the trigger changes multiple times before the transition finishes.
3291
3285
  // We want to always capture the latest content for the previous snapshot.
@@ -3334,7 +3328,7 @@ function usePopupViewport(parameters) {
3334
3328
  }
3335
3329
 
3336
3330
  // When previousContentNode is present, imperatively populate the previous container with the cloned children.
3337
- DrawerRoot.useIsoLayoutEffect(() => {
3331
+ useValueChanged.useIsoLayoutEffect(() => {
3338
3332
  const container = previousContainerRef.current;
3339
3333
  if (!container || !previousContentNode) {
3340
3334
  return;
@@ -3421,7 +3415,7 @@ function usePopupContentKey(activeTriggerId, payload) {
3421
3415
  const previousActiveTriggerIdRef = React__namespace.useRef(activeTriggerId);
3422
3416
  const previousPayloadRef = React__namespace.useRef(payload);
3423
3417
  const pendingPayloadUpdateRef = React__namespace.useRef(false);
3424
- DrawerRoot.useIsoLayoutEffect(() => {
3418
+ useValueChanged.useIsoLayoutEffect(() => {
3425
3419
  // Compare against the last committed values to decide whether we need a new DOM subtree.
3426
3420
  const previousActiveTriggerId = previousActiveTriggerIdRef.current;
3427
3421
  const previousPayload = previousPayloadRef.current;
@@ -3460,7 +3454,7 @@ let MenuViewportCssVars = /*#__PURE__*/function (MenuViewportCssVars) {
3460
3454
  return MenuViewportCssVars;
3461
3455
  }({});
3462
3456
 
3463
- const stateAttributesMapping$5 = {
3457
+ const stateAttributesMapping$3 = {
3464
3458
  activationDirection: value => value ? {
3465
3459
  'data-activation-direction': value
3466
3460
  } : null
@@ -3508,7 +3502,7 @@ const MenuViewport = /*#__PURE__*/React__namespace.forwardRef(function MenuViewp
3508
3502
  props: [elementProps, {
3509
3503
  children: childrenToRender
3510
3504
  }],
3511
- stateAttributesMapping: stateAttributesMapping$5
3505
+ stateAttributesMapping: stateAttributesMapping$3
3512
3506
  });
3513
3507
  });
3514
3508
  if (process.env.NODE_ENV !== "production") MenuViewport.displayName = "MenuViewport";
@@ -3534,14 +3528,14 @@ class MenuHandle {
3534
3528
  if (triggerId && !triggerElement) {
3535
3529
  throw new Error(process.env.NODE_ENV !== "production" ? `Base UI: MenuHandle.open: No trigger found with id "${triggerId}".` : useRenderElement.formatErrorMessage(83, triggerId));
3536
3530
  }
3537
- this.store.setOpen(true, DrawerRoot.createChangeEventDetails('imperative-action', undefined, triggerElement));
3531
+ this.store.setOpen(true, useValueChanged.createChangeEventDetails('imperative-action', undefined, triggerElement));
3538
3532
  }
3539
3533
 
3540
3534
  /**
3541
3535
  * Closes the menu.
3542
3536
  */
3543
3537
  close() {
3544
- this.store.setOpen(false, DrawerRoot.createChangeEventDetails('imperative-action', undefined, undefined));
3538
+ this.store.setOpen(false, useValueChanged.createChangeEventDetails('imperative-action', undefined, undefined));
3545
3539
  }
3546
3540
 
3547
3541
  /**
@@ -3852,299 +3846,6 @@ const selectors = {
3852
3846
  submitOnItemClick: DrawerRoot.createSelector(state => state.submitOnItemClick)
3853
3847
  };
3854
3848
 
3855
- let FieldControlDataAttributes = /*#__PURE__*/function (FieldControlDataAttributes) {
3856
- /**
3857
- * Present when the field is disabled.
3858
- */
3859
- FieldControlDataAttributes["disabled"] = "data-disabled";
3860
- /**
3861
- * Present when the field is in valid state.
3862
- */
3863
- FieldControlDataAttributes["valid"] = "data-valid";
3864
- /**
3865
- * Present when the field is in invalid state.
3866
- */
3867
- FieldControlDataAttributes["invalid"] = "data-invalid";
3868
- /**
3869
- * Present when the field has been touched.
3870
- */
3871
- FieldControlDataAttributes["touched"] = "data-touched";
3872
- /**
3873
- * Present when the field's value has changed.
3874
- */
3875
- FieldControlDataAttributes["dirty"] = "data-dirty";
3876
- /**
3877
- * Present when the field is filled.
3878
- */
3879
- FieldControlDataAttributes["filled"] = "data-filled";
3880
- /**
3881
- * Present when the field control is focused.
3882
- */
3883
- FieldControlDataAttributes["focused"] = "data-focused";
3884
- return FieldControlDataAttributes;
3885
- }({});
3886
-
3887
- const DEFAULT_VALIDITY_STATE = {
3888
- badInput: false,
3889
- customError: false,
3890
- patternMismatch: false,
3891
- rangeOverflow: false,
3892
- rangeUnderflow: false,
3893
- stepMismatch: false,
3894
- tooLong: false,
3895
- tooShort: false,
3896
- typeMismatch: false,
3897
- valid: null,
3898
- valueMissing: false
3899
- };
3900
- const DEFAULT_FIELD_STATE_ATTRIBUTES = {
3901
- valid: null,
3902
- touched: false,
3903
- dirty: false,
3904
- filled: false,
3905
- focused: false
3906
- };
3907
- const DEFAULT_FIELD_ROOT_STATE = {
3908
- disabled: false,
3909
- ...DEFAULT_FIELD_STATE_ATTRIBUTES
3910
- };
3911
- const fieldValidityMapping = {
3912
- valid(value) {
3913
- if (value === null) {
3914
- return null;
3915
- }
3916
- if (value) {
3917
- return {
3918
- [FieldControlDataAttributes.valid]: ''
3919
- };
3920
- }
3921
- return {
3922
- [FieldControlDataAttributes.invalid]: ''
3923
- };
3924
- }
3925
- };
3926
-
3927
- const FieldRootContext = /*#__PURE__*/React__namespace.createContext({
3928
- invalid: undefined,
3929
- name: undefined,
3930
- validityData: {
3931
- state: DEFAULT_VALIDITY_STATE,
3932
- errors: [],
3933
- error: '',
3934
- value: '',
3935
- initialValue: null
3936
- },
3937
- setValidityData: useRenderElement.NOOP,
3938
- disabled: undefined,
3939
- touched: DEFAULT_FIELD_STATE_ATTRIBUTES.touched,
3940
- setTouched: useRenderElement.NOOP,
3941
- dirty: DEFAULT_FIELD_STATE_ATTRIBUTES.dirty,
3942
- setDirty: useRenderElement.NOOP,
3943
- filled: DEFAULT_FIELD_STATE_ATTRIBUTES.filled,
3944
- setFilled: useRenderElement.NOOP,
3945
- focused: DEFAULT_FIELD_STATE_ATTRIBUTES.focused,
3946
- setFocused: useRenderElement.NOOP,
3947
- validate: () => null,
3948
- validationMode: 'onSubmit',
3949
- validationDebounceTime: 0,
3950
- shouldValidateOnChange: () => false,
3951
- state: DEFAULT_FIELD_ROOT_STATE,
3952
- markedDirtyRef: {
3953
- current: false
3954
- },
3955
- validation: {
3956
- getValidationProps: (props = useRenderElement.EMPTY_OBJECT) => props,
3957
- getInputValidationProps: (props = useRenderElement.EMPTY_OBJECT) => props,
3958
- inputRef: {
3959
- current: null
3960
- },
3961
- commit: async () => {}
3962
- }
3963
- });
3964
- if (process.env.NODE_ENV !== "production") FieldRootContext.displayName = "FieldRootContext";
3965
- function useFieldRootContext(optional = true) {
3966
- const context = React__namespace.useContext(FieldRootContext);
3967
- if (context.setValidityData === useRenderElement.NOOP && !optional) {
3968
- throw new Error(process.env.NODE_ENV !== "production" ? 'Base UI: FieldRootContext is missing. Field parts must be placed within <Field.Root>.' : useRenderElement.formatErrorMessage(28));
3969
- }
3970
- return context;
3971
- }
3972
-
3973
- /**
3974
- * Combines the field's client-side, stateful validity data with the external invalid state to
3975
- * determine the field's true validity.
3976
- */
3977
- function getCombinedFieldValidityData(validityData, invalid) {
3978
- return {
3979
- ...validityData,
3980
- state: {
3981
- ...validityData.state,
3982
- valid: !invalid && validityData.state.valid
3983
- }
3984
- };
3985
- }
3986
-
3987
- const FormContext = /*#__PURE__*/React__namespace.createContext({
3988
- formRef: {
3989
- current: {
3990
- fields: new Map()
3991
- }
3992
- },
3993
- errors: {},
3994
- clearErrors: useRenderElement.NOOP,
3995
- validationMode: 'onSubmit',
3996
- submitAttemptedRef: {
3997
- current: false
3998
- }
3999
- });
4000
- if (process.env.NODE_ENV !== "production") FormContext.displayName = "FormContext";
4001
- function useFormContext() {
4002
- return React__namespace.useContext(FormContext);
4003
- }
4004
-
4005
- function useField(params) {
4006
- const {
4007
- enabled = true,
4008
- value,
4009
- id,
4010
- name,
4011
- controlRef,
4012
- commit
4013
- } = params;
4014
- const {
4015
- formRef
4016
- } = useFormContext();
4017
- const {
4018
- invalid,
4019
- markedDirtyRef,
4020
- validityData,
4021
- setValidityData
4022
- } = useFieldRootContext();
4023
- const getValue = DrawerRoot.useStableCallback(params.getValue);
4024
- DrawerRoot.useIsoLayoutEffect(() => {
4025
- if (!enabled) {
4026
- return;
4027
- }
4028
- let initialValue = value;
4029
- if (initialValue === undefined) {
4030
- initialValue = getValue();
4031
- }
4032
- if (validityData.initialValue === null && initialValue !== null) {
4033
- setValidityData(prev => ({
4034
- ...prev,
4035
- initialValue
4036
- }));
4037
- }
4038
- }, [enabled, setValidityData, value, validityData.initialValue, getValue]);
4039
- DrawerRoot.useIsoLayoutEffect(() => {
4040
- if (!enabled || !id) {
4041
- return;
4042
- }
4043
- formRef.current.fields.set(id, {
4044
- getValue,
4045
- name,
4046
- controlRef,
4047
- validityData: getCombinedFieldValidityData(validityData, invalid),
4048
- validate(flushSync = true) {
4049
- let nextValue = value;
4050
- if (nextValue === undefined) {
4051
- nextValue = getValue();
4052
- }
4053
- markedDirtyRef.current = true;
4054
- if (!flushSync) {
4055
- commit(nextValue);
4056
- } else {
4057
- // Synchronously update the validity state so the submit event can be prevented.
4058
- ReactDOM__namespace.flushSync(() => commit(nextValue));
4059
- }
4060
- }
4061
- });
4062
- }, [commit, controlRef, enabled, formRef, getValue, id, invalid, markedDirtyRef, name, validityData, value]);
4063
- DrawerRoot.useIsoLayoutEffect(() => {
4064
- const fields = formRef.current.fields;
4065
- return () => {
4066
- if (id) {
4067
- fields.delete(id);
4068
- }
4069
- };
4070
- }, [formRef, id]);
4071
- }
4072
-
4073
- /**
4074
- * A context for providing [labelable elements](https://html.spec.whatwg.org/multipage/forms.html#category-label)\
4075
- * with an accessible name (label) and description.
4076
- */
4077
- const LabelableContext = /*#__PURE__*/React__namespace.createContext({
4078
- controlId: undefined,
4079
- registerControlId: useRenderElement.NOOP,
4080
- labelId: undefined,
4081
- setLabelId: useRenderElement.NOOP,
4082
- messageIds: [],
4083
- setMessageIds: useRenderElement.NOOP,
4084
- getDescriptionProps: externalProps => externalProps
4085
- });
4086
- if (process.env.NODE_ENV !== "production") LabelableContext.displayName = "LabelableContext";
4087
- function useLabelableContext() {
4088
- return React__namespace.useContext(LabelableContext);
4089
- }
4090
-
4091
- function useLabelableId(params = {}) {
4092
- const {
4093
- id,
4094
- implicit = false,
4095
- controlRef
4096
- } = params;
4097
- const {
4098
- controlId,
4099
- registerControlId
4100
- } = useLabelableContext();
4101
- const defaultId = MenuSubmenuTrigger.useBaseUiId(id);
4102
- const controlIdForEffect = implicit ? controlId : undefined;
4103
- const controlSourceRef = useRenderElement.useRefWithInit(() => Symbol('labelable-control'));
4104
- const hasRegisteredRef = React__namespace.useRef(false);
4105
- const hadExplicitIdRef = React__namespace.useRef(id != null);
4106
- const unregisterControlId = DrawerRoot.useStableCallback(() => {
4107
- if (!hasRegisteredRef.current || registerControlId === useRenderElement.NOOP) {
4108
- return;
4109
- }
4110
- hasRegisteredRef.current = false;
4111
- registerControlId(controlSourceRef.current, undefined);
4112
- });
4113
- DrawerRoot.useIsoLayoutEffect(() => {
4114
- if (registerControlId === useRenderElement.NOOP) {
4115
- return undefined;
4116
- }
4117
- let nextId;
4118
- if (implicit) {
4119
- const elem = controlRef?.current;
4120
- if (index_esm.isElement(elem) && elem.closest('label') != null) {
4121
- nextId = id ?? null;
4122
- } else {
4123
- nextId = controlIdForEffect ?? defaultId;
4124
- }
4125
- } else if (id != null) {
4126
- hadExplicitIdRef.current = true;
4127
- nextId = id;
4128
- } else if (hadExplicitIdRef.current) {
4129
- nextId = defaultId;
4130
- } else {
4131
- unregisterControlId();
4132
- return undefined;
4133
- }
4134
- if (nextId === undefined) {
4135
- unregisterControlId();
4136
- return undefined;
4137
- }
4138
- hasRegisteredRef.current = true;
4139
- registerControlId(controlSourceRef.current, nextId);
4140
- return undefined;
4141
- }, [id, controlRef, controlIdForEffect, registerControlId, implicit, defaultId, controlSourceRef, unregisterControlId]);
4142
- React__namespace.useEffect(() => {
4143
- return unregisterControlId;
4144
- }, [unregisterControlId]);
4145
- return controlId ?? defaultId;
4146
- }
4147
-
4148
3849
  /**
4149
3850
  * Enhanced filter using Intl.Collator for more robust string matching.
4150
3851
  * Uses the provided `itemToStringLabel` function if available, otherwise falls back to:
@@ -4313,7 +4014,7 @@ function AriaCombobox(props) {
4313
4014
  } = props;
4314
4015
  const {
4315
4016
  clearErrors
4316
- } = useFormContext();
4017
+ } = NumberFieldInput.useFormContext();
4317
4018
  const {
4318
4019
  setDirty,
4319
4020
  validityData,
@@ -4325,8 +4026,8 @@ function AriaCombobox(props) {
4325
4026
  setFocused,
4326
4027
  validationMode,
4327
4028
  validation
4328
- } = useFieldRootContext();
4329
- const id = useLabelableId({
4029
+ } = NumberFieldInput.useFieldRootContext();
4030
+ const id = NumberFieldInput.useLabelableId({
4330
4031
  id: idProp
4331
4032
  });
4332
4033
  const collatorFilter = useCoreFilter({
@@ -4373,7 +4074,7 @@ function AriaCombobox(props) {
4373
4074
  } else {
4374
4075
  autoHighlightMode = autoHighlight ? 'input-change' : false;
4375
4076
  }
4376
- const [selectedValue, setSelectedValueUnwrapped] = DrawerRoot.useControlled({
4077
+ const [selectedValue, setSelectedValueUnwrapped] = useValueChanged.useControlled({
4377
4078
  controlled: selectedValueProp,
4378
4079
  default: multiple ? defaultSelectedValue ?? useRenderElement.EMPTY_ARRAY : defaultSelectedValue,
4379
4080
  name: 'Combobox',
@@ -4403,13 +4104,13 @@ function AriaCombobox(props) {
4403
4104
  }
4404
4105
  return '';
4405
4106
  }).current;
4406
- const [inputValue, setInputValueUnwrapped] = DrawerRoot.useControlled({
4107
+ const [inputValue, setInputValueUnwrapped] = useValueChanged.useControlled({
4407
4108
  controlled: inputValueProp,
4408
4109
  default: initialDefaultInputValue,
4409
4110
  name: 'Combobox',
4410
4111
  state: 'inputValue'
4411
4112
  });
4412
- const [open, setOpenUnwrapped] = DrawerRoot.useControlled({
4113
+ const [open, setOpenUnwrapped] = useValueChanged.useControlled({
4413
4114
  controlled: props.open,
4414
4115
  default: props.defaultOpen,
4415
4116
  name: 'Combobox',
@@ -4565,8 +4266,8 @@ function AriaCombobox(props) {
4565
4266
  }
4566
4267
  return stringifyAsValue(selectedValue, itemToStringValue);
4567
4268
  }, [fieldRawValue, itemToStringValue, selectionMode, selectedValue]);
4568
- const onItemHighlighted = DrawerRoot.useStableCallback(onItemHighlightedProp);
4569
- const onOpenChangeComplete = DrawerRoot.useStableCallback(onOpenChangeCompleteProp);
4269
+ const onItemHighlighted = useValueChanged.useStableCallback(onItemHighlightedProp);
4270
+ const onOpenChangeComplete = useValueChanged.useStableCallback(onOpenChangeCompleteProp);
4570
4271
  const activeIndex = DrawerRoot.useStore(store, selectors.activeIndex);
4571
4272
  const selectedIndex = DrawerRoot.useStore(store, selectors.selectedIndex);
4572
4273
  const positionerElement = DrawerRoot.useStore(store, selectors.positionerElement);
@@ -4576,17 +4277,17 @@ function AriaCombobox(props) {
4576
4277
  const inputGroupElement = DrawerRoot.useStore(store, selectors.inputGroupElement);
4577
4278
  const inline = DrawerRoot.useStore(store, selectors.inline);
4578
4279
  const inputInsidePopup = DrawerRoot.useStore(store, selectors.inputInsidePopup);
4579
- const triggerRef = DrawerRoot.useValueAsRef(triggerElement);
4280
+ const triggerRef = useValueChanged.useValueAsRef(triggerElement);
4580
4281
  const {
4581
4282
  mounted,
4582
4283
  setMounted,
4583
4284
  transitionStatus
4584
- } = DrawerRoot.useTransitionStatus(open);
4285
+ } = useValueChanged.useTransitionStatus(open);
4585
4286
  const {
4586
4287
  openMethod,
4587
4288
  triggerProps
4588
4289
  } = DrawerRoot.useOpenInteractionType(open);
4589
- useField({
4290
+ NumberFieldInput.useField({
4590
4291
  id,
4591
4292
  name,
4592
4293
  commit: validation.commit,
@@ -4594,7 +4295,7 @@ function AriaCombobox(props) {
4594
4295
  controlRef: inputInsidePopup ? triggerRef : inputRef,
4595
4296
  getValue: () => fieldStringValue
4596
4297
  });
4597
- const forceMount = DrawerRoot.useStableCallback(() => {
4298
+ const forceMount = useValueChanged.useStableCallback(() => {
4598
4299
  if (items) {
4599
4300
  // Ensure typeahead works on a closed list.
4600
4301
  labelsRef.current = flatFilteredItems.map(item => stringifyAsLabel(item, itemToStringLabel));
@@ -4603,13 +4304,13 @@ function AriaCombobox(props) {
4603
4304
  }
4604
4305
  });
4605
4306
  const initialSelectedValueRef = React__namespace.useRef(selectedValue);
4606
- DrawerRoot.useIsoLayoutEffect(() => {
4307
+ useValueChanged.useIsoLayoutEffect(() => {
4607
4308
  // Ensure the values and labels are registered for programmatic value changes.
4608
4309
  if (selectedValue !== initialSelectedValueRef.current) {
4609
4310
  forceMount();
4610
4311
  }
4611
4312
  }, [forceMount, selectedValue]);
4612
- const setIndices = DrawerRoot.useStableCallback(options => {
4313
+ const setIndices = useValueChanged.useStableCallback(options => {
4613
4314
  store.update(options);
4614
4315
  const type = options.type || 'none';
4615
4316
  if (options.activeIndex === undefined) {
@@ -4618,7 +4319,7 @@ function AriaCombobox(props) {
4618
4319
  if (options.activeIndex === null) {
4619
4320
  if (lastHighlightRef.current !== INITIAL_LAST_HIGHLIGHT) {
4620
4321
  lastHighlightRef.current = INITIAL_LAST_HIGHLIGHT;
4621
- onItemHighlighted(undefined, DrawerRoot.createGenericEventDetails(type, undefined, {
4322
+ onItemHighlighted(undefined, useValueChanged.createGenericEventDetails(type, undefined, {
4622
4323
  index: -1
4623
4324
  }));
4624
4325
  }
@@ -4628,13 +4329,13 @@ function AriaCombobox(props) {
4628
4329
  value: activeValue,
4629
4330
  index: options.activeIndex
4630
4331
  };
4631
- onItemHighlighted(activeValue, DrawerRoot.createGenericEventDetails(type, undefined, {
4332
+ onItemHighlighted(activeValue, useValueChanged.createGenericEventDetails(type, undefined, {
4632
4333
  index: options.activeIndex
4633
4334
  }));
4634
4335
  }
4635
4336
  });
4636
- const setInputValue = DrawerRoot.useStableCallback((next, eventDetails) => {
4637
- hadInputClearRef.current = eventDetails.reason === DrawerRoot.inputClear;
4337
+ const setInputValue = useValueChanged.useStableCallback((next, eventDetails) => {
4338
+ hadInputClearRef.current = eventDetails.reason === useValueChanged.inputClear;
4638
4339
  props.onInputValueChange?.(next, eventDetails);
4639
4340
  if (eventDetails.isCanceled) {
4640
4341
  return;
@@ -4642,7 +4343,7 @@ function AriaCombobox(props) {
4642
4343
 
4643
4344
  // If user is typing, ensure we don't auto-highlight on open due to a race
4644
4345
  // with the post-open effect that sets this flag.
4645
- if (eventDetails.reason === DrawerRoot.inputChange) {
4346
+ if (eventDetails.reason === useValueChanged.inputChange) {
4646
4347
  const event = eventDetails.event;
4647
4348
  const inputType = event.inputType;
4648
4349
  // Treat composition commits as typed input; autofill may omit `inputType` or
@@ -4665,7 +4366,7 @@ function AriaCombobox(props) {
4665
4366
  }
4666
4367
  setInputValueUnwrapped(next);
4667
4368
  });
4668
- const setOpen = DrawerRoot.useStableCallback((nextOpen, eventDetails) => {
4369
+ const setOpen = useValueChanged.useStableCallback((nextOpen, eventDetails) => {
4669
4370
  if (open === nextOpen) {
4670
4371
  return;
4671
4372
  }
@@ -4700,11 +4401,11 @@ function AriaCombobox(props) {
4700
4401
  }
4701
4402
  // Clear the input immediately on close while retaining filtering via closeQuery for exit animations
4702
4403
  // if the input is outside the popup.
4703
- setInputValue('', DrawerRoot.createChangeEventDetails(DrawerRoot.inputClear, eventDetails.event));
4404
+ setInputValue('', useValueChanged.createChangeEventDetails(useValueChanged.inputClear, eventDetails.event));
4704
4405
  }
4705
4406
  }
4706
4407
  setOpenUnwrapped(nextOpen);
4707
- if (!nextOpen && inputInsidePopup && (eventDetails.reason === DrawerRoot.focusOut || eventDetails.reason === DrawerRoot.outsidePress)) {
4408
+ if (!nextOpen && inputInsidePopup && (eventDetails.reason === useValueChanged.focusOut || eventDetails.reason === useValueChanged.outsidePress)) {
4708
4409
  setTouched(true);
4709
4410
  setFocused(false);
4710
4411
  if (validationMode === 'onBlur') {
@@ -4713,7 +4414,7 @@ function AriaCombobox(props) {
4713
4414
  }
4714
4415
  }
4715
4416
  });
4716
- const setSelectedValue = DrawerRoot.useStableCallback((nextValue, eventDetails) => {
4417
+ const setSelectedValue = useValueChanged.useStableCallback((nextValue, eventDetails) => {
4717
4418
  // Cast to `any` due to conditional value type (single vs. multiple).
4718
4419
  // The runtime implementation already ensures the correct value shape.
4719
4420
  onSelectedValueChange?.(nextValue, eventDetails);
@@ -4723,13 +4424,13 @@ function AriaCombobox(props) {
4723
4424
  setSelectedValueUnwrapped(nextValue);
4724
4425
  const shouldFillInput = selectionMode === 'none' && popupRef.current && fillInputOnItemPress || single && !store.state.inputInsidePopup;
4725
4426
  if (shouldFillInput) {
4726
- setInputValue(stringifyAsLabel(nextValue, itemToStringLabel), DrawerRoot.createChangeEventDetails(eventDetails.reason, eventDetails.event));
4427
+ setInputValue(stringifyAsLabel(nextValue, itemToStringLabel), useValueChanged.createChangeEventDetails(eventDetails.reason, eventDetails.event));
4727
4428
  }
4728
- if (single && nextValue != null && eventDetails.reason !== DrawerRoot.inputChange && queryChangedAfterOpen && !inline) {
4429
+ if (single && nextValue != null && eventDetails.reason !== useValueChanged.inputChange && queryChangedAfterOpen && !inline) {
4729
4430
  setCloseQuery(query);
4730
4431
  }
4731
4432
  });
4732
- const handleSelection = DrawerRoot.useStableCallback((event, passedValue) => {
4433
+ const handleSelection = useValueChanged.useStableCallback((event, passedValue) => {
4733
4434
  let itemValue = passedValue;
4734
4435
  if (itemValue === undefined) {
4735
4436
  if (activeIndex === null) {
@@ -4740,7 +4441,7 @@ function AriaCombobox(props) {
4740
4441
  const targetEl = DrawerRoot.getTarget(event);
4741
4442
  const overrideEvent = selectionEventRef.current ?? event;
4742
4443
  selectionEventRef.current = null;
4743
- const eventDetails = DrawerRoot.createChangeEventDetails(DrawerRoot.itemPress, overrideEvent);
4444
+ const eventDetails = useValueChanged.createChangeEventDetails(useValueChanged.itemPress, overrideEvent);
4744
4445
 
4745
4446
  // Let the link handle the click.
4746
4447
  const href = targetEl?.closest('a')?.getAttribute('href');
@@ -4760,7 +4461,7 @@ function AriaCombobox(props) {
4760
4461
  return;
4761
4462
  }
4762
4463
  if (store.state.inputInsidePopup) {
4763
- setInputValue('', DrawerRoot.createChangeEventDetails(DrawerRoot.inputClear, eventDetails.event));
4464
+ setInputValue('', useValueChanged.createChangeEventDetails(useValueChanged.inputClear, eventDetails.event));
4764
4465
  } else {
4765
4466
  setOpen(false, eventDetails);
4766
4467
  }
@@ -4769,7 +4470,7 @@ function AriaCombobox(props) {
4769
4470
  setOpen(false, eventDetails);
4770
4471
  }
4771
4472
  });
4772
- const requestSubmit = DrawerRoot.useStableCallback(() => {
4473
+ const requestSubmit = useValueChanged.useStableCallback(() => {
4773
4474
  if (!store.state.submitOnItemClick) {
4774
4475
  return;
4775
4476
  }
@@ -4778,7 +4479,7 @@ function AriaCombobox(props) {
4778
4479
  form.requestSubmit();
4779
4480
  }
4780
4481
  });
4781
- const handleUnmount = DrawerRoot.useStableCallback(() => {
4482
+ const handleUnmount = useValueChanged.useStableCallback(() => {
4782
4483
  setMounted(false);
4783
4484
  onOpenChangeComplete?.(false);
4784
4485
  setQueryChangedAfterOpen(false);
@@ -4798,7 +4499,7 @@ function AriaCombobox(props) {
4798
4499
  // If the user typed a filter and didn't select in multiple mode, clear the input
4799
4500
  // after close completes to avoid mid-exit flicker and start fresh on next open.
4800
4501
  if (multiple && inputRef.current && inputRef.current.value !== '' && !hadInputClearRef.current) {
4801
- setInputValue('', DrawerRoot.createChangeEventDetails(DrawerRoot.inputClear));
4502
+ setInputValue('', useValueChanged.createChangeEventDetails(useValueChanged.inputClear));
4802
4503
  }
4803
4504
 
4804
4505
  // Single selection mode:
@@ -4807,14 +4508,14 @@ function AriaCombobox(props) {
4807
4508
  if (single) {
4808
4509
  if (store.state.inputInsidePopup) {
4809
4510
  if (inputRef.current && inputRef.current.value !== '') {
4810
- setInputValue('', DrawerRoot.createChangeEventDetails(DrawerRoot.inputClear));
4511
+ setInputValue('', useValueChanged.createChangeEventDetails(useValueChanged.inputClear));
4811
4512
  }
4812
4513
  } else {
4813
4514
  const stringVal = stringifyAsLabel(selectedValue, itemToStringLabel);
4814
4515
  if (inputRef.current && inputRef.current.value !== stringVal) {
4815
4516
  // If no selection was made, treat this as clearing the typed filter.
4816
- const reason = stringVal === '' ? DrawerRoot.inputClear : DrawerRoot.none;
4817
- setInputValue(stringVal, DrawerRoot.createChangeEventDetails(reason));
4517
+ const reason = stringVal === '' ? useValueChanged.inputClear : useValueChanged.none;
4518
+ setInputValue(stringVal, useValueChanged.createChangeEventDetails(reason));
4818
4519
  }
4819
4520
  }
4820
4521
  }
@@ -4832,7 +4533,7 @@ function AriaCombobox(props) {
4832
4533
  }
4833
4534
  return popupRef;
4834
4535
  }, [inline, positionerElement]);
4835
- DrawerRoot.useOpenChangeComplete({
4536
+ useValueChanged.useOpenChangeComplete({
4836
4537
  enabled: !props.actionsRef,
4837
4538
  open,
4838
4539
  ref: resolvedPopupRef,
@@ -4845,7 +4546,7 @@ function AriaCombobox(props) {
4845
4546
  React__namespace.useImperativeHandle(props.actionsRef, () => ({
4846
4547
  unmount: handleUnmount
4847
4548
  }), [handleUnmount]);
4848
- DrawerRoot.useIsoLayoutEffect(function syncSelectedIndex() {
4549
+ useValueChanged.useIsoLayoutEffect(function syncSelectedIndex() {
4849
4550
  if (open || selectionMode === 'none') {
4850
4551
  return;
4851
4552
  }
@@ -4864,13 +4565,13 @@ function AriaCombobox(props) {
4864
4565
  });
4865
4566
  }
4866
4567
  }, [open, selectedValue, items, selectionMode, flatItems, multiple, isItemEqualToValue, setIndices]);
4867
- DrawerRoot.useIsoLayoutEffect(() => {
4568
+ useValueChanged.useIsoLayoutEffect(() => {
4868
4569
  if (items) {
4869
4570
  valuesRef.current = flatFilteredItems;
4870
4571
  listRef.current.length = flatFilteredItems.length;
4871
4572
  }
4872
4573
  }, [items, flatFilteredItems]);
4873
- DrawerRoot.useIsoLayoutEffect(() => {
4574
+ useValueChanged.useIsoLayoutEffect(() => {
4874
4575
  const pendingHighlight = pendingQueryHighlightRef.current;
4875
4576
  if (pendingHighlight) {
4876
4577
  if (pendingHighlight.hasQuery) {
@@ -4895,7 +4596,7 @@ function AriaCombobox(props) {
4895
4596
  }
4896
4597
  if (lastHighlightRef.current !== INITIAL_LAST_HIGHLIGHT) {
4897
4598
  lastHighlightRef.current = INITIAL_LAST_HIGHLIGHT;
4898
- store.state.onItemHighlighted(undefined, DrawerRoot.createGenericEventDetails(DrawerRoot.none, undefined, {
4599
+ store.state.onItemHighlighted(undefined, useValueChanged.createGenericEventDetails(useValueChanged.none, undefined, {
4899
4600
  index: -1
4900
4601
  }));
4901
4602
  }
@@ -4904,7 +4605,7 @@ function AriaCombobox(props) {
4904
4605
  if (storeActiveIndex >= candidateItems.length) {
4905
4606
  if (lastHighlightRef.current !== INITIAL_LAST_HIGHLIGHT) {
4906
4607
  lastHighlightRef.current = INITIAL_LAST_HIGHLIGHT;
4907
- store.state.onItemHighlighted(undefined, DrawerRoot.createGenericEventDetails(DrawerRoot.none, undefined, {
4608
+ store.state.onItemHighlighted(undefined, useValueChanged.createGenericEventDetails(useValueChanged.none, undefined, {
4908
4609
  index: -1
4909
4610
  }));
4910
4611
  }
@@ -4919,12 +4620,12 @@ function AriaCombobox(props) {
4919
4620
  value: itemValue,
4920
4621
  index: storeActiveIndex
4921
4622
  };
4922
- store.state.onItemHighlighted(itemValue, DrawerRoot.createGenericEventDetails(DrawerRoot.none, undefined, {
4623
+ store.state.onItemHighlighted(itemValue, useValueChanged.createGenericEventDetails(useValueChanged.none, undefined, {
4923
4624
  index: storeActiveIndex
4924
4625
  }));
4925
4626
  }
4926
4627
  }, [activeIndex, autoHighlightMode, hasFilteredItemsProp, hasItems, flatFilteredItems, inline, open, store]);
4927
- DrawerRoot.useIsoLayoutEffect(() => {
4628
+ useValueChanged.useIsoLayoutEffect(() => {
4928
4629
  if (selectionMode === 'none') {
4929
4630
  setFilled(String(inputValue) !== '');
4930
4631
  return;
@@ -4941,13 +4642,13 @@ function AriaCombobox(props) {
4941
4642
  });
4942
4643
  }
4943
4644
  }, [hasItems, autoHighlightMode, flatFilteredItems.length, setIndices]);
4944
- DrawerRoot.useValueChanged(query, () => {
4645
+ useValueChanged.useValueChanged(query, () => {
4945
4646
  if (!open || query === '' || query === String(initialDefaultInputValue)) {
4946
4647
  return;
4947
4648
  }
4948
4649
  setQueryChangedAfterOpen(true);
4949
4650
  });
4950
- DrawerRoot.useValueChanged(selectedValue, () => {
4651
+ useValueChanged.useValueChanged(selectedValue, () => {
4951
4652
  if (selectionMode === 'none') {
4952
4653
  return;
4953
4654
  }
@@ -4961,11 +4662,11 @@ function AriaCombobox(props) {
4961
4662
  if (single && !hasInputValue && !inputInsidePopup) {
4962
4663
  const nextInputValue = stringifyAsLabel(selectedValue, itemToStringLabel);
4963
4664
  if (inputValue !== nextInputValue) {
4964
- setInputValue(nextInputValue, DrawerRoot.createChangeEventDetails(DrawerRoot.none));
4665
+ setInputValue(nextInputValue, useValueChanged.createChangeEventDetails(useValueChanged.none));
4965
4666
  }
4966
4667
  }
4967
4668
  });
4968
- DrawerRoot.useValueChanged(inputValue, () => {
4669
+ useValueChanged.useValueChanged(inputValue, () => {
4969
4670
  if (selectionMode !== 'none') {
4970
4671
  return;
4971
4672
  }
@@ -4977,13 +4678,13 @@ function AriaCombobox(props) {
4977
4678
  validation.commit(inputValue, true);
4978
4679
  }
4979
4680
  });
4980
- DrawerRoot.useValueChanged(items, () => {
4681
+ useValueChanged.useValueChanged(items, () => {
4981
4682
  if (!single || hasInputValue || inputInsidePopup || queryChangedAfterOpen) {
4982
4683
  return;
4983
4684
  }
4984
4685
  const nextInputValue = stringifyAsLabel(selectedValue, itemToStringLabel);
4985
4686
  if (inputValue !== nextInputValue) {
4986
- setInputValue(nextInputValue, DrawerRoot.createChangeEventDetails(DrawerRoot.none));
4687
+ setInputValue(nextInputValue, useValueChanged.createChangeEventDetails(useValueChanged.none));
4987
4688
  }
4988
4689
  });
4989
4690
  const floatingRootContext = MenuSubmenuTrigger.useFloatingRootContext({
@@ -5033,7 +4734,7 @@ function AriaCombobox(props) {
5033
4734
  // Apply a small delay for touch to let iOS viewport centering settle.
5034
4735
  // This avoids top-bottom flip flickers if the preferred position is "top" when first tapping.
5035
4736
  touchOpenDelay: inputInsidePopup ? 0 : 50,
5036
- reason: DrawerRoot.inputPress
4737
+ reason: useValueChanged.inputPress
5037
4738
  });
5038
4739
  const dismiss = DrawerRoot.useDismiss(floatingRootContext, {
5039
4740
  enabled: !readOnly && !disabled && !inline,
@@ -5109,7 +4810,7 @@ function AriaCombobox(props) {
5109
4810
  requestSubmit
5110
4811
  });
5111
4812
  });
5112
- DrawerRoot.useIsoLayoutEffect(() => {
4813
+ useValueChanged.useIsoLayoutEffect(() => {
5113
4814
  store.update({
5114
4815
  id,
5115
4816
  selectedValue,
@@ -5188,7 +4889,7 @@ function AriaCombobox(props) {
5188
4889
  return;
5189
4890
  }
5190
4891
  const nextValue = event.target.value;
5191
- const details = DrawerRoot.createChangeEventDetails(DrawerRoot.none, event.nativeEvent);
4892
+ const details = useValueChanged.createChangeEventDetails(useValueChanged.none, event.nativeEvent);
5192
4893
  function handleChange() {
5193
4894
  // Browser autofill only writes a single scalar value.
5194
4895
  if (multiple) {
@@ -5233,7 +4934,7 @@ function AriaCombobox(props) {
5233
4934
  readOnly: readOnly,
5234
4935
  value: serializedValue,
5235
4936
  ref: hiddenInputRef,
5236
- style: hiddenInputName ? DrawerRoot.visuallyHiddenInput : DrawerRoot.visuallyHidden,
4937
+ style: hiddenInputName ? useValueChanged.visuallyHiddenInput : useValueChanged.visuallyHidden,
5237
4938
  tabIndex: -1,
5238
4939
  "aria-hidden": true
5239
4940
  }), hiddenInputs]
@@ -5255,7 +4956,7 @@ function AriaCombobox(props) {
5255
4956
 
5256
4957
  const triggerStateAttributesMapping = {
5257
4958
  ...DrawerRoot.pressableTriggerOpenStateMapping,
5258
- ...fieldValidityMapping,
4959
+ ...NumberFieldInput.fieldValidityMapping,
5259
4960
  popupSide: side => side ? {
5260
4961
  'data-popup-side': side
5261
4962
  } : null,
@@ -5293,10 +4994,10 @@ const ComboboxTrigger = /*#__PURE__*/React__namespace.forwardRef(function Combob
5293
4994
  setFocused,
5294
4995
  validationMode,
5295
4996
  validation
5296
- } = useFieldRootContext();
4997
+ } = NumberFieldInput.useFieldRootContext();
5297
4998
  const {
5298
4999
  labelId: fieldLabelId
5299
- } = useLabelableContext();
5000
+ } = NumberFieldInput.useLabelableContext();
5300
5001
  const store = useComboboxRootContext();
5301
5002
  const {
5302
5003
  filteredItems
@@ -5321,11 +5022,11 @@ const ComboboxTrigger = /*#__PURE__*/React__namespace.forwardRef(function Combob
5321
5022
  const hasSelectedValue = DrawerRoot.useStore(store, selectors.hasSelectedValue);
5322
5023
  const floatingRootContext = useComboboxFloatingContext();
5323
5024
  const inputValue = useComboboxInputValueContext();
5324
- const focusTimeout = DrawerRoot.useTimeout();
5025
+ const focusTimeout = useValueChanged.useTimeout();
5325
5026
  const disabled = fieldDisabled || comboboxDisabled || disabledProp;
5326
5027
  const listEmpty = filteredItems.length === 0;
5327
5028
  const popupSide = mounted && positionerElement ? popupSideValue : null;
5328
- useLabelableId({
5029
+ NumberFieldInput.useLabelableId({
5329
5030
  id: inputInsidePopup ? idProp : undefined
5330
5031
  });
5331
5032
  const id = inputInsidePopup ? idProp ?? rootId : idProp;
@@ -5356,7 +5057,7 @@ const ComboboxTrigger = /*#__PURE__*/React__namespace.forwardRef(function Combob
5356
5057
  onMatch(index) {
5357
5058
  const nextSelectedValue = store.state.valuesRef.current[index];
5358
5059
  if (nextSelectedValue !== undefined) {
5359
- store.state.setSelectedValue(nextSelectedValue, DrawerRoot.createChangeEventDetails('none'));
5060
+ store.state.setSelectedValue(nextSelectedValue, useValueChanged.createChangeEventDetails('none'));
5360
5061
  }
5361
5062
  }
5362
5063
  });
@@ -5369,7 +5070,7 @@ const ComboboxTrigger = /*#__PURE__*/React__namespace.forwardRef(function Combob
5369
5070
  const {
5370
5071
  buttonRef,
5371
5072
  getButtonProps
5372
- } = MenuSubmenuTrigger.useButton({
5073
+ } = useBaseUiId.useButton({
5373
5074
  native: nativeButton,
5374
5075
  disabled
5375
5076
  });
@@ -5381,7 +5082,7 @@ const ComboboxTrigger = /*#__PURE__*/React__namespace.forwardRef(function Combob
5381
5082
  listEmpty,
5382
5083
  placeholder: !hasSelectedValue
5383
5084
  };
5384
- const setTriggerElement = DrawerRoot.useStableCallback(element => {
5085
+ const setTriggerElement = useValueChanged.useStableCallback(element => {
5385
5086
  store.set('triggerElement', element);
5386
5087
  });
5387
5088
  const element = useRenderElement.useRenderElement('button', componentProps, {
@@ -5436,7 +5137,7 @@ const ComboboxTrigger = /*#__PURE__*/React__namespace.forwardRef(function Combob
5436
5137
  if (open) {
5437
5138
  return;
5438
5139
  }
5439
- const doc = DrawerRoot.ownerDocument(event.currentTarget);
5140
+ const doc = useValueChanged.ownerDocument(event.currentTarget);
5440
5141
  function handleMouseUp(mouseEvent) {
5441
5142
  if (!triggerElement) {
5442
5143
  return;
@@ -5453,7 +5154,7 @@ const ComboboxTrigger = /*#__PURE__*/React__namespace.forwardRef(function Combob
5453
5154
  if (withinHorizontal && withinVertical) {
5454
5155
  return;
5455
5156
  }
5456
- store.state.setOpen(false, DrawerRoot.createChangeEventDetails('cancel-open', mouseEvent));
5157
+ store.state.setOpen(false, useValueChanged.createChangeEventDetails('cancel-open', mouseEvent));
5457
5158
  }
5458
5159
  if (inputInsidePopup) {
5459
5160
  doc.addEventListener('mouseup', handleMouseUp, {
@@ -5466,8 +5167,8 @@ const ComboboxTrigger = /*#__PURE__*/React__namespace.forwardRef(function Combob
5466
5167
  return;
5467
5168
  }
5468
5169
  if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
5469
- DrawerRoot.stopEvent(event);
5470
- store.state.setOpen(true, DrawerRoot.createChangeEventDetails(DrawerRoot.listNavigation, event.nativeEvent));
5170
+ useValueChanged.stopEvent(event);
5171
+ store.state.setOpen(true, useValueChanged.createChangeEventDetails(useValueChanged.listNavigation, event.nativeEvent));
5471
5172
  store.state.inputRef.current?.focus();
5472
5173
  }
5473
5174
  }
@@ -5502,12 +5203,12 @@ const ComboboxInternalDismissButton = /*#__PURE__*/React__namespace.forwardRef(f
5502
5203
  const {
5503
5204
  buttonRef,
5504
5205
  getButtonProps
5505
- } = MenuSubmenuTrigger.useButton({
5206
+ } = useBaseUiId.useButton({
5506
5207
  native: false
5507
5208
  });
5508
5209
  const mergedRef = useRenderElement.useMergedRefs(forwardedRef, buttonRef);
5509
- const handleDismiss = DrawerRoot.useStableCallback(event => {
5510
- store.state.setOpen(false, DrawerRoot.createChangeEventDetails(DrawerRoot.closePress, event.nativeEvent, event.currentTarget));
5210
+ const handleDismiss = useValueChanged.useStableCallback(event => {
5211
+ store.state.setOpen(false, useValueChanged.createChangeEventDetails(useValueChanged.closePress, event.nativeEvent, event.currentTarget));
5511
5212
  });
5512
5213
  const dismissProps = getButtonProps({
5513
5214
  onClick: handleDismiss
@@ -5517,7 +5218,7 @@ const ComboboxInternalDismissButton = /*#__PURE__*/React__namespace.forwardRef(f
5517
5218
  ...dismissProps,
5518
5219
  "aria-label": "Dismiss",
5519
5220
  tabIndex: undefined,
5520
- style: DrawerRoot.visuallyHiddenInput
5221
+ style: useValueChanged.visuallyHiddenInput
5521
5222
  });
5522
5223
  });
5523
5224
  if (process.env.NODE_ENV !== "production") ComboboxInternalDismissButton.displayName = "ComboboxInternalDismissButton";
@@ -5537,10 +5238,10 @@ const ComboboxInput = /*#__PURE__*/React__namespace.forwardRef(function Combobox
5537
5238
  setFocused,
5538
5239
  validationMode,
5539
5240
  validation
5540
- } = useFieldRootContext();
5241
+ } = NumberFieldInput.useFieldRootContext();
5541
5242
  const {
5542
5243
  labelId: fieldLabelId
5543
- } = useLabelableContext();
5244
+ } = NumberFieldInput.useLabelableContext();
5544
5245
  const comboboxChipsContext = useComboboxChipsContext();
5545
5246
  const positioning = useComboboxPositionerContext(true);
5546
5247
  const hasPositionerParent = Boolean(positioning);
@@ -5574,17 +5275,17 @@ const ComboboxInput = /*#__PURE__*/React__namespace.forwardRef(function Combobox
5574
5275
  const listEmpty = filteredItems.length === 0;
5575
5276
  const isInsidePopup = hasPositionerParent || inline;
5576
5277
  const focusManagerModal = !isInsidePopup || modal;
5577
- const id = MenuSubmenuTrigger.useBaseUiId(idProp ?? (!isInsidePopup ? rootId : undefined));
5278
+ const id = useBaseUiId.useBaseUiId(idProp ?? (!isInsidePopup ? rootId : undefined));
5578
5279
  const ariaLabelledBy = resolveAriaLabelledBy(fieldLabelId, undefined);
5579
- const fieldStateForInput = hasPositionerParent ? DEFAULT_FIELD_STATE_ATTRIBUTES : fieldState;
5280
+ const fieldStateForInput = hasPositionerParent ? NumberFieldInput.DEFAULT_FIELD_STATE_ATTRIBUTES : fieldState;
5580
5281
  const [composingValue, setComposingValue] = React__namespace.useState(null);
5581
5282
  const isComposingRef = React__namespace.useRef(false);
5582
5283
  const lastActiveIndexRef = React__namespace.useRef(null);
5583
5284
  const shouldRestoreActiveIndexRef = React__namespace.useRef(false);
5584
- const setInputElement = DrawerRoot.useStableCallback(element => {
5285
+ const setInputElement = useValueChanged.useStableCallback(element => {
5585
5286
  const nextIsInsidePopup = hasPositionerParent || store.state.inline;
5586
5287
  if (nextIsInsidePopup && !store.state.hasInputValue) {
5587
- store.state.setInputValue('', DrawerRoot.createChangeEventDetails(DrawerRoot.none));
5288
+ store.state.setInputValue('', useValueChanged.createChangeEventDetails(useValueChanged.none));
5588
5289
  }
5589
5290
  store.update({
5590
5291
  inputElement: element,
@@ -5702,7 +5403,7 @@ const ComboboxInput = /*#__PURE__*/React__namespace.forwardRef(function Combobox
5702
5403
  }
5703
5404
  },
5704
5405
  onCompositionStart(event) {
5705
- if (DrawerRoot.isAndroid) {
5406
+ if (useValueChanged.isAndroid) {
5706
5407
  return;
5707
5408
  }
5708
5409
  isComposingRef.current = true;
@@ -5712,7 +5413,7 @@ const ComboboxInput = /*#__PURE__*/React__namespace.forwardRef(function Combobox
5712
5413
  isComposingRef.current = false;
5713
5414
  const next = event.currentTarget.value;
5714
5415
  setComposingValue(null);
5715
- store.state.setInputValue(next, DrawerRoot.createChangeEventDetails(DrawerRoot.inputChange, event.nativeEvent));
5416
+ store.state.setInputValue(next, useValueChanged.createChangeEventDetails(useValueChanged.inputChange, event.nativeEvent));
5716
5417
  },
5717
5418
  onChange(event) {
5718
5419
  // Autofill may not provide `inputType` (Chrome) or may report
@@ -5731,13 +5432,13 @@ const ComboboxInput = /*#__PURE__*/React__namespace.forwardRef(function Combobox
5731
5432
  const nextVal = event.currentTarget.value;
5732
5433
  setComposingValue(nextVal);
5733
5434
  if (nextVal === '' && !store.state.openOnInputClick && !store.state.inputInsidePopup) {
5734
- store.state.setOpen(false, DrawerRoot.createChangeEventDetails(DrawerRoot.inputClear, event.nativeEvent));
5435
+ store.state.setOpen(false, useValueChanged.createChangeEventDetails(useValueChanged.inputClear, event.nativeEvent));
5735
5436
  }
5736
5437
  const trimmed = nextVal.trim();
5737
5438
  const shouldMaintainHighlight = autoHighlightEnabled && trimmed !== '';
5738
5439
  if (!readOnly && !disabled && trimmed) {
5739
5440
  if (shouldOpenOnInput) {
5740
- store.state.setOpen(true, DrawerRoot.createChangeEventDetails(DrawerRoot.inputChange, event.nativeEvent));
5441
+ store.state.setOpen(true, useValueChanged.createChangeEventDetails(useValueChanged.inputChange, event.nativeEvent));
5741
5442
  if (!autoHighlightEnabled) {
5742
5443
  store.state.setIndices({
5743
5444
  activeIndex: null,
@@ -5756,9 +5457,9 @@ const ComboboxInput = /*#__PURE__*/React__namespace.forwardRef(function Combobox
5756
5457
  }
5757
5458
  return;
5758
5459
  }
5759
- store.state.setInputValue(event.currentTarget.value, DrawerRoot.createChangeEventDetails(DrawerRoot.inputChange, event.nativeEvent));
5460
+ store.state.setInputValue(event.currentTarget.value, useValueChanged.createChangeEventDetails(useValueChanged.inputChange, event.nativeEvent));
5760
5461
  const empty = event.currentTarget.value === '';
5761
- const clearDetails = DrawerRoot.createChangeEventDetails(DrawerRoot.inputClear, event.nativeEvent);
5462
+ const clearDetails = useValueChanged.createChangeEventDetails(useValueChanged.inputClear, event.nativeEvent);
5762
5463
  if (empty && !store.state.inputInsidePopup) {
5763
5464
  if (selectionMode === 'single') {
5764
5465
  store.state.setSelectedValue(null, clearDetails);
@@ -5770,7 +5471,7 @@ const ComboboxInput = /*#__PURE__*/React__namespace.forwardRef(function Combobox
5770
5471
  const trimmed = event.currentTarget.value.trim();
5771
5472
  if (!readOnly && !disabled && trimmed) {
5772
5473
  if (shouldOpenOnInput) {
5773
- store.state.setOpen(true, DrawerRoot.createChangeEventDetails(DrawerRoot.inputChange, event.nativeEvent));
5474
+ store.state.setOpen(true, useValueChanged.createChangeEventDetails(useValueChanged.inputChange, event.nativeEvent));
5774
5475
  // When autoHighlight is enabled, keep the highlight (will be set to 0 in root).
5775
5476
  if (!autoHighlightEnabled) {
5776
5477
  store.state.setIndices({
@@ -5805,22 +5506,22 @@ const ComboboxInput = /*#__PURE__*/React__namespace.forwardRef(function Combobox
5805
5506
  const scrollAmount = input.scrollWidth - input.clientWidth;
5806
5507
  const isRTL = direction === 'rtl';
5807
5508
  if (event.key === 'Home') {
5808
- DrawerRoot.stopEvent(event);
5809
- const cursor = DrawerRoot.isFirefox && isRTL ? input.value.length : 0;
5509
+ useValueChanged.stopEvent(event);
5510
+ const cursor = useValueChanged.isFirefox && isRTL ? input.value.length : 0;
5810
5511
  input.setSelectionRange(cursor, cursor);
5811
5512
  input.scrollLeft = 0;
5812
5513
  return;
5813
5514
  }
5814
5515
  if (event.key === 'End') {
5815
- DrawerRoot.stopEvent(event);
5816
- const cursor = DrawerRoot.isFirefox && isRTL ? 0 : input.value.length;
5516
+ useValueChanged.stopEvent(event);
5517
+ const cursor = useValueChanged.isFirefox && isRTL ? 0 : input.value.length;
5817
5518
  input.setSelectionRange(cursor, cursor);
5818
5519
  input.scrollLeft = isRTL ? -scrollAmount : scrollAmount;
5819
5520
  return;
5820
5521
  }
5821
5522
  if (!mounted && event.key === 'Escape') {
5822
5523
  const isClear = selectionMode === 'multiple' && Array.isArray(selectedValue) ? selectedValue.length === 0 : selectedValue === null;
5823
- const details = DrawerRoot.createChangeEventDetails(DrawerRoot.escapeKey, event.nativeEvent);
5524
+ const details = useValueChanged.createChangeEventDetails(useValueChanged.escapeKey, event.nativeEvent);
5824
5525
  const value = selectionMode === 'multiple' ? [] : null;
5825
5526
  store.state.setInputValue('', details);
5826
5527
  store.state.setSelectedValue(value, details);
@@ -5839,7 +5540,7 @@ const ComboboxInput = /*#__PURE__*/React__namespace.forwardRef(function Combobox
5839
5540
  selectedIndex: null,
5840
5541
  type: store.state.keyboardActiveRef.current ? 'keyboard' : 'pointer'
5841
5542
  });
5842
- store.state.setSelectedValue(newValue, DrawerRoot.createChangeEventDetails(DrawerRoot.none, event.nativeEvent));
5543
+ store.state.setSelectedValue(newValue, useValueChanged.createChangeEventDetails(useValueChanged.none, event.nativeEvent));
5843
5544
  return;
5844
5545
  }
5845
5546
  const hadHighlightedChip = comboboxChipsContext?.highlightedChipIndex !== undefined;
@@ -5864,10 +5565,10 @@ const ComboboxInput = /*#__PURE__*/React__namespace.forwardRef(function Combobox
5864
5565
  }
5865
5566
 
5866
5567
  // Allow form submission when no item is highlighted.
5867
- store.state.setOpen(false, DrawerRoot.createChangeEventDetails(DrawerRoot.none, nativeEvent));
5568
+ store.state.setOpen(false, useValueChanged.createChangeEventDetails(useValueChanged.none, nativeEvent));
5868
5569
  return;
5869
5570
  }
5870
- DrawerRoot.stopEvent(event);
5571
+ useValueChanged.stopEvent(event);
5871
5572
  const listItem = store.state.listRef.current[activeIndex];
5872
5573
  if (listItem) {
5873
5574
  store.state.selectionEventRef.current = nativeEvent;
@@ -5906,7 +5607,7 @@ const ComboboxInputGroup = /*#__PURE__*/React__namespace.forwardRef(function Com
5906
5607
  const {
5907
5608
  state: fieldState,
5908
5609
  disabled: fieldDisabled
5909
- } = useFieldRootContext();
5610
+ } = NumberFieldInput.useFieldRootContext();
5910
5611
  const store = useComboboxRootContext();
5911
5612
  const {
5912
5613
  filteredItems
@@ -5932,7 +5633,7 @@ const ComboboxInputGroup = /*#__PURE__*/React__namespace.forwardRef(function Com
5932
5633
  listEmpty,
5933
5634
  placeholder
5934
5635
  };
5935
- const setInputGroupElement = DrawerRoot.useStableCallback(element => {
5636
+ const setInputGroupElement = useValueChanged.useStableCallback(element => {
5936
5637
  store.set('inputGroupElement', element);
5937
5638
  });
5938
5639
  return useRenderElement.useRenderElement('div', componentProps, {
@@ -5967,8 +5668,8 @@ const ComboboxIcon = /*#__PURE__*/React__namespace.forwardRef(function ComboboxI
5967
5668
  });
5968
5669
  if (process.env.NODE_ENV !== "production") ComboboxIcon.displayName = "ComboboxIcon";
5969
5670
 
5970
- const stateAttributesMapping$4 = {
5971
- ...DrawerRoot.transitionStatusMapping,
5671
+ const stateAttributesMapping$2 = {
5672
+ ...useValueChanged.transitionStatusMapping,
5972
5673
  ...DrawerRoot.triggerOpenStateMapping
5973
5674
  };
5974
5675
 
@@ -5987,7 +5688,7 @@ const ComboboxClear = /*#__PURE__*/React__namespace.forwardRef(function Combobox
5987
5688
  } = componentProps;
5988
5689
  const {
5989
5690
  disabled: fieldDisabled
5990
- } = useFieldRootContext();
5691
+ } = NumberFieldInput.useFieldRootContext();
5991
5692
  const store = useComboboxRootContext();
5992
5693
  const selectionMode = DrawerRoot.useStore(store, selectors.selectionMode);
5993
5694
  const comboboxDisabled = DrawerRoot.useStore(store, selectors.disabled);
@@ -6008,7 +5709,7 @@ const ComboboxClear = /*#__PURE__*/React__namespace.forwardRef(function Combobox
6008
5709
  const {
6009
5710
  buttonRef,
6010
5711
  getButtonProps
6011
- } = MenuSubmenuTrigger.useButton({
5712
+ } = useBaseUiId.useButton({
6012
5713
  native: nativeButton,
6013
5714
  disabled
6014
5715
  });
@@ -6016,13 +5717,13 @@ const ComboboxClear = /*#__PURE__*/React__namespace.forwardRef(function Combobox
6016
5717
  mounted,
6017
5718
  transitionStatus,
6018
5719
  setMounted
6019
- } = DrawerRoot.useTransitionStatus(visible);
5720
+ } = useValueChanged.useTransitionStatus(visible);
6020
5721
  const state = {
6021
5722
  disabled,
6022
5723
  open,
6023
5724
  transitionStatus
6024
5725
  };
6025
- DrawerRoot.useOpenChangeComplete({
5726
+ useValueChanged.useOpenChangeComplete({
6026
5727
  open: visible,
6027
5728
  ref: store.state.clearRef,
6028
5729
  onComplete() {
@@ -6046,9 +5747,9 @@ const ComboboxClear = /*#__PURE__*/React__namespace.forwardRef(function Combobox
6046
5747
  return;
6047
5748
  }
6048
5749
  const keyboardActiveRef = store.state.keyboardActiveRef;
6049
- store.state.setInputValue('', DrawerRoot.createChangeEventDetails(DrawerRoot.clearPress, event.nativeEvent));
5750
+ store.state.setInputValue('', useValueChanged.createChangeEventDetails(useValueChanged.clearPress, event.nativeEvent));
6050
5751
  if (selectionMode !== 'none') {
6051
- store.state.setSelectedValue(Array.isArray(selectedValue) ? [] : null, DrawerRoot.createChangeEventDetails(DrawerRoot.clearPress, event.nativeEvent));
5752
+ store.state.setSelectedValue(Array.isArray(selectedValue) ? [] : null, useValueChanged.createChangeEventDetails(useValueChanged.clearPress, event.nativeEvent));
6052
5753
  store.state.setIndices({
6053
5754
  activeIndex: null,
6054
5755
  selectedIndex: null,
@@ -6063,7 +5764,7 @@ const ComboboxClear = /*#__PURE__*/React__namespace.forwardRef(function Combobox
6063
5764
  store.state.inputRef.current?.focus();
6064
5765
  }
6065
5766
  }, elementProps, getButtonProps],
6066
- stateAttributesMapping: stateAttributesMapping$4
5767
+ stateAttributesMapping: stateAttributesMapping$2
6067
5768
  });
6068
5769
  const shouldRender = keepMounted || mounted;
6069
5770
  if (!shouldRender) {
@@ -6134,10 +5835,10 @@ const ComboboxList = /*#__PURE__*/React__namespace.forwardRef(function ComboboxL
6134
5835
  const virtualized = DrawerRoot.useStore(store, selectors.virtualized);
6135
5836
  const multiple = selectionMode === 'multiple';
6136
5837
  const empty = filteredItems.length === 0;
6137
- const setPositionerElement = DrawerRoot.useStableCallback(element => {
5838
+ const setPositionerElement = useValueChanged.useStableCallback(element => {
6138
5839
  store.set('positionerElement', element);
6139
5840
  });
6140
- const setListElement = DrawerRoot.useStableCallback(element => {
5841
+ const setListElement = useValueChanged.useStableCallback(element => {
6141
5842
  store.set('listElement', element);
6142
5843
  });
6143
5844
 
@@ -6176,7 +5877,7 @@ const ComboboxList = /*#__PURE__*/React__namespace.forwardRef(function ComboboxL
6176
5877
  // Allow form submission when no item is highlighted.
6177
5878
  return;
6178
5879
  }
6179
- DrawerRoot.stopEvent(event);
5880
+ useValueChanged.stopEvent(event);
6180
5881
  const nativeEvent = event.nativeEvent;
6181
5882
  const listItem = store.state.listRef.current[activeIndex];
6182
5883
  if (listItem) {
@@ -6259,9 +5960,9 @@ const ComboboxPortal = /*#__PURE__*/React__namespace.forwardRef(function Combobo
6259
5960
  });
6260
5961
  if (process.env.NODE_ENV !== "production") ComboboxPortal.displayName = "ComboboxPortal";
6261
5962
 
6262
- const stateAttributesMapping$3 = {
5963
+ const stateAttributesMapping$1 = {
6263
5964
  ...DrawerRoot.popupStateMapping,
6264
- ...DrawerRoot.transitionStatusMapping
5965
+ ...useValueChanged.transitionStatusMapping
6265
5966
  };
6266
5967
 
6267
5968
  /**
@@ -6285,7 +5986,7 @@ const ComboboxBackdrop = /*#__PURE__*/React__namespace.forwardRef(function Combo
6285
5986
  return useRenderElement.useRenderElement('div', componentProps, {
6286
5987
  state,
6287
5988
  ref: forwardedRef,
6288
- stateAttributesMapping: stateAttributesMapping$3,
5989
+ stateAttributesMapping: stateAttributesMapping$1,
6289
5990
  props: [{
6290
5991
  role: 'presentation',
6291
5992
  hidden: !mounted,
@@ -6372,7 +6073,7 @@ const ComboboxPositioner = /*#__PURE__*/React__namespace.forwardRef(function Com
6372
6073
  anchorHidden: positioning.anchorHidden,
6373
6074
  empty
6374
6075
  };
6375
- DrawerRoot.useIsoLayoutEffect(() => {
6076
+ useValueChanged.useIsoLayoutEffect(() => {
6376
6077
  store.set('popupSide', positioning.side);
6377
6078
  }, [store, positioning.side]);
6378
6079
  const contextValue = React__namespace.useMemo(() => ({
@@ -6384,7 +6085,7 @@ const ComboboxPositioner = /*#__PURE__*/React__namespace.forwardRef(function Com
6384
6085
  anchorHidden: positioning.anchorHidden,
6385
6086
  isPositioned: positioning.isPositioned
6386
6087
  }), [positioning.side, positioning.align, positioning.arrowRef, positioning.arrowUncentered, positioning.arrowStyles, positioning.anchorHidden, positioning.isPositioned]);
6387
- const setPositionerElement = DrawerRoot.useStableCallback(element => {
6088
+ const setPositionerElement = useValueChanged.useStableCallback(element => {
6388
6089
  store.set('positionerElement', element);
6389
6090
  });
6390
6091
  const element = useRenderElement.useRenderElement('div', componentProps, {
@@ -6403,9 +6104,9 @@ const ComboboxPositioner = /*#__PURE__*/React__namespace.forwardRef(function Com
6403
6104
  });
6404
6105
  if (process.env.NODE_ENV !== "production") ComboboxPositioner.displayName = "ComboboxPositioner";
6405
6106
 
6406
- const stateAttributesMapping$2 = {
6107
+ const stateAttributesMapping = {
6407
6108
  ...DrawerRoot.popupStateMapping,
6408
- ...DrawerRoot.transitionStatusMapping
6109
+ ...useValueChanged.transitionStatusMapping
6409
6110
  };
6410
6111
 
6411
6112
  /**
@@ -6434,7 +6135,7 @@ const ComboboxPopup = /*#__PURE__*/React__namespace.forwardRef(function Combobox
6434
6135
  const inputElement = DrawerRoot.useStore(store, selectors.inputElement);
6435
6136
  const modal = DrawerRoot.useStore(store, selectors.modal);
6436
6137
  const empty = filteredItems.length === 0;
6437
- DrawerRoot.useOpenChangeComplete({
6138
+ useValueChanged.useOpenChangeComplete({
6438
6139
  open,
6439
6140
  ref: store.state.popupRef,
6440
6141
  onComplete() {
@@ -6464,7 +6165,7 @@ const ComboboxPopup = /*#__PURE__*/React__namespace.forwardRef(function Combobox
6464
6165
  }
6465
6166
  }
6466
6167
  }, MenuSubmenuTrigger.getDisabledMountTransitionStyles(transitionStatus), elementProps],
6467
- stateAttributesMapping: stateAttributesMapping$2
6168
+ stateAttributesMapping
6468
6169
  });
6469
6170
 
6470
6171
  // Default initial focus logic:
@@ -6592,8 +6293,8 @@ const ComboboxGroupLabel = /*#__PURE__*/React__namespace.forwardRef(function Com
6592
6293
  const {
6593
6294
  setLabelId
6594
6295
  } = useComboboxGroupContext();
6595
- const id = MenuSubmenuTrigger.useBaseUiId(idProp);
6596
- DrawerRoot.useIsoLayoutEffect(() => {
6296
+ const id = useBaseUiId.useBaseUiId(idProp);
6297
+ useValueChanged.useIsoLayoutEffect(() => {
6597
6298
  setLabelId(id);
6598
6299
  return () => {
6599
6300
  setLabelId(undefined);
@@ -6663,7 +6364,7 @@ const ComboboxItem = /*#__PURE__*/React__namespace.memo(/*#__PURE__*/React__name
6663
6364
  const itemRef = React__namespace.useRef(null);
6664
6365
  const id = rootId != null && hasRegistered ? `${rootId}-${index}` : undefined;
6665
6366
  const selected = matchesSelectedValue && selectable;
6666
- DrawerRoot.useIsoLayoutEffect(() => {
6367
+ useValueChanged.useIsoLayoutEffect(() => {
6667
6368
  const shouldRun = hasRegistered && (virtualized || indexProp != null);
6668
6369
  if (!shouldRun) {
6669
6370
  return undefined;
@@ -6674,7 +6375,7 @@ const ComboboxItem = /*#__PURE__*/React__namespace.memo(/*#__PURE__*/React__name
6674
6375
  delete list[index];
6675
6376
  };
6676
6377
  }, [hasRegistered, virtualized, index, indexProp, store]);
6677
- DrawerRoot.useIsoLayoutEffect(() => {
6378
+ useValueChanged.useIsoLayoutEffect(() => {
6678
6379
  if (!hasRegistered || hasItems) {
6679
6380
  return undefined;
6680
6381
  }
@@ -6691,7 +6392,7 @@ const ComboboxItem = /*#__PURE__*/React__namespace.memo(/*#__PURE__*/React__name
6691
6392
  delete visibleMap[index];
6692
6393
  };
6693
6394
  }, [hasRegistered, hasItems, index, itemValue, store, selectionMode]);
6694
- DrawerRoot.useIsoLayoutEffect(() => {
6395
+ useValueChanged.useIsoLayoutEffect(() => {
6695
6396
  if (!open) {
6696
6397
  didPointerDownRef.current = false;
6697
6398
  return;
@@ -6719,7 +6420,7 @@ const ComboboxItem = /*#__PURE__*/React__namespace.memo(/*#__PURE__*/React__name
6719
6420
  const {
6720
6421
  getButtonProps,
6721
6422
  buttonRef
6722
- } = MenuSubmenuTrigger.useButton({
6423
+ } = useBaseUiId.useButton({
6723
6424
  disabled,
6724
6425
  focusableWhenDisabled: true,
6725
6426
  native: nativeButton,
@@ -6856,8 +6557,8 @@ function ComboboxRoot(props) {
6856
6557
  }
6857
6558
 
6858
6559
  function useRegisteredLabelId(idProp, setLabelId) {
6859
- const id = MenuSubmenuTrigger.useBaseUiId(idProp);
6860
- DrawerRoot.useIsoLayoutEffect(() => {
6560
+ const id = useBaseUiId.useBaseUiId(idProp);
6561
+ useValueChanged.useIsoLayoutEffect(() => {
6861
6562
  setLabelId(id);
6862
6563
  return () => {
6863
6564
  setLabelId(undefined);
@@ -6877,8 +6578,8 @@ function useLabel(params = {}) {
6877
6578
  const {
6878
6579
  controlId: contextControlId,
6879
6580
  setLabelId: setContextLabelId
6880
- } = useLabelableContext();
6881
- const syncLabelId = DrawerRoot.useStableCallback(nextLabelId => {
6581
+ } = NumberFieldInput.useLabelableContext();
6582
+ const syncLabelId = useValueChanged.useStableCallback(nextLabelId => {
6882
6583
  setContextLabelId(nextLabelId);
6883
6584
  setLabelIdProp?.(nextLabelId);
6884
6585
  });
@@ -6892,8 +6593,8 @@ function useLabel(params = {}) {
6892
6593
  if (!resolvedControlId) {
6893
6594
  return;
6894
6595
  }
6895
- const controlElement = DrawerRoot.ownerDocument(event.currentTarget).getElementById(resolvedControlId);
6896
- if (index_esm.isHTMLElement(controlElement)) {
6596
+ const controlElement = useValueChanged.ownerDocument(event.currentTarget).getElementById(resolvedControlId);
6597
+ if (floatingUi_utils_dom.isHTMLElement(controlElement)) {
6897
6598
  focusElementWithVisible(controlElement);
6898
6599
  }
6899
6600
  }
@@ -6948,7 +6649,7 @@ const ComboboxLabel = /*#__PURE__*/React__namespace.forwardRef(function Combobox
6948
6649
  // Keep label id derived from the root and ignore runtime `id` overrides from untyped consumers.
6949
6650
  const elementPropsWithoutId = elementProps;
6950
6651
  delete elementPropsWithoutId.id;
6951
- const fieldRootContext = useFieldRootContext();
6652
+ const fieldRootContext = NumberFieldInput.useFieldRootContext();
6952
6653
  const store = useComboboxRootContext();
6953
6654
  const inputInsidePopup = DrawerRoot.useStore(store, selectors.inputInsidePopup);
6954
6655
  const triggerElement = DrawerRoot.useStore(store, selectors.triggerElement);
@@ -6962,9 +6663,9 @@ const ComboboxLabel = /*#__PURE__*/React__namespace.forwardRef(function Combobox
6962
6663
  if (!inputElement || inputInsidePopup) {
6963
6664
  return;
6964
6665
  }
6965
- const ownerStackMessage = DrawerRoot.SafeReact.captureOwnerStack?.() || '';
6666
+ const ownerStackMessage = useValueChanged.SafeReact.captureOwnerStack?.() || '';
6966
6667
  const message = '<Combobox.Label> labels <Combobox.Trigger> only. ' + 'When <Combobox.Input> is the form control, use a native <label> or <Field.Label> instead.';
6967
- MenuSubmenuTrigger.error(`${message}${ownerStackMessage}`);
6668
+ useBaseUiId.error(`${message}${ownerStackMessage}`);
6968
6669
  }, [inputElement, inputInsidePopup]);
6969
6670
  }
6970
6671
  const labelProps = useLabel({
@@ -6978,7 +6679,7 @@ const ComboboxLabel = /*#__PURE__*/React__namespace.forwardRef(function Combobox
6978
6679
  ref: forwardedRef,
6979
6680
  state: fieldRootContext.state,
6980
6681
  props: [labelProps, elementProps],
6981
- stateAttributesMapping: fieldValidityMapping
6682
+ stateAttributesMapping: NumberFieldInput.fieldValidityMapping
6982
6683
  });
6983
6684
  });
6984
6685
  if (process.env.NODE_ENV !== "production") ComboboxLabel.displayName = "ComboboxLabel";
@@ -7047,7 +6748,7 @@ const Inner = /*#__PURE__*/React__namespace.memo(/*#__PURE__*/React__namespace.f
7047
6748
  const {
7048
6749
  transitionStatus,
7049
6750
  setMounted
7050
- } = DrawerRoot.useTransitionStatus(selected);
6751
+ } = useValueChanged.useTransitionStatus(selected);
7051
6752
  const state = {
7052
6753
  selected,
7053
6754
  transitionStatus
@@ -7059,9 +6760,9 @@ const Inner = /*#__PURE__*/React__namespace.memo(/*#__PURE__*/React__namespace.f
7059
6760
  'aria-hidden': true,
7060
6761
  children: '✔️'
7061
6762
  }, elementProps],
7062
- stateAttributesMapping: DrawerRoot.transitionStatusMapping
6763
+ stateAttributesMapping: useValueChanged.transitionStatusMapping
7063
6764
  });
7064
- DrawerRoot.useOpenChangeComplete({
6765
+ useValueChanged.useOpenChangeComplete({
7065
6766
  open: selected,
7066
6767
  ref: indicatorRef,
7067
6768
  onComplete() {
@@ -7158,19 +6859,19 @@ const ComboboxChip = /*#__PURE__*/React__namespace.forwardRef(function ComboboxC
7158
6859
  } else if (event.key === 'Backspace' || event.key === 'Delete') {
7159
6860
  const computedNextIndex = index >= selectedValue.length - 1 ? selectedValue.length - 2 : index;
7160
6861
  nextIndex = computedNextIndex >= 0 ? computedNextIndex : undefined;
7161
- DrawerRoot.stopEvent(event);
6862
+ useValueChanged.stopEvent(event);
7162
6863
  store.state.setIndices({
7163
6864
  activeIndex: null,
7164
6865
  selectedIndex: null,
7165
6866
  type: 'keyboard'
7166
6867
  });
7167
- store.state.setSelectedValue(selectedValue.filter((_, i) => i !== index), DrawerRoot.createChangeEventDetails(DrawerRoot.none, event.nativeEvent));
6868
+ store.state.setSelectedValue(selectedValue.filter((_, i) => i !== index), useValueChanged.createChangeEventDetails(useValueChanged.none, event.nativeEvent));
7168
6869
  } else if (event.key === 'Enter' || event.key === ' ') {
7169
- DrawerRoot.stopEvent(event);
6870
+ useValueChanged.stopEvent(event);
7170
6871
  nextIndex = undefined;
7171
6872
  } else if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
7172
- DrawerRoot.stopEvent(event);
7173
- store.state.setOpen(true, DrawerRoot.createChangeEventDetails(DrawerRoot.listNavigation, event.nativeEvent));
6873
+ useValueChanged.stopEvent(event);
6874
+ store.state.setOpen(true, useValueChanged.createChangeEventDetails(useValueChanged.listNavigation, event.nativeEvent));
7174
6875
  nextIndex = undefined;
7175
6876
  } else if (
7176
6877
  // Check for printable characters (letters, numbers, symbols)
@@ -7249,7 +6950,7 @@ const ComboboxChipRemove = /*#__PURE__*/React__namespace.forwardRef(function Com
7249
6950
  const {
7250
6951
  buttonRef,
7251
6952
  getButtonProps
7252
- } = MenuSubmenuTrigger.useButton({
6953
+ } = useBaseUiId.useButton({
7253
6954
  native: nativeButton,
7254
6955
  disabled: disabled || readOnly,
7255
6956
  focusableWhenDisabled: true
@@ -7274,7 +6975,7 @@ const ComboboxChipRemove = /*#__PURE__*/React__namespace.forwardRef(function Com
7274
6975
  }
7275
6976
  }
7276
6977
  function removeChip(event) {
7277
- const eventDetails = DrawerRoot.createChangeEventDetails(DrawerRoot.chipRemovePress, event.nativeEvent);
6978
+ const eventDetails = useValueChanged.createChangeEventDetails(useValueChanged.chipRemovePress, event.nativeEvent);
7278
6979
  const removedItem = selectedValue[index];
7279
6980
  clearActiveIndexForRemovedItem(removedItem);
7280
6981
  store.state.setSelectedValue(selectedValue.filter((_, i) => i !== index), eventDetails);
@@ -7302,7 +7003,7 @@ const ComboboxChipRemove = /*#__PURE__*/React__namespace.forwardRef(function Com
7302
7003
  if (event.key === 'Enter' || event.key === ' ') {
7303
7004
  const eventDetails = removeChip(event);
7304
7005
  if (!eventDetails.isPropagationAllowed) {
7305
- DrawerRoot.stopEvent(event);
7006
+ useValueChanged.stopEvent(event);
7306
7007
  }
7307
7008
  }
7308
7009
  }
@@ -7344,1482 +7045,6 @@ var index_parts$1 = /*#__PURE__*/Object.freeze({
7344
7045
  useFilteredItems: useFilteredItems
7345
7046
  });
7346
7047
 
7347
- const cache = new Map();
7348
- function getFormatter(locale, options) {
7349
- const optionsString = JSON.stringify({
7350
- locale,
7351
- options
7352
- });
7353
- const cachedFormatter = cache.get(optionsString);
7354
- if (cachedFormatter) {
7355
- return cachedFormatter;
7356
- }
7357
- const formatter = new Intl.NumberFormat(locale, options);
7358
- cache.set(optionsString, formatter);
7359
- return formatter;
7360
- }
7361
- function formatNumber(value, locale, options) {
7362
- if (value == null) {
7363
- return '';
7364
- }
7365
- return getFormatter(locale, options).format(value);
7366
- }
7367
- function formatNumberMaxPrecision(value, locale, options) {
7368
- return formatNumber(value, locale, {
7369
- ...options,
7370
- maximumFractionDigits: 20
7371
- });
7372
- }
7373
-
7374
- const EMPTY = 0;
7375
- class Interval extends DrawerRoot.Timeout {
7376
- static create() {
7377
- return new Interval();
7378
- }
7379
-
7380
- /**
7381
- * Executes `fn` at `delay` interval, clearing any previously scheduled call.
7382
- */
7383
- start(delay, fn) {
7384
- this.clear();
7385
- this.currentId = setInterval(() => {
7386
- fn();
7387
- }, delay);
7388
- }
7389
- clear = () => {
7390
- if (this.currentId !== EMPTY) {
7391
- clearInterval(this.currentId);
7392
- this.currentId = EMPTY;
7393
- }
7394
- };
7395
- }
7396
-
7397
- /**
7398
- * A `setInterval` with automatic cleanup and guard.
7399
- */
7400
- function useInterval() {
7401
- const timeout = useRenderElement.useRefWithInit(Interval.create).current;
7402
- DrawerRoot.useOnMount(timeout.disposeEffect);
7403
- return timeout;
7404
- }
7405
-
7406
- const NumberFieldRootContext = /*#__PURE__*/React__namespace.createContext(undefined);
7407
- if (process.env.NODE_ENV !== "production") NumberFieldRootContext.displayName = "NumberFieldRootContext";
7408
- function useNumberFieldRootContext() {
7409
- const context = React__namespace.useContext(NumberFieldRootContext);
7410
- if (context === undefined) {
7411
- throw new Error(process.env.NODE_ENV !== "production" ? 'Base UI: NumberFieldRootContext is missing. NumberField parts must be placed within <NumberField.Root>.' : useRenderElement.formatErrorMessage(43));
7412
- }
7413
- return context;
7414
- }
7415
-
7416
- const stateAttributesMapping$1 = {
7417
- inputValue: () => null,
7418
- value: () => null,
7419
- ...fieldValidityMapping
7420
- };
7421
-
7422
- const HAN_NUMERALS = ['零', '〇', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
7423
- // Map Han numeral characters to ASCII digits. Includes both forms of zero.
7424
- const HAN_NUMERAL_TO_DIGIT = {
7425
- 零: '0',
7426
- 〇: '0',
7427
- 一: '1',
7428
- 二: '2',
7429
- 三: '3',
7430
- 四: '4',
7431
- 五: '5',
7432
- 六: '6',
7433
- 七: '7',
7434
- 八: '8',
7435
- 九: '9'
7436
- };
7437
- const ARABIC_NUMERALS = ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'];
7438
- const PERSIAN_NUMERALS = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
7439
- const FULLWIDTH_NUMERALS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
7440
- const PERCENTAGES = ['%', '٪', '%', '﹪'];
7441
- const PERMILLE = ['‰', '؉'];
7442
- const UNICODE_MINUS_SIGNS = ['−', '-', '‒', '–', '—', '﹣'];
7443
- const UNICODE_PLUS_SIGNS = ['+', '﹢'];
7444
-
7445
- // Fullwidth punctuation common in CJK inputs
7446
- const FULLWIDTH_DECIMAL = '.'; // U+FF0E
7447
- const FULLWIDTH_GROUP = ','; // U+FF0C
7448
-
7449
- const ARABIC_RE = new RegExp(`[${ARABIC_NUMERALS.join('')}]`, 'g');
7450
- const PERSIAN_RE = new RegExp(`[${PERSIAN_NUMERALS.join('')}]`, 'g');
7451
- const FULLWIDTH_RE = new RegExp(`[${FULLWIDTH_NUMERALS.join('')}]`, 'g');
7452
- const HAN_RE = new RegExp(`[${HAN_NUMERALS.join('')}]`, 'g');
7453
- const PERCENT_RE = new RegExp(`[${PERCENTAGES.join('')}]`);
7454
- const PERMILLE_RE = new RegExp(`[${PERMILLE.join('')}]`);
7455
-
7456
- // Detection regexes (non-global to avoid lastIndex side effects)
7457
- const ARABIC_DETECT_RE = /[٠١٢٣٤٥٦٧٨٩]/;
7458
- const PERSIAN_DETECT_RE = /[۰۱۲۳۴۵۶۷۸۹]/;
7459
- const HAN_DETECT_RE = /[零〇一二三四五六七八九]/;
7460
- const FULLWIDTH_DETECT_RE = new RegExp(`[${FULLWIDTH_NUMERALS.join('')}]`);
7461
- const BASE_NON_NUMERIC_SYMBOLS = ['.', ',', FULLWIDTH_DECIMAL, FULLWIDTH_GROUP, '٫', '٬'];
7462
- const SPACE_SEPARATOR_RE = /\p{Zs}/u;
7463
- const PLUS_SIGNS_WITH_ASCII = ['+', ...UNICODE_PLUS_SIGNS];
7464
- const MINUS_SIGNS_WITH_ASCII = ['-', ...UNICODE_MINUS_SIGNS];
7465
- const escapeRegExp = s => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
7466
- const escapeClassChar = s => s.replace(/[-\\\]^]/g, m => `\\${m}`); // escape for use inside [...]
7467
-
7468
- const charClassFrom = chars => `[${chars.map(escapeClassChar).join('')}]`;
7469
- const ANY_MINUS_CLASS = charClassFrom(['-'].concat(UNICODE_MINUS_SIGNS));
7470
- const ANY_PLUS_CLASS = charClassFrom(['+'].concat(UNICODE_PLUS_SIGNS));
7471
- const ANY_MINUS_RE = new RegExp(ANY_MINUS_CLASS, 'gu');
7472
- const ANY_PLUS_RE = new RegExp(ANY_PLUS_CLASS, 'gu');
7473
- const ANY_MINUS_DETECT_RE = new RegExp(ANY_MINUS_CLASS);
7474
- const ANY_PLUS_DETECT_RE = new RegExp(ANY_PLUS_CLASS);
7475
- function getNumberLocaleDetails(locale, options) {
7476
- const parts = getFormatter(locale, options).formatToParts(11111.1);
7477
- const result = {};
7478
- parts.forEach(part => {
7479
- result[part.type] = part.value;
7480
- });
7481
-
7482
- // The formatting options may result in not returning a decimal.
7483
- getFormatter(locale).formatToParts(0.1).forEach(part => {
7484
- if (part.type === 'decimal') {
7485
- result[part.type] = part.value;
7486
- }
7487
- });
7488
- return result;
7489
- }
7490
- function parseNumber(formattedNumber, locale, options) {
7491
- if (formattedNumber == null) {
7492
- return null;
7493
- }
7494
-
7495
- // Normalize control characters and whitespace; remove bidi/format controls
7496
- let input = String(formattedNumber).replace(/\p{Cf}/gu, '').trim();
7497
-
7498
- // Normalize unicode minus/plus to ASCII, handle leading/trailing signs
7499
- input = input.replace(ANY_MINUS_RE, '-').replace(ANY_PLUS_RE, '+');
7500
- let isNegative = false;
7501
-
7502
- // Trailing sign, e.g. "1234-" / "1234+"
7503
- const trailing = input.match(/([+-])\s*$/);
7504
- if (trailing) {
7505
- if (trailing[1] === '-') {
7506
- isNegative = true;
7507
- }
7508
- input = input.replace(/([+-])\s*$/, '');
7509
- }
7510
- // Leading sign
7511
- const leading = input.match(/^\s*([+-])/);
7512
- if (leading) {
7513
- if (leading[1] === '-') {
7514
- isNegative = true;
7515
- }
7516
- input = input.replace(/^\s*[+-]/, '');
7517
- }
7518
-
7519
- // Heuristic locale detection
7520
- let computedLocale = locale;
7521
- if (computedLocale === undefined) {
7522
- if (ARABIC_DETECT_RE.test(input) || PERSIAN_DETECT_RE.test(input)) {
7523
- computedLocale = 'ar';
7524
- } else if (HAN_DETECT_RE.test(input)) {
7525
- computedLocale = 'zh';
7526
- }
7527
- }
7528
- const {
7529
- group,
7530
- decimal,
7531
- currency
7532
- } = getNumberLocaleDetails(computedLocale, options);
7533
-
7534
- // Build robust unit regex from all unit parts (such as "km/h")
7535
- const unitParts = getFormatter(computedLocale, options).formatToParts(1).filter(p => p.type === 'unit').map(p => escapeRegExp(p.value));
7536
- const unitRegex = unitParts.length ? new RegExp(unitParts.join('|'), 'g') : null;
7537
- let groupRegex = null;
7538
- if (group) {
7539
- const isSpaceGroup = /\p{Zs}/u.test(group);
7540
- const isApostropheGroup = group === "'" || group === '’';
7541
-
7542
- // Check if the group separator is a space-like character.
7543
- // If so, we'll replace all such characters with an empty string.
7544
- if (isSpaceGroup) {
7545
- groupRegex = /\p{Zs}/gu;
7546
- } else if (isApostropheGroup) {
7547
- // Some environments format numbers with ASCII apostrophe and others with a curly apostrophe.
7548
- groupRegex = /['’]/g;
7549
- } else {
7550
- groupRegex = new RegExp(escapeRegExp(group), 'g');
7551
- }
7552
- }
7553
- const replacements = [{
7554
- regex: group ? groupRegex : null,
7555
- replacement: ''
7556
- }, {
7557
- regex: decimal ? new RegExp(escapeRegExp(decimal), 'g') : null,
7558
- replacement: '.'
7559
- },
7560
- // Fullwidth punctuation
7561
- {
7562
- regex: /./g,
7563
- replacement: '.'
7564
- },
7565
- // FULLWIDTH_DECIMAL
7566
- {
7567
- regex: /,/g,
7568
- replacement: ''
7569
- },
7570
- // FULLWIDTH_GROUP
7571
- // Arabic punctuation
7572
- {
7573
- regex: /٫/g,
7574
- replacement: '.'
7575
- },
7576
- // ARABIC DECIMAL SEPARATOR (U+066B)
7577
- {
7578
- regex: /٬/g,
7579
- replacement: ''
7580
- },
7581
- // ARABIC THOUSANDS SEPARATOR (U+066C)
7582
- // Currency & unit labels
7583
- {
7584
- regex: currency ? new RegExp(escapeRegExp(currency), 'g') : null,
7585
- replacement: ''
7586
- }, {
7587
- regex: unitRegex,
7588
- replacement: ''
7589
- },
7590
- // Numeral systems to ASCII digits
7591
- {
7592
- regex: ARABIC_RE,
7593
- replacement: ch => String(ARABIC_NUMERALS.indexOf(ch))
7594
- }, {
7595
- regex: PERSIAN_RE,
7596
- replacement: ch => String(PERSIAN_NUMERALS.indexOf(ch))
7597
- }, {
7598
- regex: FULLWIDTH_RE,
7599
- replacement: ch => String(FULLWIDTH_NUMERALS.indexOf(ch))
7600
- }, {
7601
- regex: HAN_RE,
7602
- replacement: ch => HAN_NUMERAL_TO_DIGIT[ch]
7603
- }];
7604
- let unformatted = replacements.reduce((acc, {
7605
- regex,
7606
- replacement
7607
- }) => {
7608
- return regex ? acc.replace(regex, replacement) : acc;
7609
- }, input);
7610
-
7611
- // Mixed-locale safety: keep only the last '.' as decimal
7612
- const lastDot = unformatted.lastIndexOf('.');
7613
- if (lastDot !== -1) {
7614
- unformatted = `${unformatted.slice(0, lastDot).replace(/\./g, '')}.${unformatted.slice(lastDot + 1).replace(/\./g, '')}`;
7615
- }
7616
-
7617
- // Guard against Infinity inputs (ASCII and symbol)
7618
- if (/^[-+]?Infinity$/i.test(input) || /[∞]/.test(input)) {
7619
- return null;
7620
- }
7621
- const parseTarget = (isNegative ? '-' : '') + unformatted;
7622
- let num = parseFloat(parseTarget);
7623
- const style = options?.style;
7624
- const isUnitPercent = style === 'unit' && options?.unit === 'percent';
7625
- const hasPercentSymbol = PERCENT_RE.test(formattedNumber) || style === 'percent';
7626
- const hasPermilleSymbol = PERMILLE_RE.test(formattedNumber);
7627
- if (hasPermilleSymbol) {
7628
- num /= 1000;
7629
- } else if (!isUnitPercent && hasPercentSymbol) {
7630
- num /= 100;
7631
- }
7632
- if (Number.isNaN(num)) {
7633
- return null;
7634
- }
7635
- return num;
7636
- }
7637
-
7638
- const CHANGE_VALUE_TICK_DELAY = 60;
7639
- const START_AUTO_CHANGE_DELAY = 400;
7640
- const TOUCH_TIMEOUT = 50;
7641
- const MAX_POINTER_MOVES_AFTER_TOUCH = 3;
7642
- const SCROLLING_POINTER_MOVE_DISTANCE = 8;
7643
- const DEFAULT_STEP = 1;
7644
-
7645
- const STEP_EPSILON_FACTOR = 1e-10;
7646
- function getFractionDigits(format) {
7647
- const defaultOptions = getFormatter('en-US').resolvedOptions();
7648
- const minimumFractionDigits = format?.minimumFractionDigits ?? defaultOptions.minimumFractionDigits ?? 0;
7649
- const maximumFractionDigits = Math.max(format?.maximumFractionDigits ?? defaultOptions.maximumFractionDigits ?? 20, minimumFractionDigits);
7650
- return {
7651
- maximumFractionDigits,
7652
- minimumFractionDigits
7653
- };
7654
- }
7655
- function roundToFractionDigits(value, maximumFractionDigits) {
7656
- if (!Number.isFinite(value)) {
7657
- return value;
7658
- }
7659
- const digits = Math.min(Math.max(maximumFractionDigits, 0), 20);
7660
- return Number(value.toFixed(digits));
7661
- }
7662
- function removeFloatingPointErrors(value, format) {
7663
- const {
7664
- maximumFractionDigits
7665
- } = getFractionDigits(format);
7666
- return roundToFractionDigits(value, maximumFractionDigits);
7667
- }
7668
- function snapToStep(clampedValue, base, step, mode = 'directional') {
7669
- if (step === 0) {
7670
- return clampedValue;
7671
- }
7672
- const stepSize = Math.abs(step);
7673
- const direction = Math.sign(step);
7674
- const tolerance = stepSize * STEP_EPSILON_FACTOR * direction;
7675
- const divisor = mode === 'nearest' ? step : stepSize;
7676
- const rawSteps = (clampedValue - base + tolerance) / divisor;
7677
- let snappedSteps;
7678
- if (mode === 'nearest') {
7679
- snappedSteps = Math.round(rawSteps);
7680
- } else if (direction > 0) {
7681
- snappedSteps = Math.floor(rawSteps);
7682
- } else {
7683
- snappedSteps = Math.ceil(rawSteps);
7684
- }
7685
- const stepForResult = mode === 'nearest' ? step : stepSize;
7686
- return base + snappedSteps * stepForResult;
7687
- }
7688
- function toValidatedNumber(value, {
7689
- step,
7690
- minWithDefault,
7691
- maxWithDefault,
7692
- minWithZeroDefault,
7693
- format,
7694
- snapOnStep,
7695
- small,
7696
- clamp: shouldClamp
7697
- }) {
7698
- if (value === null) {
7699
- return value;
7700
- }
7701
- const clampedValue = shouldClamp ? DrawerRoot.clamp(value, minWithDefault, maxWithDefault) : value;
7702
- if (step != null && snapOnStep) {
7703
- if (step === 0) {
7704
- return removeFloatingPointErrors(clampedValue, format);
7705
- }
7706
-
7707
- // If a real minimum is provided, use it
7708
- let base = minWithZeroDefault;
7709
- if (!small && minWithDefault !== Number.MIN_SAFE_INTEGER) {
7710
- base = minWithDefault;
7711
- }
7712
- const snappedValue = snapToStep(clampedValue, base, step, small ? 'nearest' : 'directional');
7713
- return removeFloatingPointErrors(snappedValue, format);
7714
- }
7715
- return removeFloatingPointErrors(clampedValue, format);
7716
- }
7717
-
7718
- const NumberFieldRoot = /*#__PURE__*/React__namespace.forwardRef(function NumberFieldRoot(componentProps, forwardedRef) {
7719
- const {
7720
- id: idProp,
7721
- min,
7722
- max,
7723
- smallStep = 0.1,
7724
- step: stepProp = 1,
7725
- largeStep = 10,
7726
- required = false,
7727
- disabled: disabledProp = false,
7728
- readOnly = false,
7729
- name: nameProp,
7730
- defaultValue,
7731
- value: valueProp,
7732
- onValueChange: onValueChangeProp,
7733
- onValueCommitted: onValueCommittedProp,
7734
- allowWheelScrub = false,
7735
- snapOnStep = false,
7736
- allowOutOfRange = false,
7737
- format,
7738
- locale,
7739
- render,
7740
- className,
7741
- inputRef: inputRefProp,
7742
- ...elementProps
7743
- } = componentProps;
7744
- const {
7745
- setDirty,
7746
- validityData,
7747
- disabled: fieldDisabled,
7748
- setFilled,
7749
- invalid,
7750
- name: fieldName,
7751
- state: fieldState,
7752
- validation,
7753
- shouldValidateOnChange
7754
- } = useFieldRootContext();
7755
- const disabled = fieldDisabled || disabledProp;
7756
- const name = fieldName ?? nameProp;
7757
- const step = stepProp === 'any' ? 1 : stepProp;
7758
- const [isScrubbing, setIsScrubbing] = React__namespace.useState(false);
7759
- const minWithDefault = min ?? Number.MIN_SAFE_INTEGER;
7760
- const maxWithDefault = max ?? Number.MAX_SAFE_INTEGER;
7761
- const minWithZeroDefault = min ?? 0;
7762
- const formatStyle = format?.style;
7763
- const inputRef = React__namespace.useRef(null);
7764
- const hiddenInputRef = useRenderElement.useMergedRefs(inputRefProp, validation.inputRef);
7765
- const id = useLabelableId({
7766
- id: idProp
7767
- });
7768
- const [valueUnwrapped, setValueUnwrapped] = DrawerRoot.useControlled({
7769
- controlled: valueProp,
7770
- default: defaultValue,
7771
- name: 'NumberField',
7772
- state: 'value'
7773
- });
7774
- const value = valueUnwrapped ?? null;
7775
- const valueRef = DrawerRoot.useValueAsRef(value);
7776
- DrawerRoot.useIsoLayoutEffect(() => {
7777
- setFilled(value !== null);
7778
- }, [setFilled, value]);
7779
- const forceRender = useForcedRerendering();
7780
- const formatOptionsRef = DrawerRoot.useValueAsRef(format);
7781
- const hasPendingCommitRef = React__namespace.useRef(false);
7782
- const onValueCommitted = DrawerRoot.useStableCallback((nextValue, eventDetails) => {
7783
- hasPendingCommitRef.current = false;
7784
- onValueCommittedProp?.(nextValue, eventDetails);
7785
- });
7786
- const startTickTimeout = DrawerRoot.useTimeout();
7787
- const tickInterval = useInterval();
7788
- const intentionalTouchCheckTimeout = DrawerRoot.useTimeout();
7789
- const isPressedRef = React__namespace.useRef(false);
7790
- const movesAfterTouchRef = React__namespace.useRef(0);
7791
- const allowInputSyncRef = React__namespace.useRef(true);
7792
- const lastChangedValueRef = React__namespace.useRef(null);
7793
- const unsubscribeFromGlobalContextMenuRef = React__namespace.useRef(() => {});
7794
-
7795
- // During SSR, the value is formatted on the server, whose locale may differ from the client's
7796
- // locale. This causes a hydration mismatch, which we manually suppress. This is preferable to
7797
- // rendering an empty input field and then updating it with the formatted value, as the user
7798
- // can still see the value prior to hydration, even if it's not formatted correctly.
7799
- const [inputValue, setInputValue] = React__namespace.useState(() => {
7800
- if (valueProp !== undefined) {
7801
- return getControlledInputValue(value, locale, format);
7802
- }
7803
- return formatNumber(value, locale, format);
7804
- });
7805
- const [inputMode, setInputMode] = React__namespace.useState('numeric');
7806
- const getAllowedNonNumericKeys = DrawerRoot.useStableCallback(() => {
7807
- const {
7808
- decimal,
7809
- group,
7810
- currency,
7811
- literal
7812
- } = getNumberLocaleDetails(locale, format);
7813
- const keys = new Set();
7814
- BASE_NON_NUMERIC_SYMBOLS.forEach(symbol => keys.add(symbol));
7815
- if (decimal) {
7816
- keys.add(decimal);
7817
- }
7818
- if (group) {
7819
- keys.add(group);
7820
- if (SPACE_SEPARATOR_RE.test(group)) {
7821
- keys.add(' ');
7822
- }
7823
- }
7824
- const allowPercentSymbols = formatStyle === 'percent' || formatStyle === 'unit' && format?.unit === 'percent';
7825
- const allowPermilleSymbols = formatStyle === 'percent' || formatStyle === 'unit' && format?.unit === 'permille';
7826
- if (allowPercentSymbols) {
7827
- PERCENTAGES.forEach(key => keys.add(key));
7828
- }
7829
- if (allowPermilleSymbols) {
7830
- PERMILLE.forEach(key => keys.add(key));
7831
- }
7832
- if (formatStyle === 'currency' && currency) {
7833
- keys.add(currency);
7834
- }
7835
- if (literal) {
7836
- // Some locales (e.g. de-DE) insert a literal space character between the number
7837
- // and the symbol, so allow those characters to be typed/removed.
7838
- Array.from(literal).forEach(char => keys.add(char));
7839
- if (SPACE_SEPARATOR_RE.test(literal)) {
7840
- keys.add(' ');
7841
- }
7842
- }
7843
-
7844
- // Allow plus sign in all cases; minus sign only when negatives are valid
7845
- PLUS_SIGNS_WITH_ASCII.forEach(key => keys.add(key));
7846
- if (minWithDefault < 0) {
7847
- MINUS_SIGNS_WITH_ASCII.forEach(key => keys.add(key));
7848
- }
7849
- return keys;
7850
- });
7851
- const getStepAmount = DrawerRoot.useStableCallback(event => {
7852
- if (event?.altKey) {
7853
- return smallStep;
7854
- }
7855
- if (event?.shiftKey) {
7856
- return largeStep;
7857
- }
7858
- return step;
7859
- });
7860
- const setValue = DrawerRoot.useStableCallback((unvalidatedValue, details) => {
7861
- const eventWithOptionalKeyState = details.event;
7862
- const dir = details.direction;
7863
- const reason = details.reason;
7864
- // Only allow out-of-range values for direct text entry (native-like behavior).
7865
- // Step-based interactions (keyboard arrows, buttons, wheel, scrub) still clamp to min/max.
7866
- const shouldClampValue = !allowOutOfRange || !(reason === DrawerRoot.inputChange || reason === DrawerRoot.inputBlur || reason === DrawerRoot.inputPaste || reason === DrawerRoot.inputClear || reason === DrawerRoot.none);
7867
- const validatedValue = toValidatedNumber(unvalidatedValue, {
7868
- step: dir ? getStepAmount(eventWithOptionalKeyState) * dir : undefined,
7869
- format: formatOptionsRef.current,
7870
- minWithDefault,
7871
- maxWithDefault,
7872
- minWithZeroDefault,
7873
- snapOnStep,
7874
- small: eventWithOptionalKeyState?.altKey ?? false,
7875
- clamp: shouldClampValue
7876
- });
7877
-
7878
- // Determine whether we should notify about a change even if the numeric value is unchanged.
7879
- // This is needed when the user input is clamped/snapped to the same current value, or when
7880
- // the source value differs but validation normalizes to the existing value.
7881
- const isInputReason = details.reason === DrawerRoot.inputChange || details.reason === DrawerRoot.inputClear || details.reason === DrawerRoot.inputBlur || details.reason === DrawerRoot.inputPaste || details.reason === DrawerRoot.none;
7882
- const shouldFireChange = validatedValue !== value || isInputReason && (unvalidatedValue !== value || allowInputSyncRef.current === false);
7883
- if (shouldFireChange) {
7884
- lastChangedValueRef.current = validatedValue;
7885
- onValueChangeProp?.(validatedValue, details);
7886
- if (details.isCanceled) {
7887
- return shouldFireChange;
7888
- }
7889
- setValueUnwrapped(validatedValue);
7890
- setDirty(validatedValue !== validityData.initialValue);
7891
- hasPendingCommitRef.current = true;
7892
- }
7893
-
7894
- // Keep the visible input in sync immediately when programmatic changes occur
7895
- // (increment/decrement, wheel, etc). During direct typing we don't want
7896
- // to overwrite the user-provided text until blur, so we gate on
7897
- // `allowInputSyncRef`.
7898
- if (allowInputSyncRef.current) {
7899
- setInputValue(formatNumber(validatedValue, locale, format));
7900
- }
7901
-
7902
- // Formatting can change even if the numeric value hasn't, so ensure a re-render when needed.
7903
- forceRender();
7904
- return shouldFireChange;
7905
- });
7906
- const incrementValue = DrawerRoot.useStableCallback((amount, {
7907
- direction,
7908
- currentValue,
7909
- event,
7910
- reason
7911
- }) => {
7912
- const prevValue = currentValue == null ? valueRef.current : currentValue;
7913
- const nextValue = typeof prevValue === 'number' ? prevValue + amount * direction : Math.max(0, min ?? 0);
7914
- const nativeEvent = event;
7915
- return setValue(nextValue, DrawerRoot.createChangeEventDetails(reason, nativeEvent, undefined, {
7916
- direction
7917
- }));
7918
- });
7919
- const stopAutoChange = DrawerRoot.useStableCallback(() => {
7920
- intentionalTouchCheckTimeout.clear();
7921
- startTickTimeout.clear();
7922
- tickInterval.clear();
7923
- unsubscribeFromGlobalContextMenuRef.current();
7924
- movesAfterTouchRef.current = 0;
7925
- });
7926
- const startAutoChange = DrawerRoot.useStableCallback((isIncrement, triggerEvent) => {
7927
- stopAutoChange();
7928
- if (!inputRef.current) {
7929
- return;
7930
- }
7931
- const win = index_esm.getWindow(inputRef.current);
7932
- function handleContextMenu(event) {
7933
- event.preventDefault();
7934
- }
7935
-
7936
- // A global context menu is necessary to prevent the context menu from appearing when the touch
7937
- // is slightly outside of the element's hit area.
7938
- win.addEventListener('contextmenu', handleContextMenu);
7939
- unsubscribeFromGlobalContextMenuRef.current = () => {
7940
- win.removeEventListener('contextmenu', handleContextMenu);
7941
- };
7942
- win.addEventListener('pointerup', event => {
7943
- isPressedRef.current = false;
7944
- stopAutoChange();
7945
- const committed = lastChangedValueRef.current ?? valueRef.current;
7946
- const commitReason = isIncrement ? DrawerRoot.incrementPress : DrawerRoot.decrementPress;
7947
- onValueCommitted(committed, DrawerRoot.createGenericEventDetails(commitReason, event));
7948
- }, {
7949
- once: true
7950
- });
7951
- function tick() {
7952
- const amount = getStepAmount(triggerEvent) ?? DEFAULT_STEP;
7953
- return incrementValue(amount, {
7954
- direction: isIncrement ? 1 : -1,
7955
- event: triggerEvent,
7956
- reason: isIncrement ? 'increment-press' : 'decrement-press'
7957
- });
7958
- }
7959
- if (!tick()) {
7960
- stopAutoChange();
7961
- return;
7962
- }
7963
- startTickTimeout.start(START_AUTO_CHANGE_DELAY, () => {
7964
- tickInterval.start(CHANGE_VALUE_TICK_DELAY, () => {
7965
- if (!tick()) {
7966
- stopAutoChange();
7967
- }
7968
- });
7969
- });
7970
- });
7971
-
7972
- // We need to update the input value when the external `value` prop changes. This ends up acting
7973
- // as a single source of truth to update the input value, bypassing the need to manually set it in
7974
- // each event handler internally in this hook.
7975
- // This is done inside a layout effect as an alternative to the technique to set state during
7976
- // render as we're accessing a ref, which must be inside an effect.
7977
- // https://react.dev/learn/you-might-not-need-an-effect#adjusting-some-state-when-a-prop-changes
7978
- //
7979
- // ESLint is disabled because it needs to run even if the parsed value hasn't changed, since the
7980
- // value still can be formatted differently.
7981
- // eslint-disable-next-line react-hooks/exhaustive-deps
7982
- DrawerRoot.useIsoLayoutEffect(function syncFormattedInputValueOnValueChange() {
7983
- // This ensures the value is only updated on blur rather than every keystroke, but still
7984
- // allows the input value to be updated when the value is changed externally.
7985
- if (!allowInputSyncRef.current) {
7986
- return;
7987
- }
7988
- const nextInputValue = valueProp !== undefined ? getControlledInputValue(value, locale, format) : formatNumber(value, locale, format);
7989
- if (nextInputValue !== inputValue) {
7990
- setInputValue(nextInputValue);
7991
- }
7992
- });
7993
- DrawerRoot.useIsoLayoutEffect(function setDynamicInputModeForIOS() {
7994
- if (!DrawerRoot.isIOS) {
7995
- return;
7996
- }
7997
-
7998
- // iOS numeric software keyboard doesn't have a minus key, so we need to use the default
7999
- // keyboard to let the user input a negative number.
8000
- let computedInputMode = 'text';
8001
- if (minWithDefault >= 0) {
8002
- // iOS numeric software keyboard doesn't have a decimal key for "numeric" input mode, but
8003
- // this is better than the "text" input if possible to use.
8004
- computedInputMode = 'decimal';
8005
- }
8006
- setInputMode(computedInputMode);
8007
- }, [minWithDefault, formatStyle]);
8008
- React__namespace.useEffect(() => {
8009
- return () => stopAutoChange();
8010
- }, [stopAutoChange]);
8011
-
8012
- // The `onWheel` prop can't be prevented, so we need to use a global event listener.
8013
- React__namespace.useEffect(function registerElementWheelListener() {
8014
- const element = inputRef.current;
8015
- if (disabled || readOnly || !allowWheelScrub || !element) {
8016
- return undefined;
8017
- }
8018
- function handleWheel(event) {
8019
- if (
8020
- // Allow pinch-zooming.
8021
- event.ctrlKey || DrawerRoot.ownerDocument(inputRef.current).activeElement !== inputRef.current) {
8022
- return;
8023
- }
8024
-
8025
- // Prevent the default behavior to avoid scrolling the page.
8026
- event.preventDefault();
8027
- const amount = getStepAmount(event) ?? DEFAULT_STEP;
8028
- incrementValue(amount, {
8029
- direction: event.deltaY > 0 ? -1 : 1,
8030
- event,
8031
- reason: 'wheel'
8032
- });
8033
- }
8034
- element.addEventListener('wheel', handleWheel);
8035
- return () => {
8036
- element.removeEventListener('wheel', handleWheel);
8037
- };
8038
- }, [allowWheelScrub, incrementValue, disabled, readOnly, largeStep, step, getStepAmount]);
8039
- const state = React__namespace.useMemo(() => ({
8040
- ...fieldState,
8041
- disabled,
8042
- readOnly,
8043
- required,
8044
- value,
8045
- inputValue,
8046
- scrubbing: isScrubbing
8047
- }), [fieldState, disabled, readOnly, required, value, inputValue, isScrubbing]);
8048
- const contextValue = React__namespace.useMemo(() => ({
8049
- inputRef,
8050
- inputValue,
8051
- value,
8052
- startAutoChange,
8053
- stopAutoChange,
8054
- minWithDefault,
8055
- maxWithDefault,
8056
- disabled,
8057
- readOnly,
8058
- id,
8059
- setValue,
8060
- incrementValue,
8061
- getStepAmount,
8062
- allowInputSyncRef,
8063
- formatOptionsRef,
8064
- valueRef,
8065
- lastChangedValueRef,
8066
- hasPendingCommitRef,
8067
- isPressedRef,
8068
- intentionalTouchCheckTimeout,
8069
- movesAfterTouchRef,
8070
- name,
8071
- required,
8072
- invalid,
8073
- inputMode,
8074
- getAllowedNonNumericKeys,
8075
- min,
8076
- max,
8077
- setInputValue,
8078
- locale,
8079
- isScrubbing,
8080
- setIsScrubbing,
8081
- state,
8082
- onValueCommitted
8083
- }), [inputRef, inputValue, value, startAutoChange, stopAutoChange, minWithDefault, maxWithDefault, disabled, readOnly, id, setValue, incrementValue, getStepAmount, formatOptionsRef, valueRef, intentionalTouchCheckTimeout, name, required, invalid, inputMode, getAllowedNonNumericKeys, min, max, setInputValue, locale, isScrubbing, state, onValueCommitted]);
8084
- const element = useRenderElement.useRenderElement('div', componentProps, {
8085
- ref: forwardedRef,
8086
- state,
8087
- props: elementProps,
8088
- stateAttributesMapping: stateAttributesMapping$1
8089
- });
8090
- return /*#__PURE__*/jsxRuntime.jsxs(NumberFieldRootContext.Provider, {
8091
- value: contextValue,
8092
- children: [element, /*#__PURE__*/jsxRuntime.jsx("input", {
8093
- ...validation.getInputValidationProps({
8094
- onFocus() {
8095
- inputRef.current?.focus();
8096
- },
8097
- onChange(event) {
8098
- // Workaround for https://github.com/facebook/react/issues/9023
8099
- if (event.nativeEvent.defaultPrevented) {
8100
- return;
8101
- }
8102
-
8103
- // Handle browser autofill.
8104
- const nextValue = event.currentTarget.valueAsNumber;
8105
- const parsedValue = Number.isNaN(nextValue) ? null : nextValue;
8106
- const details = DrawerRoot.createChangeEventDetails(DrawerRoot.none, event.nativeEvent);
8107
- setDirty(parsedValue !== validityData.initialValue);
8108
- setValue(parsedValue, details);
8109
- if (shouldValidateOnChange()) {
8110
- validation.commit(parsedValue);
8111
- }
8112
- }
8113
- }),
8114
- ref: hiddenInputRef,
8115
- type: "number",
8116
- name: name,
8117
- value: value ?? '',
8118
- min: min,
8119
- max: max
8120
- // stepMismatch validation is broken unless an explicit `min` is added.
8121
- // See https://github.com/facebook/react/issues/12334.
8122
- ,
8123
- step: stepProp,
8124
- disabled: disabled,
8125
- required: required,
8126
- "aria-hidden": true,
8127
- tabIndex: -1,
8128
- style: name ? DrawerRoot.visuallyHiddenInput : DrawerRoot.visuallyHidden
8129
- })]
8130
- });
8131
- });
8132
- if (process.env.NODE_ENV !== "production") NumberFieldRoot.displayName = "NumberFieldRoot";
8133
- function getControlledInputValue(value, locale, format) {
8134
- const explicitPrecision = format?.maximumFractionDigits != null || format?.minimumFractionDigits != null;
8135
- return explicitPrecision ? formatNumber(value, locale, format) : formatNumberMaxPrecision(value, locale, format);
8136
- }
8137
-
8138
- /**
8139
- * Groups the input with the increment and decrement buttons.
8140
- * Renders a `<div>` element.
8141
- *
8142
- * Documentation: [Base UI Number Field](https://base-ui.com/react/components/number-field)
8143
- */
8144
- const NumberFieldGroup = /*#__PURE__*/React__namespace.forwardRef(function NumberFieldGroup(componentProps, forwardedRef) {
8145
- const {
8146
- render,
8147
- className,
8148
- ...elementProps
8149
- } = componentProps;
8150
- const {
8151
- state
8152
- } = useNumberFieldRootContext();
8153
- const element = useRenderElement.useRenderElement('div', componentProps, {
8154
- ref: forwardedRef,
8155
- state,
8156
- props: [{
8157
- role: 'group'
8158
- }, elementProps],
8159
- stateAttributesMapping: stateAttributesMapping$1
8160
- });
8161
- return element;
8162
- });
8163
- if (process.env.NODE_ENV !== "production") NumberFieldGroup.displayName = "NumberFieldGroup";
8164
-
8165
- // Treat pen as touch-like to avoid forcing the software keyboard on stylus taps.
8166
- // Linux Chrome may emit "pen" historically for mouse usage due to a bug, but the touch path
8167
- // still works with minor behavioral differences.
8168
- function isTouchLikePointerType(pointerType) {
8169
- return pointerType === 'touch' || pointerType === 'pen';
8170
- }
8171
- function useNumberFieldButton(params) {
8172
- const {
8173
- allowInputSyncRef,
8174
- disabled,
8175
- formatOptionsRef,
8176
- getStepAmount,
8177
- id,
8178
- incrementValue,
8179
- inputRef,
8180
- inputValue,
8181
- intentionalTouchCheckTimeout,
8182
- isIncrement,
8183
- isPressedRef,
8184
- locale,
8185
- movesAfterTouchRef,
8186
- readOnly,
8187
- setValue,
8188
- startAutoChange,
8189
- stopAutoChange,
8190
- valueRef,
8191
- lastChangedValueRef,
8192
- onValueCommitted
8193
- } = params;
8194
- const incrementDownCoordsRef = React__namespace.useRef({
8195
- x: 0,
8196
- y: 0
8197
- });
8198
- const isTouchingButtonRef = React__namespace.useRef(false);
8199
- const ignoreClickRef = React__namespace.useRef(false);
8200
- const pointerTypeRef = React__namespace.useRef('');
8201
- const pressReason = isIncrement ? 'increment-press' : 'decrement-press';
8202
- function commitValue(nativeEvent) {
8203
- allowInputSyncRef.current = true;
8204
-
8205
- // The input may be dirty but not yet blurred, so the value won't have been committed.
8206
- const parsedValue = parseNumber(inputValue, locale, formatOptionsRef.current);
8207
- if (parsedValue !== null) {
8208
- // The increment value function needs to know the current input value to increment it
8209
- // correctly.
8210
- valueRef.current = parsedValue;
8211
- setValue(parsedValue, DrawerRoot.createChangeEventDetails(pressReason, nativeEvent, undefined, {
8212
- direction: isIncrement ? 1 : -1
8213
- }));
8214
- }
8215
- }
8216
- const props = {
8217
- disabled,
8218
- 'aria-readonly': readOnly || undefined,
8219
- 'aria-label': isIncrement ? 'Increase' : 'Decrease',
8220
- 'aria-controls': id,
8221
- // Keyboard users shouldn't have access to the buttons, since they can use the input element
8222
- // to change the value. On the other hand, `aria-hidden` is not applied because touch screen
8223
- // readers should be able to use the buttons.
8224
- tabIndex: -1,
8225
- style: {
8226
- WebkitUserSelect: 'none',
8227
- userSelect: 'none'
8228
- },
8229
- onTouchStart() {
8230
- isTouchingButtonRef.current = true;
8231
- },
8232
- onTouchEnd() {
8233
- isTouchingButtonRef.current = false;
8234
- },
8235
- onClick(event) {
8236
- const isDisabled = disabled || readOnly;
8237
- if (event.defaultPrevented || isDisabled || (
8238
- // If it's not a keyboard/virtual click, ignore.
8239
- isTouchLikePointerType(pointerTypeRef.current) ? ignoreClickRef.current : event.detail !== 0)) {
8240
- return;
8241
- }
8242
- commitValue(event.nativeEvent);
8243
- const amount = getStepAmount(event) ?? DEFAULT_STEP;
8244
- const prev = valueRef.current;
8245
- incrementValue(amount, {
8246
- direction: isIncrement ? 1 : -1,
8247
- event: event.nativeEvent,
8248
- reason: pressReason
8249
- });
8250
- const committed = lastChangedValueRef.current ?? valueRef.current;
8251
- if (committed !== prev) {
8252
- onValueCommitted(committed, DrawerRoot.createGenericEventDetails(pressReason, event.nativeEvent));
8253
- }
8254
- },
8255
- onPointerDown(event) {
8256
- const isMainButton = !event.button || event.button === 0;
8257
- if (event.defaultPrevented || readOnly || !isMainButton || disabled) {
8258
- return;
8259
- }
8260
- pointerTypeRef.current = event.pointerType;
8261
- ignoreClickRef.current = false;
8262
- isPressedRef.current = true;
8263
- incrementDownCoordsRef.current = {
8264
- x: event.clientX,
8265
- y: event.clientY
8266
- };
8267
- commitValue(event.nativeEvent);
8268
- const isTouchPointer = isTouchLikePointerType(event.pointerType);
8269
- if (!isTouchPointer) {
8270
- event.preventDefault();
8271
- inputRef.current?.focus();
8272
- startAutoChange(isIncrement, event);
8273
- } else {
8274
- // We need to check if the pointerdown was intentional, and not the result of a scroll
8275
- // or pinch-zoom. In that case, we don't want to change the value.
8276
- intentionalTouchCheckTimeout.start(TOUCH_TIMEOUT, () => {
8277
- const moves = movesAfterTouchRef.current;
8278
- movesAfterTouchRef.current = 0;
8279
- // Only start auto-change if the touch is still pressed (prevents races
8280
- // with pointerup occurring before the timeout fires on quick taps).
8281
- const stillPressed = isPressedRef.current;
8282
- if (stillPressed && moves != null && moves < MAX_POINTER_MOVES_AFTER_TOUCH) {
8283
- startAutoChange(isIncrement, event);
8284
- ignoreClickRef.current = true; // synthesized click should be ignored
8285
- } else {
8286
- // No auto-change (simple tap or scroll gesture), allow the click handler
8287
- // to perform a single increment and commit.
8288
- ignoreClickRef.current = false;
8289
- stopAutoChange();
8290
- }
8291
- });
8292
- }
8293
- },
8294
- onPointerUp(event) {
8295
- // Ensure we mark the press as released for touch flows even if auto-change never started,
8296
- // so the delayed auto-change check won’t start after a quick tap.
8297
- if (isTouchLikePointerType(event.pointerType)) {
8298
- isPressedRef.current = false;
8299
- }
8300
- },
8301
- onPointerMove(event) {
8302
- const isDisabled = disabled || readOnly;
8303
- if (isDisabled || !isTouchLikePointerType(event.pointerType) || !isPressedRef.current) {
8304
- return;
8305
- }
8306
- if (movesAfterTouchRef.current != null) {
8307
- movesAfterTouchRef.current += 1;
8308
- }
8309
- const {
8310
- x,
8311
- y
8312
- } = incrementDownCoordsRef.current;
8313
- const dx = x - event.clientX;
8314
- const dy = y - event.clientY;
8315
-
8316
- // An alternative to this technique is to detect when the NumberField's parent container
8317
- // has been scrolled
8318
- if (dx ** 2 + dy ** 2 > SCROLLING_POINTER_MOVE_DISTANCE ** 2) {
8319
- stopAutoChange();
8320
- }
8321
- },
8322
- onMouseEnter(event) {
8323
- const isDisabled = disabled || readOnly;
8324
- if (event.defaultPrevented || isDisabled || !isPressedRef.current || isTouchingButtonRef.current || isTouchLikePointerType(pointerTypeRef.current)) {
8325
- return;
8326
- }
8327
- startAutoChange(isIncrement, event);
8328
- },
8329
- onMouseLeave() {
8330
- if (isTouchingButtonRef.current) {
8331
- return;
8332
- }
8333
- stopAutoChange();
8334
- },
8335
- onMouseUp() {
8336
- if (isTouchingButtonRef.current) {
8337
- return;
8338
- }
8339
- stopAutoChange();
8340
- }
8341
- };
8342
- return props;
8343
- }
8344
-
8345
- /**
8346
- * A stepper button that increases the field value when clicked.
8347
- * Renders an `<button>` element.
8348
- *
8349
- * Documentation: [Base UI Number Field](https://base-ui.com/react/components/number-field)
8350
- */
8351
- const NumberFieldIncrement = /*#__PURE__*/React__namespace.forwardRef(function NumberFieldIncrement(componentProps, forwardedRef) {
8352
- const {
8353
- render,
8354
- className,
8355
- disabled: disabledProp = false,
8356
- nativeButton = true,
8357
- ...elementProps
8358
- } = componentProps;
8359
- const {
8360
- allowInputSyncRef,
8361
- disabled: contextDisabled,
8362
- formatOptionsRef,
8363
- getStepAmount,
8364
- id,
8365
- incrementValue,
8366
- inputRef,
8367
- inputValue,
8368
- intentionalTouchCheckTimeout,
8369
- isPressedRef,
8370
- locale,
8371
- maxWithDefault,
8372
- movesAfterTouchRef,
8373
- readOnly,
8374
- setValue,
8375
- startAutoChange,
8376
- state,
8377
- stopAutoChange,
8378
- value,
8379
- valueRef,
8380
- lastChangedValueRef,
8381
- onValueCommitted
8382
- } = useNumberFieldRootContext();
8383
- const isMax = value != null && value >= maxWithDefault;
8384
- const disabled = disabledProp || contextDisabled || isMax;
8385
- const props = useNumberFieldButton({
8386
- isIncrement: true,
8387
- inputRef,
8388
- startAutoChange,
8389
- stopAutoChange,
8390
- inputValue,
8391
- disabled,
8392
- readOnly,
8393
- id,
8394
- setValue,
8395
- getStepAmount,
8396
- incrementValue,
8397
- allowInputSyncRef,
8398
- formatOptionsRef,
8399
- valueRef,
8400
- isPressedRef,
8401
- intentionalTouchCheckTimeout,
8402
- movesAfterTouchRef,
8403
- locale,
8404
- lastChangedValueRef,
8405
- onValueCommitted
8406
- });
8407
- const {
8408
- getButtonProps,
8409
- buttonRef
8410
- } = MenuSubmenuTrigger.useButton({
8411
- disabled,
8412
- native: nativeButton,
8413
- focusableWhenDisabled: true
8414
- });
8415
- const buttonState = React__namespace.useMemo(() => ({
8416
- ...state,
8417
- disabled
8418
- }), [state, disabled]);
8419
- const element = useRenderElement.useRenderElement('button', componentProps, {
8420
- ref: [forwardedRef, buttonRef],
8421
- state: buttonState,
8422
- props: [props, elementProps, getButtonProps],
8423
- stateAttributesMapping: stateAttributesMapping$1
8424
- });
8425
- return element;
8426
- });
8427
- if (process.env.NODE_ENV !== "production") NumberFieldIncrement.displayName = "NumberFieldIncrement";
8428
-
8429
- /**
8430
- * A stepper button that decreases the field value when clicked.
8431
- * Renders an `<button>` element.
8432
- *
8433
- * Documentation: [Base UI Number Field](https://base-ui.com/react/components/number-field)
8434
- */
8435
- const NumberFieldDecrement = /*#__PURE__*/React__namespace.forwardRef(function NumberFieldDecrement(componentProps, forwardedRef) {
8436
- const {
8437
- render,
8438
- className,
8439
- disabled: disabledProp = false,
8440
- nativeButton = true,
8441
- ...elementProps
8442
- } = componentProps;
8443
- const {
8444
- allowInputSyncRef,
8445
- disabled: contextDisabled,
8446
- formatOptionsRef,
8447
- getStepAmount,
8448
- id,
8449
- incrementValue,
8450
- inputRef,
8451
- inputValue,
8452
- intentionalTouchCheckTimeout,
8453
- isPressedRef,
8454
- minWithDefault,
8455
- movesAfterTouchRef,
8456
- readOnly,
8457
- setValue,
8458
- startAutoChange,
8459
- state,
8460
- stopAutoChange,
8461
- value,
8462
- valueRef,
8463
- locale,
8464
- lastChangedValueRef,
8465
- onValueCommitted
8466
- } = useNumberFieldRootContext();
8467
- const isMin = value != null && value <= minWithDefault;
8468
- const disabled = disabledProp || contextDisabled || isMin;
8469
- const props = useNumberFieldButton({
8470
- isIncrement: false,
8471
- inputRef,
8472
- startAutoChange,
8473
- stopAutoChange,
8474
- inputValue,
8475
- disabled,
8476
- readOnly,
8477
- id,
8478
- setValue,
8479
- getStepAmount,
8480
- incrementValue,
8481
- allowInputSyncRef,
8482
- formatOptionsRef,
8483
- valueRef,
8484
- isPressedRef,
8485
- intentionalTouchCheckTimeout,
8486
- movesAfterTouchRef,
8487
- locale,
8488
- lastChangedValueRef,
8489
- onValueCommitted
8490
- });
8491
- const {
8492
- getButtonProps,
8493
- buttonRef
8494
- } = MenuSubmenuTrigger.useButton({
8495
- disabled,
8496
- native: nativeButton,
8497
- focusableWhenDisabled: true
8498
- });
8499
- const buttonState = React__namespace.useMemo(() => ({
8500
- ...state,
8501
- disabled
8502
- }), [state, disabled]);
8503
- const element = useRenderElement.useRenderElement('button', componentProps, {
8504
- ref: [forwardedRef, buttonRef],
8505
- state: buttonState,
8506
- props: [props, elementProps, getButtonProps],
8507
- stateAttributesMapping: stateAttributesMapping$1
8508
- });
8509
- return element;
8510
- });
8511
- if (process.env.NODE_ENV !== "production") NumberFieldDecrement.displayName = "NumberFieldDecrement";
8512
-
8513
- const stateAttributesMapping = {
8514
- ...fieldValidityMapping,
8515
- ...stateAttributesMapping$1
8516
- };
8517
- const NAVIGATE_KEYS = new Set(['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Tab', 'Enter', 'Escape']);
8518
-
8519
- /**
8520
- * The native input control in the number field.
8521
- * Renders an `<input>` element.
8522
- *
8523
- * Documentation: [Base UI Number Field](https://base-ui.com/react/components/number-field)
8524
- */
8525
- const NumberFieldInput = /*#__PURE__*/React__namespace.forwardRef(function NumberFieldInput(componentProps, forwardedRef) {
8526
- const {
8527
- render,
8528
- className,
8529
- ...elementProps
8530
- } = componentProps;
8531
- const {
8532
- allowInputSyncRef,
8533
- disabled,
8534
- formatOptionsRef,
8535
- getAllowedNonNumericKeys,
8536
- getStepAmount,
8537
- id,
8538
- incrementValue,
8539
- inputMode,
8540
- inputValue,
8541
- max,
8542
- min,
8543
- name,
8544
- readOnly,
8545
- required,
8546
- setValue,
8547
- state,
8548
- setInputValue,
8549
- locale,
8550
- inputRef,
8551
- value,
8552
- onValueCommitted,
8553
- lastChangedValueRef,
8554
- hasPendingCommitRef,
8555
- valueRef
8556
- } = useNumberFieldRootContext();
8557
- const {
8558
- clearErrors
8559
- } = useFormContext();
8560
- const {
8561
- validationMode,
8562
- setTouched,
8563
- setFocused,
8564
- invalid,
8565
- shouldValidateOnChange,
8566
- validation
8567
- } = useFieldRootContext();
8568
- const {
8569
- labelId
8570
- } = useLabelableContext();
8571
- const hasTouchedInputRef = React__namespace.useRef(false);
8572
- const blockRevalidationRef = React__namespace.useRef(false);
8573
- useField({
8574
- id,
8575
- commit: validation.commit,
8576
- value,
8577
- controlRef: inputRef,
8578
- name,
8579
- getValue: () => value ?? null
8580
- });
8581
- DrawerRoot.useValueChanged(value, previousValue => {
8582
- const validateOnChange = shouldValidateOnChange();
8583
- clearErrors(name);
8584
- if (validateOnChange) {
8585
- validation.commit(value);
8586
- }
8587
- if (previousValue === value || validateOnChange) {
8588
- return;
8589
- }
8590
- if (blockRevalidationRef.current) {
8591
- blockRevalidationRef.current = false;
8592
- return;
8593
- }
8594
- validation.commit(value, true);
8595
- });
8596
- const inputProps = {
8597
- id,
8598
- required,
8599
- disabled,
8600
- readOnly,
8601
- inputMode,
8602
- value: inputValue,
8603
- type: 'text',
8604
- autoComplete: 'off',
8605
- autoCorrect: 'off',
8606
- spellCheck: 'false',
8607
- 'aria-roledescription': 'Number field',
8608
- 'aria-invalid': invalid || undefined,
8609
- 'aria-labelledby': labelId,
8610
- // If the server's locale does not match the client's locale, the formatting may not match,
8611
- // causing a hydration mismatch.
8612
- suppressHydrationWarning: true,
8613
- onFocus(event) {
8614
- if (event.defaultPrevented || readOnly || disabled) {
8615
- return;
8616
- }
8617
- setFocused(true);
8618
- if (hasTouchedInputRef.current) {
8619
- return;
8620
- }
8621
- hasTouchedInputRef.current = true;
8622
-
8623
- // Browsers set selection at the start of the input field by default. We want to set it at
8624
- // the end for the first focus.
8625
- const target = event.currentTarget;
8626
- const length = target.value.length;
8627
- target.setSelectionRange(length, length);
8628
- },
8629
- onBlur(event) {
8630
- if (event.defaultPrevented || readOnly || disabled) {
8631
- return;
8632
- }
8633
- setTouched(true);
8634
- setFocused(false);
8635
- const hadManualInput = !allowInputSyncRef.current;
8636
- const hadPendingProgrammaticChange = hasPendingCommitRef.current;
8637
- allowInputSyncRef.current = true;
8638
- if (inputValue.trim() === '') {
8639
- setValue(null, DrawerRoot.createChangeEventDetails(DrawerRoot.inputClear, event.nativeEvent));
8640
- if (validationMode === 'onBlur') {
8641
- validation.commit(null);
8642
- }
8643
- onValueCommitted(null, DrawerRoot.createGenericEventDetails(DrawerRoot.inputClear, event.nativeEvent));
8644
- return;
8645
- }
8646
- const formatOptions = formatOptionsRef.current;
8647
- const parsedValue = parseNumber(inputValue, locale, formatOptions);
8648
- if (parsedValue === null) {
8649
- return;
8650
- }
8651
-
8652
- // If an explicit precision is requested, round the committed numeric value.
8653
- const hasExplicitPrecision = formatOptions?.maximumFractionDigits != null || formatOptions?.minimumFractionDigits != null;
8654
- const maxFrac = formatOptions?.maximumFractionDigits;
8655
- const committed = hasExplicitPrecision && typeof maxFrac === 'number' ? Number(parsedValue.toFixed(maxFrac)) : parsedValue;
8656
- const nextEventDetails = DrawerRoot.createGenericEventDetails(DrawerRoot.inputBlur, event.nativeEvent);
8657
- const shouldUpdateValue = value !== committed;
8658
- const shouldCommit = hadManualInput || shouldUpdateValue || hadPendingProgrammaticChange;
8659
- if (validationMode === 'onBlur') {
8660
- validation.commit(committed);
8661
- }
8662
- if (shouldUpdateValue) {
8663
- blockRevalidationRef.current = true;
8664
- setValue(committed, DrawerRoot.createChangeEventDetails(DrawerRoot.inputBlur, event.nativeEvent));
8665
- }
8666
- if (shouldCommit) {
8667
- onValueCommitted(committed, nextEventDetails);
8668
- }
8669
-
8670
- // Normalize only the displayed text
8671
- const canonicalText = formatNumber(committed, locale, formatOptions);
8672
- const maxPrecisionText = formatNumberMaxPrecision(parsedValue, locale, formatOptions);
8673
- const shouldPreserveFullPrecision = !hasExplicitPrecision && parsedValue === value && inputValue === maxPrecisionText;
8674
- if (!shouldPreserveFullPrecision && inputValue !== canonicalText) {
8675
- setInputValue(canonicalText);
8676
- }
8677
- },
8678
- onChange(event) {
8679
- // Workaround for https://github.com/facebook/react/issues/9023
8680
- if (event.nativeEvent.defaultPrevented) {
8681
- return;
8682
- }
8683
- allowInputSyncRef.current = false;
8684
- const targetValue = event.target.value;
8685
- if (targetValue.trim() === '') {
8686
- setInputValue(targetValue);
8687
- setValue(null, DrawerRoot.createChangeEventDetails(DrawerRoot.inputClear, event.nativeEvent));
8688
- return;
8689
- }
8690
-
8691
- // Update the input text immediately and only fire onValueChange if the typed value is
8692
- // currently parseable into a number. This preserves good UX for IME
8693
- // composition/partial input while still providing live numeric updates when possible.
8694
- const allowedNonNumericKeys = getAllowedNonNumericKeys();
8695
- const isValidCharacterString = Array.from(targetValue).every(ch => {
8696
- const isAsciiDigit = ch >= '0' && ch <= '9';
8697
- const isArabicNumeral = ARABIC_DETECT_RE.test(ch);
8698
- const isHanNumeral = HAN_DETECT_RE.test(ch);
8699
- const isPersianNumeral = PERSIAN_DETECT_RE.test(ch);
8700
- const isFullwidthNumeral = FULLWIDTH_DETECT_RE.test(ch);
8701
- const isMinus = ANY_MINUS_DETECT_RE.test(ch);
8702
- return isAsciiDigit || isArabicNumeral || isHanNumeral || isPersianNumeral || isFullwidthNumeral || isMinus || allowedNonNumericKeys.has(ch);
8703
- });
8704
- if (!isValidCharacterString) {
8705
- return;
8706
- }
8707
- const parsedValue = parseNumber(targetValue, locale, formatOptionsRef.current);
8708
- setInputValue(targetValue);
8709
- if (parsedValue !== null) {
8710
- setValue(parsedValue, DrawerRoot.createChangeEventDetails(DrawerRoot.inputChange, event.nativeEvent));
8711
- }
8712
- },
8713
- onKeyDown(event) {
8714
- if (event.defaultPrevented || readOnly || disabled) {
8715
- return;
8716
- }
8717
- const nativeEvent = event.nativeEvent;
8718
- allowInputSyncRef.current = true;
8719
- const allowedNonNumericKeys = getAllowedNonNumericKeys();
8720
- let isAllowedNonNumericKey = allowedNonNumericKeys.has(event.key);
8721
- const {
8722
- decimal,
8723
- currency,
8724
- percentSign
8725
- } = getNumberLocaleDetails(locale, formatOptionsRef.current);
8726
- const selectionStart = event.currentTarget.selectionStart;
8727
- const selectionEnd = event.currentTarget.selectionEnd;
8728
- const isAllSelected = selectionStart === 0 && selectionEnd === inputValue.length;
8729
-
8730
- // Normalize handling of plus/minus signs via precomputed regexes
8731
- const selectionContainsIndex = index => selectionStart != null && selectionEnd != null && index >= selectionStart && index < selectionEnd;
8732
- if (ANY_MINUS_DETECT_RE.test(event.key) && Array.from(allowedNonNumericKeys).some(k => ANY_MINUS_DETECT_RE.test(k || ''))) {
8733
- // Only allow one sign unless replacing the existing one or all text is selected
8734
- const existingIndex = inputValue.search(ANY_MINUS_RE);
8735
- const isReplacingExisting = existingIndex != null && existingIndex !== -1 && selectionContainsIndex(existingIndex);
8736
- isAllowedNonNumericKey = !(ANY_MINUS_DETECT_RE.test(inputValue) || ANY_PLUS_DETECT_RE.test(inputValue)) || isAllSelected || isReplacingExisting;
8737
- }
8738
- if (ANY_PLUS_DETECT_RE.test(event.key) && Array.from(allowedNonNumericKeys).some(k => ANY_PLUS_DETECT_RE.test(k || ''))) {
8739
- const existingIndex = inputValue.search(ANY_PLUS_RE);
8740
- const isReplacingExisting = existingIndex != null && existingIndex !== -1 && selectionContainsIndex(existingIndex);
8741
- isAllowedNonNumericKey = !(ANY_MINUS_DETECT_RE.test(inputValue) || ANY_PLUS_DETECT_RE.test(inputValue)) || isAllSelected || isReplacingExisting;
8742
- }
8743
-
8744
- // Only allow one of each symbol.
8745
- [decimal, currency, percentSign].forEach(symbol => {
8746
- if (event.key === symbol) {
8747
- const symbolIndex = inputValue.indexOf(symbol);
8748
- const isSymbolHighlighted = selectionContainsIndex(symbolIndex);
8749
- isAllowedNonNumericKey = !inputValue.includes(symbol) || isAllSelected || isSymbolHighlighted;
8750
- }
8751
- });
8752
- const isAsciiDigit = event.key >= '0' && event.key <= '9';
8753
- const isArabicNumeral = ARABIC_DETECT_RE.test(event.key);
8754
- const isHanNumeral = HAN_DETECT_RE.test(event.key);
8755
- const isFullwidthNumeral = FULLWIDTH_DETECT_RE.test(event.key);
8756
- const isNavigateKey = NAVIGATE_KEYS.has(event.key);
8757
- if (
8758
- // Allow composition events (e.g., pinyin)
8759
- // event.nativeEvent.isComposing does not work in Safari:
8760
- // https://bugs.webkit.org/show_bug.cgi?id=165004
8761
- event.which === 229 || event.altKey || event.ctrlKey || event.metaKey || isAllowedNonNumericKey || isAsciiDigit || isArabicNumeral || isFullwidthNumeral || isHanNumeral || isNavigateKey) {
8762
- return;
8763
- }
8764
-
8765
- // We need to commit the number at this point if the input hasn't been blurred.
8766
- const parsedValue = parseNumber(inputValue, locale, formatOptionsRef.current);
8767
- const amount = getStepAmount(event) ?? DEFAULT_STEP;
8768
-
8769
- // Prevent insertion of text or caret from moving.
8770
- DrawerRoot.stopEvent(event);
8771
- const commitDetails = DrawerRoot.createGenericEventDetails(DrawerRoot.keyboard, nativeEvent);
8772
- if (event.key === 'ArrowUp') {
8773
- incrementValue(amount, {
8774
- direction: 1,
8775
- currentValue: parsedValue,
8776
- event: nativeEvent,
8777
- reason: DrawerRoot.keyboard
8778
- });
8779
- onValueCommitted(lastChangedValueRef.current ?? valueRef.current, commitDetails);
8780
- } else if (event.key === 'ArrowDown') {
8781
- incrementValue(amount, {
8782
- direction: -1,
8783
- currentValue: parsedValue,
8784
- event: nativeEvent,
8785
- reason: DrawerRoot.keyboard
8786
- });
8787
- onValueCommitted(lastChangedValueRef.current ?? valueRef.current, commitDetails);
8788
- } else if (event.key === 'Home' && min != null) {
8789
- setValue(min, DrawerRoot.createChangeEventDetails(DrawerRoot.keyboard, nativeEvent));
8790
- onValueCommitted(lastChangedValueRef.current ?? valueRef.current, commitDetails);
8791
- } else if (event.key === 'End' && max != null) {
8792
- setValue(max, DrawerRoot.createChangeEventDetails(DrawerRoot.keyboard, nativeEvent));
8793
- onValueCommitted(lastChangedValueRef.current ?? valueRef.current, commitDetails);
8794
- }
8795
- },
8796
- onPaste(event) {
8797
- if (event.defaultPrevented || readOnly || disabled) {
8798
- return;
8799
- }
8800
-
8801
- // Prevent `onChange` from being called.
8802
- event.preventDefault();
8803
- const clipboardData = event.clipboardData || window.Clipboard;
8804
- const pastedData = clipboardData.getData('text/plain');
8805
- const parsedValue = parseNumber(pastedData, locale, formatOptionsRef.current);
8806
- if (parsedValue !== null) {
8807
- allowInputSyncRef.current = false;
8808
- setValue(parsedValue, DrawerRoot.createChangeEventDetails(DrawerRoot.inputPaste, event.nativeEvent));
8809
- setInputValue(pastedData);
8810
- }
8811
- }
8812
- };
8813
- const element = useRenderElement.useRenderElement('input', componentProps, {
8814
- ref: [forwardedRef, inputRef],
8815
- state,
8816
- props: [inputProps, validation.getValidationProps(), elementProps],
8817
- stateAttributesMapping
8818
- });
8819
- return element;
8820
- });
8821
- if (process.env.NODE_ENV !== "production") NumberFieldInput.displayName = "NumberFieldInput";
8822
-
8823
7048
  const NumberFieldScrubAreaContext = /*#__PURE__*/React__namespace.createContext(undefined);
8824
7049
  if (process.env.NODE_ENV !== "production") NumberFieldScrubAreaContext.displayName = "NumberFieldScrubAreaContext";
8825
7050
  function useNumberFieldScrubAreaContext() {
@@ -8832,7 +7057,7 @@ function useNumberFieldScrubAreaContext() {
8832
7057
 
8833
7058
  // Calculates the viewport rect for the virtual cursor.
8834
7059
  function getViewportRect(teleportDistance, scrubAreaEl) {
8835
- const win = index_esm.getWindow(scrubAreaEl);
7060
+ const win = floatingUi_utils_dom.getWindow(scrubAreaEl);
8836
7061
  const rect = scrubAreaEl.getBoundingClientRect();
8837
7062
  if (rect && teleportDistance != null) {
8838
7063
  return {
@@ -8862,7 +7087,7 @@ function getViewportRect(teleportDistance, scrubAreaEl) {
8862
7087
  // This lets us invert the scale of the cursor to match the OS scale, in which the cursor doesn't
8863
7088
  // scale with the content on pinch-zoom.
8864
7089
  function subscribeToVisualViewportResize(element, visualScaleRef) {
8865
- const vV = index_esm.getWindow(element).visualViewport;
7090
+ const vV = floatingUi_utils_dom.getWindow(element).visualViewport;
8866
7091
  if (!vV) {
8867
7092
  return () => {};
8868
7093
  }
@@ -8898,7 +7123,7 @@ const NumberFieldScrubArea = /*#__PURE__*/React__namespace.forwardRef(function N
8898
7123
  onValueCommitted,
8899
7124
  lastChangedValueRef,
8900
7125
  valueRef
8901
- } = useNumberFieldRootContext();
7126
+ } = NumberFieldInput.useNumberFieldRootContext();
8902
7127
  const scrubAreaRef = React__namespace.useRef(null);
8903
7128
  const isScrubbingRef = React__namespace.useRef(false);
8904
7129
  const didMoveRef = React__namespace.useRef(false);
@@ -8909,7 +7134,7 @@ const NumberFieldScrubArea = /*#__PURE__*/React__namespace.forwardRef(function N
8909
7134
  y: 0
8910
7135
  });
8911
7136
  const visualScaleRef = React__namespace.useRef(1);
8912
- const exitPointerLockTimeout = DrawerRoot.useTimeout();
7137
+ const exitPointerLockTimeout = useValueChanged.useTimeout();
8913
7138
  const [isTouchInput, setIsTouchInput] = React__namespace.useState(false);
8914
7139
  const [isPointerLockDenied, setIsPointerLockDenied] = React__namespace.useState(false);
8915
7140
  const [isScrubbing, setIsScrubbing] = React__namespace.useState(false);
@@ -8924,7 +7149,7 @@ const NumberFieldScrubArea = /*#__PURE__*/React__namespace.forwardRef(function N
8924
7149
  scrubAreaCursorRef.current.style.transform = `translate3d(${x}px,${y}px,0) scale(${1 / visualScaleRef.current})`;
8925
7150
  }
8926
7151
  }
8927
- const onScrub = DrawerRoot.useStableCallback(({
7152
+ const onScrub = useValueChanged.useStableCallback(({
8928
7153
  movementX,
8929
7154
  movementY
8930
7155
  }) => {
@@ -8954,7 +7179,7 @@ const NumberFieldScrubArea = /*#__PURE__*/React__namespace.forwardRef(function N
8954
7179
  virtualCursorCoords.current = newCoords;
8955
7180
  updateCursorTransform(newCoords.x, newCoords.y);
8956
7181
  });
8957
- const onScrubbingChange = DrawerRoot.useStableCallback((scrubbingValue, {
7182
+ const onScrubbingChange = useValueChanged.useStableCallback((scrubbingValue, {
8958
7183
  clientX,
8959
7184
  clientY
8960
7185
  }) => {
@@ -8982,13 +7207,13 @@ const NumberFieldScrubArea = /*#__PURE__*/React__namespace.forwardRef(function N
8982
7207
  function handleScrubPointerUp(event) {
8983
7208
  function handler() {
8984
7209
  try {
8985
- DrawerRoot.ownerDocument(scrubAreaRef.current).exitPointerLock();
7210
+ useValueChanged.ownerDocument(scrubAreaRef.current).exitPointerLock();
8986
7211
  } catch {
8987
7212
  // Ignore errors.
8988
7213
  } finally {
8989
7214
  isScrubbingRef.current = false;
8990
7215
  onScrubbingChange(false, event);
8991
- onValueCommitted(lastChangedValueRef.current ?? valueRef.current, DrawerRoot.createGenericEventDetails(DrawerRoot.scrub, event));
7216
+ onValueCommitted(lastChangedValueRef.current ?? valueRef.current, useValueChanged.createGenericEventDetails(useValueChanged.scrub, event));
8992
7217
 
8993
7218
  // Manually dispatch a click event if no movement happened, since
8994
7219
  // preventDefault on pointerdown prevents the browser click event.
@@ -9002,7 +7227,7 @@ const NumberFieldScrubArea = /*#__PURE__*/React__namespace.forwardRef(function N
9002
7227
  pointerDownTargetRef.current = null;
9003
7228
  }
9004
7229
  }
9005
- if (DrawerRoot.isFirefox) {
7230
+ if (useValueChanged.isFirefox) {
9006
7231
  // Firefox needs a small delay here when soft-clicking as the pointer
9007
7232
  // lock will not release otherwise.
9008
7233
  exitPointerLockTimeout.start(20, handler);
@@ -9027,18 +7252,18 @@ const NumberFieldScrubArea = /*#__PURE__*/React__namespace.forwardRef(function N
9027
7252
  cumulativeDelta = 0;
9028
7253
  didMoveRef.current = true;
9029
7254
  const dValue = direction === 'vertical' ? -movementY : movementX;
9030
- const stepAmount = getStepAmount(event) ?? DEFAULT_STEP;
7255
+ const stepAmount = getStepAmount(event) ?? NumberFieldInput.DEFAULT_STEP;
9031
7256
  const rawAmount = dValue * stepAmount;
9032
7257
  if (rawAmount !== 0) {
9033
7258
  incrementValue(Math.abs(rawAmount), {
9034
7259
  direction: rawAmount >= 0 ? 1 : -1,
9035
7260
  event,
9036
- reason: DrawerRoot.scrub
7261
+ reason: useValueChanged.scrub
9037
7262
  });
9038
7263
  }
9039
7264
  }
9040
7265
  }
9041
- const win = index_esm.getWindow(inputRef.current);
7266
+ const win = floatingUi_utils_dom.getWindow(inputRef.current);
9042
7267
  win.addEventListener('pointerup', handleScrubPointerUp, true);
9043
7268
  win.addEventListener('pointermove', handleScrubPointerMove, true);
9044
7269
  return () => {
@@ -9088,12 +7313,12 @@ const NumberFieldScrubArea = /*#__PURE__*/React__namespace.forwardRef(function N
9088
7313
  onScrubbingChange(true, event.nativeEvent);
9089
7314
 
9090
7315
  // WebKit causes significant layout shift with the native message, so we can't use it.
9091
- if (!isTouch && !DrawerRoot.isWebKit) {
7316
+ if (!isTouch && !useValueChanged.isWebKit) {
9092
7317
  try {
9093
7318
  // Avoid non-deterministic errors in testing environments. This error sometimes
9094
7319
  // appears:
9095
7320
  // "The root document of this element is not valid for pointer lock."
9096
- await DrawerRoot.ownerDocument(scrubAreaRef.current).body.requestPointerLock();
7321
+ await useValueChanged.ownerDocument(scrubAreaRef.current).body.requestPointerLock();
9097
7322
  setIsPointerLockDenied(false);
9098
7323
  } catch (error) {
9099
7324
  setIsPointerLockDenied(true);
@@ -9111,7 +7336,7 @@ const NumberFieldScrubArea = /*#__PURE__*/React__namespace.forwardRef(function N
9111
7336
  ref: [forwardedRef, scrubAreaRef],
9112
7337
  state,
9113
7338
  props: [defaultProps, elementProps],
9114
- stateAttributesMapping: stateAttributesMapping$1
7339
+ stateAttributesMapping: NumberFieldInput.stateAttributesMapping
9115
7340
  });
9116
7341
  const contextValue = React__namespace.useMemo(() => ({
9117
7342
  isScrubbing,
@@ -9147,7 +7372,7 @@ const NumberFieldScrubAreaCursor = /*#__PURE__*/React__namespace.forwardRef(func
9147
7372
  } = componentProps;
9148
7373
  const {
9149
7374
  state
9150
- } = useNumberFieldRootContext();
7375
+ } = NumberFieldInput.useNumberFieldRootContext();
9151
7376
  const {
9152
7377
  isScrubbing,
9153
7378
  isTouchInput,
@@ -9155,7 +7380,7 @@ const NumberFieldScrubAreaCursor = /*#__PURE__*/React__namespace.forwardRef(func
9155
7380
  scrubAreaCursorRef
9156
7381
  } = useNumberFieldScrubAreaContext();
9157
7382
  const [domElement, setDomElement] = React__namespace.useState(null);
9158
- const shouldRender = isScrubbing && !DrawerRoot.isWebKit && !isTouchInput && !isPointerLockDenied;
7383
+ const shouldRender = isScrubbing && !useValueChanged.isWebKit && !isTouchInput && !isPointerLockDenied;
9159
7384
  const element = useRenderElement.useRenderElement('span', componentProps, {
9160
7385
  enabled: shouldRender,
9161
7386
  ref: [forwardedRef, scrubAreaCursorRef, setDomElement],
@@ -9169,19 +7394,19 @@ const NumberFieldScrubAreaCursor = /*#__PURE__*/React__namespace.forwardRef(func
9169
7394
  pointerEvents: 'none'
9170
7395
  }
9171
7396
  }, elementProps],
9172
- stateAttributesMapping: stateAttributesMapping$1
7397
+ stateAttributesMapping: NumberFieldInput.stateAttributesMapping
9173
7398
  });
9174
- return element && /*#__PURE__*/ReactDOM__namespace.createPortal(element, DrawerRoot.ownerDocument(domElement).body);
7399
+ return element && /*#__PURE__*/ReactDOM__namespace.createPortal(element, useValueChanged.ownerDocument(domElement).body);
9175
7400
  });
9176
7401
  if (process.env.NODE_ENV !== "production") NumberFieldScrubAreaCursor.displayName = "NumberFieldScrubAreaCursor";
9177
7402
 
9178
7403
  var index_parts = /*#__PURE__*/Object.freeze({
9179
7404
  __proto__: null,
9180
- Decrement: NumberFieldDecrement,
9181
- Group: NumberFieldGroup,
9182
- Increment: NumberFieldIncrement,
9183
- Input: NumberFieldInput,
9184
- Root: NumberFieldRoot,
7405
+ Decrement: NumberFieldInput.NumberFieldDecrement,
7406
+ Group: NumberFieldInput.NumberFieldGroup,
7407
+ Increment: NumberFieldInput.NumberFieldIncrement,
7408
+ Input: NumberFieldInput.NumberFieldInput,
7409
+ Root: NumberFieldInput.NumberFieldRoot,
9185
7410
  ScrubArea: NumberFieldScrubArea,
9186
7411
  ScrubAreaCursor: NumberFieldScrubAreaCursor
9187
7412
  });