@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.
- package/dist/Autocomplete/index.cjs +1 -0
- package/dist/Autocomplete/index.mjs +1 -0
- package/dist/Card/index.cjs +3 -0
- package/dist/Card/index.mjs +3 -0
- package/dist/Chip/index.cjs +1 -0
- package/dist/Chip/index.mjs +1 -0
- package/dist/Chips/InternalChipDismissible/hooks/index.cjs +1 -0
- package/dist/Chips/InternalChipDismissible/hooks/index.mjs +1 -0
- package/dist/Chips/InternalChipDismissible/index.cjs +1 -0
- package/dist/Chips/InternalChipDismissible/index.mjs +1 -0
- package/dist/Chips/index.cjs +1 -0
- package/dist/Chips/index.mjs +1 -0
- package/dist/Combobox/components/ComboboxActivator/index.cjs +1 -0
- package/dist/Combobox/components/ComboboxActivator/index.mjs +1 -0
- package/dist/Combobox/components/ComboboxContent/index.cjs +1 -0
- package/dist/Combobox/components/ComboboxContent/index.mjs +1 -0
- package/dist/Combobox/components/ComboboxTrigger/index.cjs +1 -0
- package/dist/Combobox/components/ComboboxTrigger/index.mjs +1 -0
- package/dist/Combobox/index.cjs +1 -0
- package/dist/Combobox/index.mjs +1 -0
- package/dist/ConfirmationModal/index.cjs +1 -0
- package/dist/ConfirmationModal/index.mjs +1 -0
- package/dist/DataDump/index.cjs +3 -0
- package/dist/DataDump/index.mjs +3 -0
- package/dist/DataList/components/DataListActions/index.cjs +1 -0
- package/dist/DataList/components/DataListActions/index.mjs +1 -0
- package/dist/DataList/components/DataListBulkActions/index.cjs +1 -0
- package/dist/DataList/components/DataListBulkActions/index.mjs +1 -0
- package/dist/DataList/components/DataListFilters/components/DataListSort/index.cjs +1 -0
- package/dist/DataList/components/DataListFilters/components/DataListSort/index.mjs +1 -0
- package/dist/DataList/components/DataListFilters/index.cjs +1 -0
- package/dist/DataList/components/DataListFilters/index.mjs +1 -0
- package/dist/DataList/components/DataListHeader/index.cjs +1 -0
- package/dist/DataList/components/DataListHeader/index.mjs +1 -0
- package/dist/DataList/components/DataListItem/index.cjs +1 -0
- package/dist/DataList/components/DataListItem/index.mjs +1 -0
- package/dist/DataList/components/DataListItemActions/index.cjs +1 -0
- package/dist/DataList/components/DataListItemActions/index.mjs +1 -0
- package/dist/DataList/components/DataListItemActionsOverflow/index.cjs +1 -0
- package/dist/DataList/components/DataListItemActionsOverflow/index.mjs +1 -0
- package/dist/DataList/components/DataListItems/index.cjs +1 -0
- package/dist/DataList/components/DataListItems/index.mjs +1 -0
- package/dist/DataList/components/DataListLayout/index.cjs +1 -0
- package/dist/DataList/components/DataListLayout/index.mjs +1 -0
- package/dist/DataList/components/DataListLayoutActions/index.cjs +1 -0
- package/dist/DataList/components/DataListLayoutActions/index.mjs +1 -0
- package/dist/DataList/index.cjs +1 -0
- package/dist/DataList/index.mjs +1 -0
- package/dist/DatePicker/index.cjs +1 -0
- package/dist/DatePicker/index.mjs +1 -0
- package/dist/DrawerRoot-cjs.js +181 -968
- package/dist/DrawerRoot-es.js +5 -734
- package/dist/FormatFile/index.cjs +1 -0
- package/dist/FormatFile/index.mjs +1 -0
- package/dist/Gallery/index.cjs +1 -0
- package/dist/Gallery/index.mjs +1 -0
- package/dist/InputDate/index.cjs +1 -0
- package/dist/InputDate/index.mjs +1 -0
- package/dist/InputNumberExperimental-cjs.js +783 -0
- package/dist/InputNumberExperimental-es.js +763 -0
- package/dist/LightBox/index.cjs +1 -0
- package/dist/LightBox/index.mjs +1 -0
- package/dist/Menu/index.cjs +3 -0
- package/dist/Menu/index.mjs +3 -0
- package/dist/MenuSubmenuTrigger-cjs.js +202 -447
- package/dist/MenuSubmenuTrigger-es.js +7 -249
- package/dist/Modal/index.cjs +1 -0
- package/dist/Modal/index.mjs +1 -0
- package/dist/NumberFieldInput-cjs.js +1828 -0
- package/dist/NumberFieldInput-es.js +1788 -0
- package/dist/Page/index.cjs +3 -0
- package/dist/Page/index.mjs +3 -0
- package/dist/Popover/index.cjs +1 -0
- package/dist/Popover/index.mjs +1 -0
- package/dist/Tooltip/index.cjs +1 -0
- package/dist/Tooltip/index.mjs +1 -0
- package/dist/docs/Menu/Menu.md +197 -37
- package/dist/floating-ui.react-cjs.js +35 -34
- package/dist/floating-ui.react-dom-cjs.js +65 -64
- package/dist/floating-ui.react-dom-es.js +2 -1
- package/dist/floating-ui.react-es.js +2 -1
- package/dist/floating-ui.utils.dom-cjs.js +185 -0
- package/dist/floating-ui.utils.dom-es.js +165 -0
- package/dist/index.cjs +3 -0
- package/dist/index.esm-cjs.js +0 -183
- package/dist/index.esm-es.js +1 -165
- package/dist/index.mjs +3 -0
- package/dist/primitives/BottomSheet/index.cjs +3 -1
- package/dist/primitives/BottomSheet/index.mjs +3 -1
- package/dist/primitives/InputNumberExperimental/InputNumberExperimental.d.ts +20 -0
- package/dist/primitives/InputNumberExperimental/index.cjs +22 -0
- package/dist/primitives/InputNumberExperimental/index.d.ts +2 -0
- package/dist/primitives/InputNumberExperimental/index.mjs +16 -0
- package/dist/primitives/InputNumberExperimental/types.d.ts +147 -0
- package/dist/primitives/index.cjs +9 -1
- package/dist/primitives/index.d.ts +2 -0
- package/dist/primitives/index.mjs +8 -1
- package/dist/styles.css +499 -0
- package/dist/unstyledPrimitives/index.cjs +264 -2039
- package/dist/unstyledPrimitives/index.mjs +72 -1847
- package/dist/useBaseUiId-cjs.js +275 -0
- package/dist/useBaseUiId-es.js +251 -0
- package/dist/useValueChanged-cjs.js +820 -0
- package/dist/useValueChanged-es.js +736 -0
- package/package.json +2 -2
- 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
|
|
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 =
|
|
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$
|
|
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
|
-
|
|
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$
|
|
142
|
+
stateAttributesMapping: stateAttributesMapping$8
|
|
139
143
|
});
|
|
140
144
|
});
|
|
141
145
|
if (process.env.NODE_ENV !== "production") DrawerIndent.displayName = "DrawerIndent";
|
|
142
146
|
|
|
143
|
-
const stateAttributesMapping$
|
|
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$
|
|
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 =
|
|
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 =
|
|
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$
|
|
297
|
+
const stateAttributesMapping$6 = {
|
|
304
298
|
...DrawerRoot.popupStateMapping,
|
|
305
|
-
...
|
|
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$
|
|
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,
|
|
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,
|
|
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,
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
650
|
-
const nextProgress = Number.isFinite(progress) ?
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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$
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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,
|
|
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,
|
|
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$
|
|
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 =
|
|
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
|
|
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 =
|
|
1889
|
+
const setSwipeDismissed = useValueChanged.useStableCallback(dismissed => {
|
|
1896
1890
|
setSwipeDismissedElements(store.context.popupRef.current, store.context.backdropRef.current, dismissed);
|
|
1897
1891
|
});
|
|
1898
|
-
const clearSwipeRelease =
|
|
1892
|
+
const clearSwipeRelease = useValueChanged.useStableCallback(() => {
|
|
1899
1893
|
setSwipeDismissed(false);
|
|
1900
|
-
store.context.popupRef.current?.removeAttribute(
|
|
1894
|
+
store.context.popupRef.current?.removeAttribute(useValueChanged.TransitionStatusDataAttributes.endingStyle);
|
|
1901
1895
|
setSwipeRelease(null);
|
|
1902
1896
|
});
|
|
1903
|
-
const applySwipeProgress =
|
|
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 =
|
|
1976
|
-
const durationMs =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
2023
|
-
const focusElement =
|
|
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 =
|
|
2074
|
-
resolvedProgress =
|
|
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 =
|
|
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(
|
|
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 =
|
|
2187
|
-
const velocityOffset = Number.isFinite(resolvedDirectionalVelocity) && Math.abs(resolvedDirectionalVelocity) >= SNAP_VELOCITY_THRESHOLD ?
|
|
2188
|
-
const targetOffset = snapToSequentialPoints ? dragTargetOffset :
|
|
2189
|
-
const snapPointEventDetails =
|
|
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 =
|
|
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 =
|
|
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,
|
|
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,
|
|
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 =
|
|
2331
|
-
const win =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 (!
|
|
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 =
|
|
2636
|
-
const focusElement =
|
|
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,
|
|
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$
|
|
2806
|
+
const stateAttributesMapping$4 = {
|
|
2813
2807
|
...DrawerRoot.popupStateMapping,
|
|
2814
|
-
...
|
|
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$
|
|
2838
|
+
stateAttributesMapping: stateAttributesMapping$4,
|
|
2845
2839
|
props: [{
|
|
2846
2840
|
role: 'presentation',
|
|
2847
2841
|
hidden: !mounted,
|
|
2848
2842
|
style: {
|
|
2849
|
-
pointerEvents: lastOpenChangeReason ===
|
|
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 =
|
|
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] =
|
|
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 =
|
|
2916
|
+
const handleClick = useValueChanged.useStableCallback(event => {
|
|
2923
2917
|
const details = {
|
|
2924
|
-
...
|
|
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
|
-
} =
|
|
2969
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
3055
|
-
const animationFrame =
|
|
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 =
|
|
3061
|
-
const onMeasureLayoutComplete =
|
|
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
|
-
|
|
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 =
|
|
3238
|
-
const cleanupFrame =
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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$
|
|
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$
|
|
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,
|
|
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,
|
|
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] =
|
|
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] =
|
|
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] =
|
|
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 =
|
|
4569
|
-
const onOpenChangeComplete =
|
|
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 =
|
|
4280
|
+
const triggerRef = useValueChanged.useValueAsRef(triggerElement);
|
|
4580
4281
|
const {
|
|
4581
4282
|
mounted,
|
|
4582
4283
|
setMounted,
|
|
4583
4284
|
transitionStatus
|
|
4584
|
-
} =
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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,
|
|
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,
|
|
4332
|
+
onItemHighlighted(activeValue, useValueChanged.createGenericEventDetails(type, undefined, {
|
|
4632
4333
|
index: options.activeIndex
|
|
4633
4334
|
}));
|
|
4634
4335
|
}
|
|
4635
4336
|
});
|
|
4636
|
-
const setInputValue =
|
|
4637
|
-
hadInputClearRef.current = eventDetails.reason ===
|
|
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 ===
|
|
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 =
|
|
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('',
|
|
4404
|
+
setInputValue('', useValueChanged.createChangeEventDetails(useValueChanged.inputClear, eventDetails.event));
|
|
4704
4405
|
}
|
|
4705
4406
|
}
|
|
4706
4407
|
setOpenUnwrapped(nextOpen);
|
|
4707
|
-
if (!nextOpen && inputInsidePopup && (eventDetails.reason ===
|
|
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 =
|
|
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),
|
|
4427
|
+
setInputValue(stringifyAsLabel(nextValue, itemToStringLabel), useValueChanged.createChangeEventDetails(eventDetails.reason, eventDetails.event));
|
|
4727
4428
|
}
|
|
4728
|
-
if (single && nextValue != null && eventDetails.reason !==
|
|
4429
|
+
if (single && nextValue != null && eventDetails.reason !== useValueChanged.inputChange && queryChangedAfterOpen && !inline) {
|
|
4729
4430
|
setCloseQuery(query);
|
|
4730
4431
|
}
|
|
4731
4432
|
});
|
|
4732
|
-
const handleSelection =
|
|
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 =
|
|
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('',
|
|
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 =
|
|
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 =
|
|
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('',
|
|
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('',
|
|
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 === '' ?
|
|
4817
|
-
setInputValue(stringVal,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
4645
|
+
useValueChanged.useValueChanged(query, () => {
|
|
4945
4646
|
if (!open || query === '' || query === String(initialDefaultInputValue)) {
|
|
4946
4647
|
return;
|
|
4947
4648
|
}
|
|
4948
4649
|
setQueryChangedAfterOpen(true);
|
|
4949
4650
|
});
|
|
4950
|
-
|
|
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,
|
|
4665
|
+
setInputValue(nextInputValue, useValueChanged.createChangeEventDetails(useValueChanged.none));
|
|
4965
4666
|
}
|
|
4966
4667
|
}
|
|
4967
4668
|
});
|
|
4968
|
-
|
|
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
|
-
|
|
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,
|
|
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:
|
|
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
|
-
|
|
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 =
|
|
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 ?
|
|
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 =
|
|
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,
|
|
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
|
-
} =
|
|
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 =
|
|
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 =
|
|
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,
|
|
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
|
-
|
|
5470
|
-
store.state.setOpen(true,
|
|
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
|
-
} =
|
|
5206
|
+
} = useBaseUiId.useButton({
|
|
5506
5207
|
native: false
|
|
5507
5208
|
});
|
|
5508
5209
|
const mergedRef = useRenderElement.useMergedRefs(forwardedRef, buttonRef);
|
|
5509
|
-
const handleDismiss =
|
|
5510
|
-
store.state.setOpen(false,
|
|
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:
|
|
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 =
|
|
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 =
|
|
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('',
|
|
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 (
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
5460
|
+
store.state.setInputValue(event.currentTarget.value, useValueChanged.createChangeEventDetails(useValueChanged.inputChange, event.nativeEvent));
|
|
5760
5461
|
const empty = event.currentTarget.value === '';
|
|
5761
|
-
const clearDetails =
|
|
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,
|
|
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
|
-
|
|
5809
|
-
const cursor =
|
|
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
|
-
|
|
5816
|
-
const cursor =
|
|
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 =
|
|
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,
|
|
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,
|
|
5568
|
+
store.state.setOpen(false, useValueChanged.createChangeEventDetails(useValueChanged.none, nativeEvent));
|
|
5868
5569
|
return;
|
|
5869
5570
|
}
|
|
5870
|
-
|
|
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 =
|
|
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$
|
|
5971
|
-
...
|
|
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
|
-
} =
|
|
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
|
-
} =
|
|
5720
|
+
} = useValueChanged.useTransitionStatus(visible);
|
|
6020
5721
|
const state = {
|
|
6021
5722
|
disabled,
|
|
6022
5723
|
open,
|
|
6023
5724
|
transitionStatus
|
|
6024
5725
|
};
|
|
6025
|
-
|
|
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('',
|
|
5750
|
+
store.state.setInputValue('', useValueChanged.createChangeEventDetails(useValueChanged.clearPress, event.nativeEvent));
|
|
6050
5751
|
if (selectionMode !== 'none') {
|
|
6051
|
-
store.state.setSelectedValue(Array.isArray(selectedValue) ? [] : null,
|
|
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$
|
|
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 =
|
|
5838
|
+
const setPositionerElement = useValueChanged.useStableCallback(element => {
|
|
6138
5839
|
store.set('positionerElement', element);
|
|
6139
5840
|
});
|
|
6140
|
-
const setListElement =
|
|
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
|
-
|
|
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$
|
|
5963
|
+
const stateAttributesMapping$1 = {
|
|
6263
5964
|
...DrawerRoot.popupStateMapping,
|
|
6264
|
-
...
|
|
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$
|
|
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
|
-
|
|
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 =
|
|
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
|
|
6107
|
+
const stateAttributesMapping = {
|
|
6407
6108
|
...DrawerRoot.popupStateMapping,
|
|
6408
|
-
...
|
|
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
|
-
|
|
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
|
|
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 =
|
|
6596
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
} =
|
|
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 =
|
|
6860
|
-
|
|
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 =
|
|
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 =
|
|
6896
|
-
if (
|
|
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 =
|
|
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
|
-
|
|
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
|
-
} =
|
|
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:
|
|
6763
|
+
stateAttributesMapping: useValueChanged.transitionStatusMapping
|
|
7063
6764
|
});
|
|
7064
|
-
|
|
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
|
-
|
|
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),
|
|
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
|
-
|
|
6870
|
+
useValueChanged.stopEvent(event);
|
|
7170
6871
|
nextIndex = undefined;
|
|
7171
6872
|
} else if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
7172
|
-
|
|
7173
|
-
store.state.setOpen(true,
|
|
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
|
-
} =
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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,
|
|
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 (
|
|
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:
|
|
7261
|
+
reason: useValueChanged.scrub
|
|
9037
7262
|
});
|
|
9038
7263
|
}
|
|
9039
7264
|
}
|
|
9040
7265
|
}
|
|
9041
|
-
const win =
|
|
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 && !
|
|
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
|
|
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
|
|
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 && !
|
|
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
|
|
7397
|
+
stateAttributesMapping: NumberFieldInput.stateAttributesMapping
|
|
9173
7398
|
});
|
|
9174
|
-
return element && /*#__PURE__*/ReactDOM__namespace.createPortal(element,
|
|
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
|
});
|