@jobber/components 8.26.3 → 8.27.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/Select.d.ts +1 -0
  2. package/Select.js +17 -0
  3. package/dist/BottomSheet-cjs.js +8 -7
  4. package/dist/BottomSheet-es.js +9 -8
  5. package/dist/ComboboxChipRemove-cjs.js +2 -1
  6. package/dist/ComboboxChipRemove-es.js +4 -3
  7. package/dist/DrawerDescription-cjs.js +4 -97
  8. package/dist/DrawerDescription-es.js +6 -98
  9. package/dist/FieldDescription-cjs.js +880 -0
  10. package/dist/FieldDescription-es.js +856 -0
  11. package/dist/InputNumberExperimental-cjs.js +5 -875
  12. package/dist/InputNumberExperimental-es.js +2 -854
  13. package/dist/MenuSubmenuTrigger-es.js +4 -4
  14. package/dist/Modal/index.cjs +12 -2
  15. package/dist/Modal/index.mjs +13 -3
  16. package/dist/NumberFieldInput-cjs.js +2 -2
  17. package/dist/NumberFieldInput-es.js +1 -1
  18. package/dist/ScrollAreaViewport-cjs.js +2122 -12
  19. package/dist/ScrollAreaViewport-es.js +2118 -13
  20. package/dist/Select/Select.d.ts +31 -0
  21. package/dist/Select/Select.types.d.ts +145 -0
  22. package/dist/Select/SelectBottomSheet.d.ts +4 -0
  23. package/dist/Select/SelectDropdown.d.ts +4 -0
  24. package/dist/Select/index.cjs +41 -0
  25. package/dist/Select/index.d.ts +2 -0
  26. package/dist/Select/index.mjs +35 -0
  27. package/dist/Select-cjs.js +231 -0
  28. package/dist/Select-es.js +229 -0
  29. package/dist/SelectPrimitive-cjs.js +20 -3
  30. package/dist/SelectPrimitive-es.js +20 -3
  31. package/dist/dialogReturnFocus-cjs.js +8 -5
  32. package/dist/dialogReturnFocus-es.js +9 -6
  33. package/dist/docs/Dialog/Dialog.md +74 -21
  34. package/dist/docs/Select/Select.md +428 -0
  35. package/dist/docs/SelectPrimitive/SelectPrimitive.md +14 -1
  36. package/dist/docs/index.md +1 -0
  37. package/dist/floating-ui.react-dom-es.js +1 -1
  38. package/dist/floating-ui.react-es.js +1 -1
  39. package/dist/floating-ui.utils.dom-es.js +1 -1
  40. package/dist/index.cjs +9 -0
  41. package/dist/index.d.mts +1 -0
  42. package/dist/index.d.ts +1 -0
  43. package/dist/index.mjs +8 -0
  44. package/dist/primitives/ComboboxPrimitive/index.cjs +1 -0
  45. package/dist/primitives/ComboboxPrimitive/index.mjs +1 -0
  46. package/dist/primitives/HelperText/HelperText.d.ts +2 -1
  47. package/dist/primitives/InputNumberExperimental/index.cjs +3 -1
  48. package/dist/primitives/InputNumberExperimental/index.mjs +3 -1
  49. package/dist/primitives/SelectPrimitive/SelectPrimitive.d.ts +11 -0
  50. package/dist/primitives/SelectPrimitive/index.d.ts +1 -1
  51. package/dist/primitives/SelectPrimitive/types.d.ts +15 -0
  52. package/dist/primitives/index.cjs +2 -0
  53. package/dist/primitives/index.mjs +2 -0
  54. package/dist/stringifyLocale-cjs.js +13 -0
  55. package/dist/stringifyLocale-es.js +11 -0
  56. package/dist/styles.css +300 -10
  57. package/dist/unstyledPrimitives/index.cjs +219 -2230
  58. package/dist/unstyledPrimitives/index.mjs +225 -2236
  59. package/dist/useButton-es.js +2 -2
  60. package/dist/useCompositeListItem-es.js +1 -1
  61. package/dist/useLabel-cjs.js +0 -11
  62. package/dist/useLabel-es.js +2 -12
  63. package/dist/useScrollLock-es.js +3 -3
  64. package/dist/utils/meta/meta.json +5 -0
  65. package/package.json +7 -2
@@ -7,878 +7,8 @@ var ActivityIndicator = require('./ActivityIndicator-cjs.js');
7
7
  var Button = require('./Button-cjs.js');
8
8
  var Icon = require('./Icon-cjs.js');
9
9
  var useRenderElement = require('./useRenderElement-cjs.js');
10
- var useButton = require('./useButton-cjs.js');
11
- var useLabelableId = require('./useLabelableId-cjs.js');
12
- var jsxRuntime = require('react/jsx-runtime');
10
+ var FieldDescription = require('./FieldDescription-cjs.js');
13
11
  var NumberFieldInput = require('./NumberFieldInput-cjs.js');
14
- var useLabel = require('./useLabel-cjs.js');
15
-
16
- function _interopNamespaceDefault(e) {
17
- var n = Object.create(null);
18
- if (e) {
19
- Object.keys(e).forEach(function (k) {
20
- if (k !== 'default') {
21
- var d = Object.getOwnPropertyDescriptor(e, k);
22
- Object.defineProperty(n, k, d.get ? d : {
23
- enumerable: true,
24
- get: function () { return e[k]; }
25
- });
26
- }
27
- });
28
- }
29
- n.default = e;
30
- return Object.freeze(n);
31
- }
32
-
33
- var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
34
-
35
- const FieldItemContext = /*#__PURE__*/React__namespace.createContext({
36
- disabled: false
37
- });
38
- if (process.env.NODE_ENV !== "production") FieldItemContext.displayName = "FieldItemContext";
39
- function useFieldItemContext() {
40
- const context = React__namespace.useContext(FieldItemContext);
41
- return context;
42
- }
43
-
44
- const FieldsetRootContext = /*#__PURE__*/React__namespace.createContext(undefined);
45
- if (process.env.NODE_ENV !== "production") FieldsetRootContext.displayName = "FieldsetRootContext";
46
- function useFieldsetRootContext(optional = false) {
47
- const context = React__namespace.useContext(FieldsetRootContext);
48
- if (!context && !optional) {
49
- throw new Error(process.env.NODE_ENV !== "production" ? 'Base UI: FieldsetRootContext is missing. Fieldset parts must be placed within <Fieldset.Root>.' : useRenderElement.formatErrorMessage(86));
50
- }
51
- return context;
52
- }
53
-
54
- const LabelableProvider = function LabelableProvider(props) {
55
- const defaultId = useButton.useBaseUiId();
56
- const initialControlId = props.controlId === undefined ? defaultId : props.controlId;
57
- const [controlId, setControlIdState] = React__namespace.useState(initialControlId);
58
- const [labelId, setLabelId] = React__namespace.useState(props.labelId);
59
- const [messageIds, setMessageIds] = React__namespace.useState([]);
60
- const registrationsRef = useRenderElement.useRefWithInit(() => new Map());
61
- const {
62
- messageIds: parentMessageIds
63
- } = useLabelableId.useLabelableContext();
64
- const registerControlId = useButton.useStableCallback((source, nextId) => {
65
- const registrations = registrationsRef.current;
66
- if (nextId === undefined) {
67
- registrations.delete(source);
68
- return;
69
- }
70
- registrations.set(source, nextId);
71
-
72
- // Only flush when registering, not when unregistering.
73
- // This prevents loops during rapid unmount/remount cycles (e.g. React Activity).
74
- // The next registration will pick up the correct state.
75
- setControlIdState(prev => {
76
- if (registrations.size === 0) {
77
- return undefined;
78
- }
79
- let nextControlId;
80
- for (const id of registrations.values()) {
81
- if (prev !== undefined && id === prev) {
82
- return prev;
83
- }
84
- if (nextControlId === undefined) {
85
- nextControlId = id;
86
- }
87
- }
88
- return nextControlId;
89
- });
90
- });
91
- const getDescriptionProps = React__namespace.useCallback(externalProps => {
92
- const ids = externalProps['aria-describedby'] ? externalProps['aria-describedby'].split(' ') : [];
93
- ids.push(...parentMessageIds, ...messageIds);
94
- return {
95
- ...externalProps,
96
- 'aria-describedby': Array.from(new Set(ids)).join(' ') || undefined
97
- };
98
- }, [parentMessageIds, messageIds]);
99
- const contextValue = React__namespace.useMemo(() => ({
100
- controlId,
101
- registerControlId,
102
- labelId,
103
- setLabelId,
104
- messageIds,
105
- setMessageIds,
106
- getDescriptionProps
107
- }), [controlId, registerControlId, labelId, setLabelId, messageIds, setMessageIds, getDescriptionProps]);
108
- return /*#__PURE__*/jsxRuntime.jsx(useLabelableId.LabelableContext.Provider, {
109
- value: contextValue,
110
- children: props.children
111
- });
112
- };
113
- if (process.env.NODE_ENV !== "production") LabelableProvider.displayName = "LabelableProvider";
114
-
115
- /**
116
- * Combines the field's client-side, stateful validity data with the external invalid state to
117
- * determine the field's true validity.
118
- */
119
- function getCombinedFieldValidityData(validityData, invalid) {
120
- return {
121
- ...validityData,
122
- state: {
123
- ...validityData.state,
124
- valid: !invalid && validityData.state.valid
125
- }
126
- };
127
- }
128
-
129
- const validityKeys = Object.keys(useLabelableId.DEFAULT_VALIDITY_STATE);
130
- function isOnlyValueMissing(state) {
131
- if (!state || state.valid || !state.valueMissing) {
132
- return false;
133
- }
134
- let onlyValueMissing = false;
135
- for (const key of validityKeys) {
136
- if (key === 'valid') {
137
- continue;
138
- }
139
- if (key === 'valueMissing') {
140
- onlyValueMissing = state[key];
141
- } else if (state[key]) {
142
- onlyValueMissing = false;
143
- }
144
- }
145
- return onlyValueMissing;
146
- }
147
-
148
- /**
149
- * Picks the input whose native validity should represent a field that owns several inputs (such as a
150
- * checkbox group). Prefers the first enabled currently-invalid input, where "first" follows Set
151
- * insertion order (mount order), and otherwise returns the first enabled input. Disabled inputs are
152
- * skipped because they don't participate in native constraint validation.
153
- */
154
- function findRepresentativeInput(inputs) {
155
- let fallback = null;
156
- for (const input of inputs) {
157
- if (input.disabled) {
158
- continue;
159
- }
160
- if (!input.validity.valid) {
161
- return input;
162
- }
163
- fallback ??= input;
164
- }
165
- return fallback;
166
- }
167
- function clearCustomValidity(element, inputs) {
168
- let didClearElement = false;
169
- for (const input of inputs) {
170
- input.setCustomValidity('');
171
- didClearElement ||= input === element;
172
- }
173
- if (!didClearElement) {
174
- element.setCustomValidity('');
175
- }
176
- }
177
- function useFieldValidation(params) {
178
- const {
179
- formRef
180
- } = useLabelableId.useFormContext();
181
- const {
182
- setValidityData,
183
- validate,
184
- validityData,
185
- validationDebounceTime,
186
- invalid,
187
- markedDirtyRef,
188
- state,
189
- shouldValidateOnChange,
190
- getRegisteredFieldId
191
- } = params;
192
- const {
193
- controlId,
194
- getDescriptionProps
195
- } = useLabelableId.useLabelableContext();
196
- const timeout = useButton.useTimeout();
197
- const inputRef = React__namespace.useRef(null);
198
- const registeredInputs = useRenderElement.useRefWithInit(() => new Set()).current;
199
- const validationCommitIdRef = React__namespace.useRef(0);
200
-
201
- // Checkbox groups register several inputs against a single field. Track them so a `required`
202
- // checkbox can't be satisfied by another input in the group, matching native per-checkbox behavior.
203
- const registerInput = React__namespace.useCallback(element => {
204
- if (!element) {
205
- return undefined;
206
- }
207
- registeredInputs.add(element);
208
- return () => {
209
- registeredInputs.delete(element);
210
- };
211
- }, [registeredInputs]);
212
- const commit = useButton.useStableCallback(async (value, revalidate = false) => {
213
- // A field can own several inputs (a checkbox group), but only the last-mounted one wins the shared
214
- // `inputRef`. Validate against the registry instead so every input counts; `inputRef` is the
215
- // fallback only when no registered input applies (none registered, or all of them disabled).
216
- const element = findRepresentativeInput(registeredInputs) ?? inputRef.current;
217
- if (!element) {
218
- return;
219
- }
220
- validationCommitIdRef.current += 1;
221
- const validationCommitId = validationCommitIdRef.current;
222
- function updateRegisteredFieldValidity(nextValidityData, externalInvalid = invalid) {
223
- const fieldId = getRegisteredFieldId() ?? controlId;
224
- if (fieldId == null) {
225
- return;
226
- }
227
- const currentFieldData = formRef.current.fields.get(fieldId);
228
- if (!currentFieldData) {
229
- return;
230
- }
231
- const validityDataWithFormErrors = getCombinedFieldValidityData(nextValidityData, externalInvalid);
232
- formRef.current.fields.set(fieldId, {
233
- ...currentFieldData,
234
- validityData: validityDataWithFormErrors
235
- });
236
- }
237
- if (revalidate) {
238
- if (state.valid !== false) {
239
- return;
240
- }
241
- const currentNativeValidity = element.validity;
242
- if (!currentNativeValidity.valueMissing) {
243
- // The 'valueMissing' (required) condition has been resolved by the user typing.
244
- // Temporarily mark the field as valid for this onChange event.
245
- // Other native errors (e.g., typeMismatch) will be caught by full validation on blur or submit.
246
- const nextValidityData = {
247
- value,
248
- state: {
249
- ...useLabelableId.DEFAULT_VALIDITY_STATE,
250
- valid: true
251
- },
252
- error: '',
253
- errors: [],
254
- initialValue: validityData.initialValue
255
- };
256
- clearCustomValidity(element, registeredInputs);
257
-
258
- // The required value is now present; ignore stale external invalid state for this pass.
259
- updateRegisteredFieldValidity(nextValidityData, false);
260
- setValidityData(nextValidityData);
261
- return;
262
- }
263
-
264
- // Value is still missing, or other conditions apply.
265
- // Let's use a representation of current validity for isOnlyValueMissing.
266
- const currentNativeValidityObject = validityKeys.reduce((acc, key) => {
267
- acc[key] = currentNativeValidity[key];
268
- return acc;
269
- }, {});
270
-
271
- // If it's (still) natively invalid due to something other than just valueMissing,
272
- // then bail from this revalidation on change to avoid "scolding" for other errors.
273
- if (!currentNativeValidityObject.valid && !isOnlyValueMissing(currentNativeValidityObject)) {
274
- return;
275
- }
276
-
277
- // If valueMissing is still true AND it's the only issue, or if the field is now natively valid,
278
- // let it fall through to the main validation logic below.
279
- }
280
- function getState(el) {
281
- const computedState = validityKeys.reduce((acc, key) => {
282
- acc[key] = el.validity[key];
283
- return acc;
284
- }, {});
285
- let hasOnlyValueMissingError = false;
286
- for (const key of validityKeys) {
287
- if (key === 'valid') {
288
- continue;
289
- }
290
- if (key === 'valueMissing' && computedState[key]) {
291
- hasOnlyValueMissingError = true;
292
- } else if (computedState[key]) {
293
- return computedState;
294
- }
295
- }
296
-
297
- // Only make `valueMissing` mark the field invalid if it's been changed
298
- // to reduce error noise.
299
- if (hasOnlyValueMissingError && !markedDirtyRef.current) {
300
- computedState.valid = true;
301
- computedState.valueMissing = false;
302
- }
303
- return computedState;
304
- }
305
- timeout.clear();
306
- let result = null;
307
- let validationErrors = [];
308
- const nextState = getState(element);
309
- let defaultValidationMessage;
310
- const isValidatingOnChange = shouldValidateOnChange();
311
- if (element.validationMessage && !isValidatingOnChange) {
312
- // not validating on change, if there is a `validationMessage` from
313
- // native validity, set errors and skip calling the custom validate fn
314
- defaultValidationMessage = element.validationMessage;
315
- validationErrors = [element.validationMessage];
316
- } else {
317
- // call the validate function because either
318
- // - validating on change, or
319
- // - native constraint validations passed, custom validity check is next
320
- const formValues = Array.from(formRef.current.fields.values()).reduce((acc, field) => {
321
- if (field.name) {
322
- acc[field.name] = field.getValue();
323
- }
324
- return acc;
325
- }, {});
326
- const resultOrPromise = validate(value, formValues);
327
- if (typeof resultOrPromise === 'object' && resultOrPromise !== null && 'then' in resultOrPromise) {
328
- result = await resultOrPromise;
329
- if (validationCommitId !== validationCommitIdRef.current) {
330
- return;
331
- }
332
- } else {
333
- result = resultOrPromise;
334
- }
335
- if (result !== null) {
336
- nextState.valid = false;
337
- nextState.customError = true;
338
- if (Array.isArray(result)) {
339
- validationErrors = result;
340
- element.setCustomValidity(result.join('\n'));
341
- } else if (result) {
342
- validationErrors = [result];
343
- element.setCustomValidity(result);
344
- }
345
- } else if (isValidatingOnChange) {
346
- // validate function returned no errors, if validating on change
347
- // we need to clear the custom validity state
348
- clearCustomValidity(element, registeredInputs);
349
- nextState.customError = false;
350
- if (element.validationMessage) {
351
- defaultValidationMessage = element.validationMessage;
352
- validationErrors = [element.validationMessage];
353
- } else if (element.validity.valid && !nextState.valid) {
354
- nextState.valid = true;
355
- }
356
- }
357
- }
358
- const nextValidityData = {
359
- value,
360
- state: nextState,
361
- error: defaultValidationMessage ?? (Array.isArray(result) ? result[0] : result ?? ''),
362
- errors: validationErrors,
363
- initialValue: validityData.initialValue
364
- };
365
-
366
- // Keep Form-level errors part of overall field validity for submit blocking/focus logic.
367
- updateRegisteredFieldValidity(nextValidityData);
368
- setValidityData(nextValidityData);
369
- });
370
- const change = useButton.useStableCallback(value => {
371
- timeout.clear();
372
- const validateOnChange = shouldValidateOnChange();
373
- if (validateOnChange && value !== '' && validationDebounceTime) {
374
- validationCommitIdRef.current += 1;
375
- timeout.start(validationDebounceTime, () => {
376
- commit(value);
377
- });
378
- } else {
379
- commit(value, !validateOnChange);
380
- }
381
- });
382
- const getValidationProps = React__namespace.useCallback((disabled, externalProps = {}) => useRenderElement.mergeProps(getDescriptionProps(externalProps), state.valid === false && !state.disabled && !disabled ? {
383
- 'aria-invalid': true
384
- } : useRenderElement.EMPTY_OBJECT), [getDescriptionProps, state.disabled, state.valid]);
385
- return React__namespace.useMemo(() => ({
386
- getValidationProps,
387
- inputRef,
388
- registerInput,
389
- commit,
390
- change
391
- }), [getValidationProps, registerInput, commit, change]);
392
- }
393
-
394
- function useFieldControlRegistration(params) {
395
- const {
396
- commit,
397
- invalid,
398
- markedDirtyRef,
399
- name,
400
- setRegisteredFieldName,
401
- setRegisteredFieldId,
402
- setValidityData,
403
- validityData
404
- } = params;
405
- const {
406
- formRef
407
- } = useLabelableId.useFormContext();
408
- const activeFieldControlSourceRef = React__namespace.useRef(null);
409
- const registrationRef = React__namespace.useRef(null);
410
- const fallbackControlRef = React__namespace.useRef(null);
411
- const getValueForForm = useButton.useStableCallback(() => {
412
- const registration = registrationRef.current;
413
- if (!registration) {
414
- return undefined;
415
- }
416
- if (registration.getValue) {
417
- return registration.getValue();
418
- }
419
- return registration.value;
420
- });
421
- function getRegistrationValue(registration) {
422
- return registration.value === undefined ? getValueForForm() : registration.value;
423
- }
424
- const validate = useButton.useStableCallback(() => {
425
- const registration = registrationRef.current;
426
- markedDirtyRef.current = true;
427
- if (!registration) {
428
- commit(validityData.value);
429
- return;
430
- }
431
- commit(getRegistrationValue(registration));
432
- });
433
- function refreshRegistration() {
434
- const registration = registrationRef.current;
435
- if (!registration || !registration.id) {
436
- return;
437
- }
438
- formRef.current.fields.set(registration.id, {
439
- getValue: getValueForForm,
440
- name: name ?? registration.name,
441
- controlRef: registration.controlRef ?? fallbackControlRef,
442
- validityData: getCombinedFieldValidityData(validityData, invalid),
443
- validate
444
- });
445
- }
446
- function deleteRegistration(id = registrationRef.current?.id) {
447
- if (id) {
448
- formRef.current.fields.delete(id);
449
- }
450
- }
451
- function syncInitialValue() {
452
- const registration = registrationRef.current;
453
- if (!registration) {
454
- return;
455
- }
456
- const initialValue = getRegistrationValue(registration);
457
- if (validityData.initialValue === null && initialValue !== null) {
458
- setValidityData(prev => ({
459
- ...prev,
460
- initialValue
461
- }));
462
- }
463
- }
464
- useButton.useIsoLayoutEffect(() => {
465
- const registration = registrationRef.current;
466
- if (!registration || !registration.id) {
467
- return;
468
- }
469
- setRegisteredFieldName(name ? undefined : registration.name);
470
- formRef.current.fields.set(registration.id, {
471
- getValue: getValueForForm,
472
- name: name ?? registration.name,
473
- controlRef: registration.controlRef ?? fallbackControlRef,
474
- validityData: getCombinedFieldValidityData(validityData, invalid),
475
- validate
476
- });
477
- }, [formRef, getValueForForm, invalid, name, setRegisteredFieldName, validate, validityData]);
478
- useButton.useIsoLayoutEffect(() => {
479
- const fields = formRef.current.fields;
480
- return () => {
481
- const id = registrationRef.current?.id;
482
- if (id) {
483
- fields.delete(id);
484
- }
485
- };
486
- }, [formRef]);
487
- const register = useButton.useStableCallback((source, registration) => {
488
- if (!registration) {
489
- if (activeFieldControlSourceRef.current === source) {
490
- activeFieldControlSourceRef.current = null;
491
- deleteRegistration();
492
- registrationRef.current = null;
493
- setRegisteredFieldName(undefined);
494
- setRegisteredFieldId(undefined);
495
- }
496
- return;
497
- }
498
- const previousId = registrationRef.current?.id;
499
- activeFieldControlSourceRef.current = source;
500
- registrationRef.current = registration;
501
- if (!name) {
502
- setRegisteredFieldName(registration.name);
503
- }
504
- setRegisteredFieldId(registration.id);
505
- if (previousId && previousId !== registration.id) {
506
- deleteRegistration(previousId);
507
- }
508
- syncInitialValue();
509
- refreshRegistration();
510
- });
511
- return [validate, register];
512
- }
513
-
514
- const FieldRootInner = /*#__PURE__*/React__namespace.forwardRef(function FieldRootInner(componentProps, forwardedRef) {
515
- const {
516
- errors,
517
- validationMode: formValidationMode,
518
- submitAttemptedRef
519
- } = useLabelableId.useFormContext();
520
- const {
521
- render,
522
- className,
523
- validate: validateProp,
524
- validationDebounceTime = 0,
525
- validationMode = formValidationMode,
526
- name,
527
- disabled: disabledProp = false,
528
- invalid: invalidProp,
529
- dirty: dirtyProp,
530
- touched: touchedProp,
531
- actionsRef,
532
- style,
533
- ...elementProps
534
- } = componentProps;
535
- const disabledFieldset = useFieldsetRootContext(true)?.disabled;
536
- const validate = useButton.useStableCallback(validateProp || (() => null));
537
- const disabled = disabledFieldset || disabledProp;
538
- const [touchedState, setTouchedUnwrapped] = React__namespace.useState(false);
539
- const [dirtyState, setDirtyUnwrapped] = React__namespace.useState(false);
540
- const [filled, setFilled] = React__namespace.useState(false);
541
- const [focused, setFocused] = React__namespace.useState(false);
542
- const dirty = dirtyProp ?? dirtyState;
543
- const touched = touchedProp ?? touchedState;
544
- const markedDirtyRef = React__namespace.useRef(dirty);
545
- const registeredFieldIdRef = React__namespace.useRef(undefined);
546
- const [registeredFieldName, setRegisteredFieldName] = React__namespace.useState();
547
- const effectiveName = name ?? registeredFieldName;
548
- useButton.useIsoLayoutEffect(() => {
549
- if (dirtyProp !== undefined) {
550
- markedDirtyRef.current = dirtyProp;
551
- }
552
- }, [dirtyProp]);
553
- const getRegisteredFieldId = React__namespace.useCallback(() => registeredFieldIdRef.current, []);
554
- const setRegisteredFieldId = React__namespace.useCallback(id => {
555
- registeredFieldIdRef.current = id;
556
- }, []);
557
- const setDirty = useButton.useStableCallback(value => {
558
- if (dirtyProp !== undefined) {
559
- return;
560
- }
561
- if (value) {
562
- markedDirtyRef.current = true;
563
- }
564
- setDirtyUnwrapped(value);
565
- });
566
- const setTouched = useButton.useStableCallback(value => {
567
- if (touchedProp !== undefined) {
568
- return;
569
- }
570
- setTouchedUnwrapped(value);
571
- });
572
- const shouldValidateOnChange = useButton.useStableCallback(() => validationMode === 'onChange' || validationMode === 'onSubmit' && submitAttemptedRef.current);
573
- const formError = effectiveName && Object.hasOwn(errors, effectiveName) ? errors[effectiveName] : null;
574
- const hasFormError = !!(Array.isArray(formError) ? formError.length : formError);
575
- const invalid = invalidProp === true || hasFormError;
576
- const [validityData, setValidityData] = React__namespace.useState({
577
- state: useLabelableId.DEFAULT_VALIDITY_STATE,
578
- error: '',
579
- errors: [],
580
- value: null,
581
- initialValue: null
582
- });
583
- const valid = disabled ? null : !invalid && validityData.state.valid;
584
- const state = React__namespace.useMemo(() => ({
585
- disabled,
586
- touched,
587
- dirty,
588
- valid,
589
- filled,
590
- focused
591
- }), [disabled, touched, dirty, valid, filled, focused]);
592
- const validation = useFieldValidation({
593
- setValidityData,
594
- validate,
595
- validityData,
596
- validationDebounceTime,
597
- invalid,
598
- markedDirtyRef,
599
- state,
600
- shouldValidateOnChange,
601
- getRegisteredFieldId
602
- });
603
- const [validateFieldControl, registerFieldControl] = useFieldControlRegistration({
604
- commit: validation.commit,
605
- invalid,
606
- markedDirtyRef,
607
- name,
608
- setRegisteredFieldName,
609
- setRegisteredFieldId,
610
- setValidityData,
611
- validityData
612
- });
613
- React__namespace.useImperativeHandle(actionsRef, () => ({
614
- validate: validateFieldControl
615
- }), [validateFieldControl]);
616
- const contextValue = React__namespace.useMemo(() => ({
617
- invalid,
618
- name: effectiveName,
619
- validityData,
620
- setValidityData,
621
- disabled,
622
- touched,
623
- setTouched,
624
- dirty,
625
- setDirty,
626
- filled,
627
- setFilled,
628
- focused,
629
- setFocused,
630
- validate,
631
- validationMode,
632
- validationDebounceTime,
633
- shouldValidateOnChange,
634
- state,
635
- markedDirtyRef,
636
- registerFieldControl,
637
- validation
638
- }), [invalid, effectiveName, validityData, disabled, touched, setTouched, dirty, setDirty, filled, setFilled, focused, setFocused, validate, validationMode, validationDebounceTime, shouldValidateOnChange, state, registerFieldControl, validation]);
639
- const element = useRenderElement.useRenderElement('div', componentProps, {
640
- ref: forwardedRef,
641
- state,
642
- props: elementProps,
643
- stateAttributesMapping: useLabelableId.fieldValidityMapping
644
- });
645
- return /*#__PURE__*/jsxRuntime.jsx(useLabelableId.FieldRootContext.Provider, {
646
- value: contextValue,
647
- children: element
648
- });
649
- });
650
-
651
- /**
652
- * Groups all parts of the field.
653
- * Renders a `<div>` element.
654
- *
655
- * Documentation: [Base UI Field](https://base-ui.com/react/components/field)
656
- */
657
- if (process.env.NODE_ENV !== "production") FieldRootInner.displayName = "FieldRootInner";
658
- const FieldRoot = /*#__PURE__*/React__namespace.forwardRef(function FieldRoot(componentProps, forwardedRef) {
659
- return /*#__PURE__*/jsxRuntime.jsx(LabelableProvider, {
660
- children: /*#__PURE__*/jsxRuntime.jsx(FieldRootInner, {
661
- ...componentProps,
662
- ref: forwardedRef
663
- })
664
- });
665
- });
666
- if (process.env.NODE_ENV !== "production") FieldRoot.displayName = "FieldRoot";
667
-
668
- /**
669
- * An accessible label that is automatically associated with the field control.
670
- * Renders a `<label>` element.
671
- *
672
- * Documentation: [Base UI Field](https://base-ui.com/react/components/field)
673
- */
674
- const FieldLabel = /*#__PURE__*/React__namespace.forwardRef(function FieldLabel(componentProps, forwardedRef) {
675
- const {
676
- render,
677
- className,
678
- style,
679
- id: idProp,
680
- nativeLabel = true,
681
- ...elementProps
682
- } = componentProps;
683
- const fieldRootContext = useLabelableId.useFieldRootContext(false);
684
- const fieldItemContext = useFieldItemContext();
685
- const {
686
- labelId
687
- } = useLabelableId.useLabelableContext();
688
- const state = {
689
- ...fieldRootContext.state,
690
- disabled: fieldRootContext.disabled || fieldItemContext.disabled
691
- };
692
- const labelRef = React__namespace.useRef(null);
693
- const labelProps = useLabel.useLabel({
694
- id: labelId ?? idProp,
695
- native: nativeLabel
696
- });
697
- if (process.env.NODE_ENV !== 'production') {
698
- // eslint-disable-next-line react-hooks/rules-of-hooks
699
- React__namespace.useEffect(() => {
700
- if (!labelRef.current) {
701
- return;
702
- }
703
- const isLabelTag = labelRef.current.tagName === 'LABEL';
704
- if (nativeLabel) {
705
- if (!isLabelTag) {
706
- const ownerStackMessage = useButton.SafeReact.captureOwnerStack?.() || '';
707
- const message = '<Field.Label> expected a <label> element because the `nativeLabel` prop is true. ' + 'Rendering a non-<label> disables native label association, so `htmlFor` will not ' + 'work. Use a real <label> in the `render` prop, or set `nativeLabel` to `false`.';
708
- useButton.error(`${message}${ownerStackMessage}`);
709
- }
710
- } else if (isLabelTag) {
711
- const ownerStackMessage = useButton.SafeReact.captureOwnerStack?.() || '';
712
- const message = '<Field.Label> expected a non-<label> element because the `nativeLabel` prop is false. ' + 'Rendering a <label> assumes native label behavior while Base UI treats it as ' + 'non-native, which can cause unexpected pointer behavior. Use a non-<label> in the ' + '`render` prop, or set `nativeLabel` to `true`.';
713
- useButton.error(`${message}${ownerStackMessage}`);
714
- }
715
- }, [nativeLabel]);
716
- }
717
- const element = useRenderElement.useRenderElement('label', componentProps, {
718
- ref: [forwardedRef, labelRef],
719
- state,
720
- props: [labelProps, elementProps],
721
- stateAttributesMapping: useLabelableId.fieldValidityMapping
722
- });
723
- return element;
724
- });
725
- if (process.env.NODE_ENV !== "production") FieldLabel.displayName = "FieldLabel";
726
-
727
- const stateAttributesMapping = {
728
- ...useLabelableId.fieldValidityMapping,
729
- ...useButton.transitionStatusMapping
730
- };
731
-
732
- /**
733
- * An error message displayed if the field control fails validation.
734
- * Renders a `<div>` element.
735
- *
736
- * Documentation: [Base UI Field](https://base-ui.com/react/components/field)
737
- */
738
- const FieldError = /*#__PURE__*/React__namespace.forwardRef(function FieldError(componentProps, forwardedRef) {
739
- const {
740
- render,
741
- id: idProp,
742
- className,
743
- match,
744
- style,
745
- ...elementProps
746
- } = componentProps;
747
- const id = useButton.useBaseUiId(idProp);
748
- const {
749
- validityData,
750
- state: fieldState,
751
- name
752
- } = useLabelableId.useFieldRootContext(false);
753
- const {
754
- setMessageIds
755
- } = useLabelableId.useLabelableContext();
756
- const {
757
- errors
758
- } = useLabelableId.useFormContext();
759
- const formError = name && Object.hasOwn(errors, name) ? errors[name] : null;
760
- const hasFormError = !!(Array.isArray(formError) ? formError.length : formError);
761
- const hasSpecificMatch = typeof match === 'string';
762
- let rendered = false;
763
- if (match === true) {
764
- rendered = true;
765
- } else if (fieldState.disabled) {
766
- rendered = false;
767
- } else if (hasSpecificMatch) {
768
- rendered = Boolean(validityData.state[match]);
769
- } else {
770
- rendered = hasFormError || validityData.state.valid === false;
771
- }
772
- const {
773
- mounted,
774
- transitionStatus,
775
- setMounted
776
- } = useButton.useTransitionStatus(rendered);
777
- useButton.useIsoLayoutEffect(() => {
778
- if (!rendered || !id) {
779
- return undefined;
780
- }
781
- setMessageIds(v => v.concat(id));
782
- return () => {
783
- setMessageIds(v => v.filter(item => item !== id));
784
- };
785
- }, [rendered, id, setMessageIds]);
786
- const errorRef = React__namespace.useRef(null);
787
- const [lastRenderedMessage, setLastRenderedMessage] = React__namespace.useState(null);
788
- const [lastRenderedMessageKey, setLastRenderedMessageKey] = React__namespace.useState(null);
789
- let error = validityData.error;
790
- if (!hasSpecificMatch && hasFormError) {
791
- error = formError;
792
- } else if (validityData.errors.length > 1) {
793
- error = validityData.errors;
794
- }
795
- let errorMessage = error ?? '';
796
- if (Array.isArray(error)) {
797
- errorMessage = error.length > 1 ? /*#__PURE__*/jsxRuntime.jsx("ul", {
798
- children: error.map(message => /*#__PURE__*/jsxRuntime.jsx("li", {
799
- children: message
800
- }, message))
801
- }) : error[0] ?? '';
802
- }
803
- const errorKey = Array.isArray(error) ? JSON.stringify(error) : error;
804
- if (rendered && errorKey !== lastRenderedMessageKey) {
805
- setLastRenderedMessageKey(errorKey);
806
- setLastRenderedMessage(errorMessage);
807
- }
808
- useButton.useOpenChangeComplete({
809
- open: rendered,
810
- ref: errorRef,
811
- onComplete() {
812
- if (!rendered) {
813
- setMounted(false);
814
- }
815
- }
816
- });
817
- const state = {
818
- ...fieldState,
819
- transitionStatus
820
- };
821
- const element = useRenderElement.useRenderElement('div', componentProps, {
822
- ref: [forwardedRef, errorRef],
823
- state,
824
- props: [{
825
- id,
826
- children: rendered ? errorMessage : lastRenderedMessage
827
- }, elementProps],
828
- stateAttributesMapping,
829
- enabled: mounted
830
- });
831
- if (!mounted) {
832
- return null;
833
- }
834
- return element;
835
- });
836
- if (process.env.NODE_ENV !== "production") FieldError.displayName = "FieldError";
837
-
838
- /**
839
- * A paragraph with additional information about the field.
840
- * Renders a `<p>` element.
841
- *
842
- * Documentation: [Base UI Field](https://base-ui.com/react/components/field)
843
- */
844
- const FieldDescription = /*#__PURE__*/React__namespace.forwardRef(function FieldDescription(componentProps, forwardedRef) {
845
- const {
846
- render,
847
- id: idProp,
848
- className,
849
- style,
850
- ...elementProps
851
- } = componentProps;
852
- const id = useButton.useBaseUiId(idProp);
853
- const fieldRootContext = useLabelableId.useFieldRootContext(false);
854
- const fieldItemContext = useFieldItemContext();
855
- const {
856
- setMessageIds
857
- } = useLabelableId.useLabelableContext();
858
- const state = {
859
- ...fieldRootContext.state,
860
- disabled: fieldRootContext.disabled || fieldItemContext.disabled
861
- };
862
- useButton.useIsoLayoutEffect(() => {
863
- if (!id) {
864
- return undefined;
865
- }
866
- setMessageIds(v => v.concat(id));
867
- return () => {
868
- setMessageIds(v => v.filter(item => item !== id));
869
- };
870
- }, [id, setMessageIds]);
871
- const element = useRenderElement.useRenderElement('p', componentProps, {
872
- ref: forwardedRef,
873
- state,
874
- props: [{
875
- id
876
- }, elementProps],
877
- stateAttributesMapping: useLabelableId.fieldValidityMapping
878
- });
879
- return element;
880
- });
881
- if (process.env.NODE_ENV !== "production") FieldDescription.displayName = "FieldDescription";
882
12
 
883
13
  var styles = {"container":"_6HZLFIOZh4s-","inline":"_-6ndFYNKKaM-","wrapper":"c20czk-FSyY-","disabled":"_-2INirAxaU4-","small":"NsFBA5oqRAA-","large":"ExKqck-6xVs-","center":"UWiqNi57G8g-","right":"po25PZwJpe4-","inputWrapper":"k9dAO6d010o-","input":"D-PmE-l-hZU-","stepper":"t42w4ZDiDyI-","loadingIndicator":"NLptJ1t9Pj4-","label":"Ggk3aaMcIJU-","hideLabel":"C7d6qmoZiKU-","affixLabel":"_4u1JHjUYvkY-","prefix":"rEWH41rUUEE-","suffix":"_4-iNl6jdfmM-","affixIcon":"_5-Iw-2c-wXk-","compoundAffix":"tZjZRRcAShY-","affixLabelText":"mbEcqyBQoEg-","stepperButton":"zzrCzYF-8u0-","belowField":"_0mcAZAtwQ2o-","description":"xxp2uGc-B6o-","fieldError":"q-WsOi6joGo-","spinning":"d0TEiLWObKU-"};
884
14
 
@@ -975,7 +105,7 @@ function InputNumberExperimentalWrapper(_a) {
975
105
  value,
976
106
  ]);
977
107
  const rootProps = useRenderElement.mergeProps({ className: classnames(styles.container, inline && styles.inline) }, { className, style });
978
- return (React.createElement(FieldRoot, Object.assign({}, rootProps, { disabled: disabled, invalid: invalid || undefined, name: name }),
108
+ return (React.createElement(FieldDescription.FieldRoot, Object.assign({}, rootProps, { disabled: disabled, invalid: invalid || undefined, name: name }),
979
109
  React.createElement(InputNumberExperimentalContext.Provider, { value: contextValue }, children)));
980
110
  }
981
111
  function InputNumberExperimentalGroup({ children, className, style, }) {
@@ -1005,19 +135,19 @@ function InputNumberExperimentalLabel({ children, className, style, }) {
1005
135
  const ctx = useInputNumberExperimentalContext("Label");
1006
136
  if (!children)
1007
137
  return null;
1008
- return (React.createElement(FieldLabel, { className: classnames(styles.label, className), htmlFor: ctx.id, style: style }, children));
138
+ return (React.createElement(FieldDescription.FieldLabel, { className: classnames(styles.label, className), htmlFor: ctx.id, style: style }, children));
1009
139
  }
1010
140
  function InputNumberExperimentalDescription({ children, className, style, }) {
1011
141
  useInputNumberExperimentalContext("Description");
1012
142
  if (!children)
1013
143
  return null;
1014
- return (React.createElement(FieldDescription, { className: classnames(styles.description, className), style: style }, children));
144
+ return (React.createElement(FieldDescription.FieldDescription, { className: classnames(styles.description, className), style: style }, children));
1015
145
  }
1016
146
  function InputNumberExperimentalError({ children, className, style, }) {
1017
147
  useInputNumberExperimentalContext("Error");
1018
148
  if (!children)
1019
149
  return null;
1020
- return (React.createElement(FieldError, { className: classnames(styles.fieldError, className), match: true, role: "alert", style: style }, children));
150
+ return (React.createElement(FieldDescription.FieldError, { className: classnames(styles.fieldError, className), match: true, role: "alert", style: style }, children));
1021
151
  }
1022
152
  function InputNumberExperimentalLoading({ children, className, style, }) {
1023
153
  useInputNumberExperimentalContext("Loading");