@tamagui/field 0.0.0-bootstrap.0 → 3.0.0-beta.1091.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 (79) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/Field.cjs +856 -0
  3. package/dist/cjs/Field.native.cjs +1010 -0
  4. package/dist/cjs/Field.native.js +1012 -0
  5. package/dist/cjs/Field.native.js.map +1 -0
  6. package/dist/cjs/FieldContext.cjs +85 -0
  7. package/dist/cjs/FieldContext.native.cjs +89 -0
  8. package/dist/cjs/FieldContext.native.js +91 -0
  9. package/dist/cjs/FieldContext.native.js.map +1 -0
  10. package/dist/cjs/index.cjs +20 -0
  11. package/dist/cjs/index.native.cjs +22 -0
  12. package/dist/cjs/index.native.js +24 -0
  13. package/dist/cjs/index.native.js.map +1 -0
  14. package/dist/cjs/types.cjs +16 -0
  15. package/dist/cjs/types.native.cjs +18 -0
  16. package/dist/cjs/types.native.js +20 -0
  17. package/dist/cjs/types.native.js.map +1 -0
  18. package/dist/cjs/validation.cjs +113 -0
  19. package/dist/cjs/validation.native.cjs +121 -0
  20. package/dist/cjs/validation.native.js +123 -0
  21. package/dist/cjs/validation.native.js.map +1 -0
  22. package/dist/esm/Field.mjs +824 -0
  23. package/dist/esm/Field.mjs.map +1 -0
  24. package/dist/esm/Field.native.js +976 -0
  25. package/dist/esm/Field.native.js.map +1 -0
  26. package/dist/esm/FieldContext.mjs +51 -0
  27. package/dist/esm/FieldContext.mjs.map +1 -0
  28. package/dist/esm/FieldContext.native.js +53 -0
  29. package/dist/esm/FieldContext.native.js.map +1 -0
  30. package/dist/esm/index.js +5 -0
  31. package/dist/esm/index.mjs +5 -0
  32. package/dist/esm/index.native.js +5 -0
  33. package/dist/esm/types.mjs +0 -0
  34. package/dist/esm/types.native.js +0 -0
  35. package/dist/esm/validation.mjs +86 -0
  36. package/dist/esm/validation.mjs.map +1 -0
  37. package/dist/esm/validation.native.js +92 -0
  38. package/dist/esm/validation.native.js.map +1 -0
  39. package/dist/jsx/Field.mjs +824 -0
  40. package/dist/jsx/Field.mjs.map +1 -0
  41. package/dist/jsx/Field.native.cjs +1010 -0
  42. package/dist/jsx/Field.native.js +1012 -0
  43. package/dist/jsx/Field.native.js.map +1 -0
  44. package/dist/jsx/FieldContext.mjs +51 -0
  45. package/dist/jsx/FieldContext.mjs.map +1 -0
  46. package/dist/jsx/FieldContext.native.cjs +89 -0
  47. package/dist/jsx/FieldContext.native.js +91 -0
  48. package/dist/jsx/FieldContext.native.js.map +1 -0
  49. package/dist/jsx/index.js +5 -0
  50. package/dist/jsx/index.mjs +5 -0
  51. package/dist/jsx/index.native.cjs +22 -0
  52. package/dist/jsx/index.native.js +24 -0
  53. package/dist/jsx/index.native.js.map +1 -0
  54. package/dist/jsx/types.mjs +0 -0
  55. package/dist/jsx/types.native.cjs +18 -0
  56. package/dist/jsx/types.native.js +20 -0
  57. package/dist/jsx/types.native.js.map +1 -0
  58. package/dist/jsx/validation.mjs +86 -0
  59. package/dist/jsx/validation.mjs.map +1 -0
  60. package/dist/jsx/validation.native.cjs +121 -0
  61. package/dist/jsx/validation.native.js +123 -0
  62. package/dist/jsx/validation.native.js.map +1 -0
  63. package/package.json +51 -4
  64. package/src/Field.tsx +1127 -0
  65. package/src/FieldContext.tsx +61 -0
  66. package/src/index.ts +3 -0
  67. package/src/types.ts +125 -0
  68. package/src/validation.ts +136 -0
  69. package/types/Field.d.ts +401 -0
  70. package/types/Field.d.ts.map +1 -0
  71. package/types/FieldContext.d.ts +11 -0
  72. package/types/FieldContext.d.ts.map +1 -0
  73. package/types/index.d.ts +4 -0
  74. package/types/index.d.ts.map +1 -0
  75. package/types/types.d.ts +112 -0
  76. package/types/types.d.ts.map +1 -0
  77. package/types/validation.d.ts +24 -0
  78. package/types/validation.d.ts.map +1 -0
  79. package/README.md +0 -1
@@ -0,0 +1,856 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
16
+ get: () => from[key],
17
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
+ });
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
+ value: mod,
24
+ enumerable: true
25
+ }) : target, mod));
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var Field_exports = {};
28
+ __export(Field_exports, {
29
+ Field: () => Field2,
30
+ FieldDescriptionFrame: () => FieldDescriptionFrame,
31
+ FieldErrorFrame: () => FieldErrorFrame,
32
+ FieldFrame: () => FieldFrame,
33
+ FieldItemFrame: () => FieldItemFrame,
34
+ FieldLabelFrame: () => FieldLabelFrame
35
+ });
36
+ module.exports = __toCommonJS(Field_exports);
37
+ var import_core = require("@tamagui/core");
38
+ var import_form = require("@tamagui/form");
39
+ var import_focusable = require("@tamagui/focusable");
40
+ var React = __toESM(require("react"), 1);
41
+ var import_FieldContext = require("./FieldContext.cjs");
42
+ var import_validation = require("./validation.cjs");
43
+ var import_jsx_runtime = require("react/jsx-runtime");
44
+ const fieldStateVariants = {
45
+ valid: { true: {} },
46
+ invalid: { true: {} },
47
+ touched: { true: {} },
48
+ dirty: { true: {} },
49
+ filled: { true: {} },
50
+ focused: { true: {} },
51
+ disabled: { true: {} }
52
+ };
53
+ const FieldFrame = (0, import_core.styled)(import_core.View, {
54
+ displayName: "Field",
55
+ context: import_FieldContext.FieldStyledContext,
56
+ variants: fieldStateVariants
57
+ });
58
+ const FieldLabelFrame = (0, import_core.styled)(import_core.Text, {
59
+ displayName: "FieldLabel",
60
+ render: "label",
61
+ context: import_FieldContext.FieldStyledContext,
62
+ variants: fieldStateVariants
63
+ });
64
+ const FieldDescriptionFrame = (0, import_core.styled)(import_core.Text, {
65
+ displayName: "FieldDescription",
66
+ render: "p",
67
+ context: import_FieldContext.FieldStyledContext,
68
+ variants: fieldStateVariants
69
+ });
70
+ const FieldErrorFrame = (0, import_core.styled)(import_core.Text, {
71
+ displayName: "FieldError",
72
+ render: "span",
73
+ context: import_FieldContext.FieldStyledContext,
74
+ variants: fieldStateVariants
75
+ });
76
+ const FieldItemFrame = (0, import_core.styled)(import_core.View, {
77
+ displayName: "FieldItem",
78
+ context: import_FieldContext.FieldStyledContext,
79
+ variants: fieldStateVariants
80
+ });
81
+ const validityKeys = [
82
+ "badInput",
83
+ "customError",
84
+ "patternMismatch",
85
+ "rangeOverflow",
86
+ "rangeUnderflow",
87
+ "stepMismatch",
88
+ "tooLong",
89
+ "tooShort",
90
+ "typeMismatch",
91
+ "valueMissing"
92
+ ];
93
+ const AssociationContext = React.createContext(null);
94
+ const FieldRootContext = React.createContext(null);
95
+ const FieldItemContext = React.createContext(false);
96
+ function getText(children) {
97
+ const text = [];
98
+ React.Children.forEach(children, (child) => {
99
+ if (typeof child === "string" || typeof child === "number") {
100
+ text.push(String(child));
101
+ return;
102
+ }
103
+ if (React.isValidElement(child)) {
104
+ const nested = getText(child.props.children);
105
+ if (nested) {
106
+ text.push(nested);
107
+ }
108
+ }
109
+ });
110
+ return text.join(" ").trim() || void 0;
111
+ }
112
+ function useAssociation(prefix, parent) {
113
+ const defaultControlId = `${prefix}-control`;
114
+ const controlIdsRef = React.useRef(/* @__PURE__ */ new Map());
115
+ const labelsRef = React.useRef(/* @__PURE__ */ new Map());
116
+ const messagesRef = React.useRef(/* @__PURE__ */ new Map());
117
+ const [, update] = React.useReducer((value) => value + 1, 0);
118
+ const registerControlId = React.useCallback((id) => {
119
+ const source = /* @__PURE__ */ Symbol();
120
+ controlIdsRef.current.set(source, id);
121
+ update();
122
+ return () => {
123
+ controlIdsRef.current.delete(source);
124
+ update();
125
+ };
126
+ }, []);
127
+ const registerLabel = React.useCallback((id, text) => {
128
+ const source = /* @__PURE__ */ Symbol();
129
+ labelsRef.current.set(source, {
130
+ id,
131
+ text
132
+ });
133
+ update();
134
+ return () => {
135
+ labelsRef.current.delete(source);
136
+ update();
137
+ };
138
+ }, []);
139
+ const registerMessage = React.useCallback((id, text) => {
140
+ const source = /* @__PURE__ */ Symbol();
141
+ messagesRef.current.set(source, {
142
+ id,
143
+ text
144
+ });
145
+ update();
146
+ return () => {
147
+ messagesRef.current.delete(source);
148
+ update();
149
+ };
150
+ }, []);
151
+ const controlId = Array.from(controlIdsRef.current.values()).at(-1) ?? defaultControlId;
152
+ const label = Array.from(labelsRef.current.values()).at(-1);
153
+ const messages = Array.from(messagesRef.current.values());
154
+ return React.useMemo(() => ({
155
+ controlId,
156
+ labelId: [parent?.labelId, label?.id].filter(Boolean).join(" ") || void 0,
157
+ labelText: [parent?.labelText, label?.text].filter(Boolean).join(" ") || void 0,
158
+ messageIds: Array.from(/* @__PURE__ */ new Set([...parent?.messageIds ?? [], ...messages.map((message) => message.id)])),
159
+ messageTexts: [...parent?.messageTexts ?? [], ...messages.flatMap((message) => message.text ? [message.text] : [])],
160
+ registerControlId,
161
+ registerLabel,
162
+ registerMessage
163
+ }), [
164
+ controlId,
165
+ label?.id,
166
+ label?.text,
167
+ messages,
168
+ parent?.labelId,
169
+ parent?.labelText,
170
+ parent?.messageIds,
171
+ parent?.messageTexts,
172
+ registerControlId,
173
+ registerLabel,
174
+ registerMessage
175
+ ]);
176
+ }
177
+ function getStyleState(state, disabled = state.disabled) {
178
+ return {
179
+ valid: state.valid === true,
180
+ invalid: state.valid === false,
181
+ touched: state.touched,
182
+ dirty: state.dirty,
183
+ filled: state.filled,
184
+ focused: state.focused,
185
+ disabled
186
+ };
187
+ }
188
+ function getDataProps(state, disabled = state.disabled) {
189
+ if (!import_core.isWeb) {
190
+ return {};
191
+ }
192
+ return {
193
+ "data-valid": state.valid === true ? "" : void 0,
194
+ "data-invalid": state.valid === false ? "" : void 0,
195
+ "data-touched": state.touched ? "" : void 0,
196
+ "data-dirty": state.dirty ? "" : void 0,
197
+ "data-filled": state.filled ? "" : void 0,
198
+ "data-focused": state.focused ? "" : void 0,
199
+ "data-disabled": disabled ? "" : void 0
200
+ };
201
+ }
202
+ function useControlContext(root, association, itemDisabled = false, isItem = false) {
203
+ const disabled = root.state.disabled || itemDisabled;
204
+ const controlIdRef = React.useRef(association.controlId);
205
+ const registrationDisabledRef = React.useRef(root.rootDisabled || itemDisabled);
206
+ controlIdRef.current = association.controlId;
207
+ registrationDisabledRef.current = root.rootDisabled || itemDisabled;
208
+ const registerControl = React.useCallback((registration) => {
209
+ const id = registration.id ?? controlIdRef.current;
210
+ const unregisterId = association.registerControlId(id);
211
+ const nextRegistration = {
212
+ ...registration,
213
+ id,
214
+ get disabled() {
215
+ return registrationDisabledRef.current || registration.disabled;
216
+ }
217
+ };
218
+ const unregisterControl = root.registerControl(nextRegistration, !isItem);
219
+ return () => {
220
+ unregisterControl();
221
+ unregisterId();
222
+ };
223
+ }, [
224
+ association.registerControlId,
225
+ isItem,
226
+ root.registerControl
227
+ ]);
228
+ return React.useMemo(() => ({
229
+ name: root.name,
230
+ disabled,
231
+ ariaProps: {
232
+ id: association.controlId,
233
+ ...import_core.isWeb ? {
234
+ "aria-labelledby": association.labelId,
235
+ "aria-describedby": association.messageIds.join(" ") || void 0,
236
+ "aria-invalid": root.state.valid === false ? true : void 0
237
+ } : {
238
+ accessibilityLabel: association.labelText,
239
+ accessibilityHint: association.messageTexts.join(" ") || void 0,
240
+ accessibilityState: disabled ? { disabled: true } : void 0
241
+ }
242
+ },
243
+ dataProps: getDataProps(root.state, disabled),
244
+ onFocus: root.onFocus,
245
+ onBlur: root.onBlur,
246
+ onChange: root.onChange,
247
+ onDisabledChange: isItem ? () => {} : root.onDisabledChange,
248
+ registerControl
249
+ }), [
250
+ association.controlId,
251
+ association.labelId,
252
+ association.labelText,
253
+ association.messageIds,
254
+ association.messageTexts,
255
+ disabled,
256
+ isItem,
257
+ registerControl,
258
+ root.name,
259
+ root.onBlur,
260
+ root.onChange,
261
+ root.onDisabledChange,
262
+ root.onFocus,
263
+ root.state
264
+ ]);
265
+ }
266
+ function getRegistrationValue(registration) {
267
+ return registration?.getValue ? registration.getValue() : registration?.value;
268
+ }
269
+ function getInput(registration) {
270
+ return registration.inputRef?.current;
271
+ }
272
+ function canValidateInput(input) {
273
+ return Boolean(input && input.validity && typeof input.setCustomValidity === "function" && !input.disabled);
274
+ }
275
+ function isEligibleInput(input, formElement) {
276
+ if (input.matches?.(":disabled")) {
277
+ return false;
278
+ }
279
+ if (!formElement || input.form === formElement) {
280
+ return true;
281
+ }
282
+ return input.form === null && !input.hasAttribute?.("form");
283
+ }
284
+ function isEligibleRegistration(registration, formElement) {
285
+ if (registration.disabled) {
286
+ return false;
287
+ }
288
+ const input = getInput(registration);
289
+ return !canValidateInput(input) || isEligibleInput(input, formElement);
290
+ }
291
+ function getNativeValidity(input, showValueMissing) {
292
+ const state = (0, import_validation.createDefaultValidityState)(true);
293
+ for (const key of validityKeys) {
294
+ state[key] = Boolean(input.validity[key]);
295
+ }
296
+ state.valid = Boolean(input.validity.valid);
297
+ return (0, import_validation.normalizeNativeValidity)(state, showValueMissing);
298
+ }
299
+ function hasValidityError(state) {
300
+ return state.valid === false;
301
+ }
302
+ function hasError(errors) {
303
+ return Array.isArray(errors) ? errors.length > 0 : Boolean(errors);
304
+ }
305
+ const FieldComponent = (0, import_core.createStyledHOC)(FieldFrame, function Field({ name: nameProp, disabled: disabledProp = false, invalid = false, validate, validationMode: validationModeProp, validationDebounceTime = 0, children, ...fieldProps }, forwardedRef) {
306
+ const form = (0, import_form.useFormRegistryContext)();
307
+ const { clearErrors: clearFormErrors, errors: formErrors, formElementRef, getValues: getFormValues, registerField: registerFormField, submitAttemptedRef, validationMode: formValidationMode } = form;
308
+ const reactId = React.useId().replace(/:/g, "");
309
+ const association = useAssociation(`field-${reactId}`);
310
+ const fieldId = `field-${reactId}`;
311
+ const controlsRef = React.useRef(/* @__PURE__ */ new Map());
312
+ const reportsDisabledRef = React.useRef(/* @__PURE__ */ new WeakMap());
313
+ const activeControlRef = React.useRef(void 0);
314
+ const activeValidationControlRef = React.useRef(void 0);
315
+ const formControlRef = React.useRef(null);
316
+ const formValidityDataRef = React.useRef({ state: { valid: null } });
317
+ const initialValueRef = React.useRef(void 0);
318
+ const hasInitialValueRef = React.useRef(false);
319
+ const valueRef = React.useRef(void 0);
320
+ const dirtyRef = React.useRef(false);
321
+ const debounceRef = React.useRef(void 0);
322
+ const [registeredName, setRegisteredName] = React.useState();
323
+ const [controlDisabled, setControlDisabled] = React.useState(false);
324
+ const [touched, setTouched] = React.useState(false);
325
+ const [dirty, setDirty] = React.useState(false);
326
+ const [filled, setFilled] = React.useState(false);
327
+ const [focused, setFocused] = React.useState(false);
328
+ const [currentValue, setCurrentValue] = React.useState(void 0);
329
+ const [validityData, setValidityData] = React.useState({
330
+ state: (0, import_validation.createDefaultValidityState)(),
331
+ error: "",
332
+ errors: [],
333
+ value: void 0,
334
+ initialValue: void 0
335
+ });
336
+ const validityDataRef = React.useRef(validityData);
337
+ validityDataRef.current = validityData;
338
+ const effectiveName = nameProp ?? registeredName;
339
+ const effectiveNameRef = React.useRef(effectiveName);
340
+ effectiveNameRef.current = effectiveName;
341
+ const disabled = disabledProp || controlDisabled;
342
+ const disabledRef = React.useRef(disabled);
343
+ disabledRef.current = disabled;
344
+ const validationMode = validationModeProp ?? formValidationMode;
345
+ const externalError = effectiveName && effectiveName in formErrors ? formErrors[effectiveName] : void 0;
346
+ const externalErrors = Array.isArray(externalError) ? externalError : externalError ? [externalError] : [];
347
+ const externallyInvalid = invalid || hasError(externalError);
348
+ const externallyInvalidRef = React.useRef(externallyInvalid);
349
+ externallyInvalidRef.current = externallyInvalid;
350
+ const valid = externallyInvalid ? false : disabled ? null : validityData.state.valid;
351
+ formValidityDataRef.current.state.valid = disabled ? null : externallyInvalid ? false : validityData.state.valid;
352
+ const errors = externalErrors.length ? externalErrors : validityData.errors;
353
+ const error = errors[0] ?? "";
354
+ const state = React.useMemo(() => ({
355
+ name: effectiveName,
356
+ value: currentValue,
357
+ error,
358
+ errors,
359
+ validity: validityData.state,
360
+ valid,
361
+ touched,
362
+ dirty,
363
+ filled,
364
+ focused,
365
+ disabled
366
+ }), [
367
+ dirty,
368
+ disabled,
369
+ currentValue,
370
+ effectiveName,
371
+ error,
372
+ errors,
373
+ filled,
374
+ focused,
375
+ touched,
376
+ valid,
377
+ validityData.state
378
+ ]);
379
+ const stateRef = React.useRef(state);
380
+ stateRef.current = state;
381
+ const publishValidityRef = React.useRef(() => {});
382
+ const validationCommitterRef = React.useRef(void 0);
383
+ if (!validationCommitterRef.current) {
384
+ validationCommitterRef.current = (0, import_validation.createValidationCommitter)((data) => {
385
+ publishValidityRef.current(data);
386
+ });
387
+ }
388
+ const getActiveControl = React.useCallback(() => {
389
+ let active;
390
+ for (const registration of controlsRef.current.values()) {
391
+ if (!isEligibleRegistration(registration, formElementRef.current)) {
392
+ continue;
393
+ }
394
+ active = registration;
395
+ }
396
+ return active;
397
+ }, [formElementRef]);
398
+ const syncControlDisabled = React.useCallback(() => {
399
+ let nextDisabled = false;
400
+ for (const registration of controlsRef.current.values()) {
401
+ if (reportsDisabledRef.current.get(registration)) {
402
+ nextDisabled = Boolean(registration.disabled);
403
+ }
404
+ }
405
+ setControlDisabled(nextDisabled);
406
+ }, []);
407
+ const getRepresentativeControl = React.useCallback(() => {
408
+ let fallback;
409
+ for (const registration of controlsRef.current.values()) {
410
+ const input = getInput(registration);
411
+ if (!isEligibleRegistration(registration, formElementRef.current)) {
412
+ continue;
413
+ }
414
+ fallback ??= registration;
415
+ if (canValidateInput(input) && !input.validity.valid) {
416
+ return registration;
417
+ }
418
+ }
419
+ return fallback ?? getActiveControl();
420
+ }, [formElementRef, getActiveControl]);
421
+ const clearCustomValidity = React.useCallback(() => {
422
+ for (const registration of controlsRef.current.values()) {
423
+ const input = getInput(registration);
424
+ if (canValidateInput(input)) {
425
+ input.setCustomValidity("");
426
+ }
427
+ }
428
+ }, []);
429
+ const setCustomValidity = React.useCallback((message) => {
430
+ for (const registration of controlsRef.current.values()) {
431
+ if (!isEligibleRegistration(registration, formElementRef.current)) {
432
+ continue;
433
+ }
434
+ const input = getInput(registration);
435
+ if (canValidateInput(input)) {
436
+ input.setCustomValidity(message);
437
+ }
438
+ }
439
+ }, [formElementRef]);
440
+ const publishValidity = React.useCallback((data) => {
441
+ if (data.state.customError) {
442
+ setCustomValidity(data.errors.join("\n"));
443
+ } else {
444
+ clearCustomValidity();
445
+ }
446
+ formValidityDataRef.current.state.valid = disabledRef.current ? null : externallyInvalidRef.current ? false : data.state.valid;
447
+ validityDataRef.current = data;
448
+ setCurrentValue(data.value);
449
+ setValidityData(data);
450
+ }, [clearCustomValidity, setCustomValidity]);
451
+ publishValidityRef.current = publishValidity;
452
+ const validateValue = React.useCallback((value, submit = false, fromChange = false) => {
453
+ if (debounceRef.current) {
454
+ clearTimeout(debounceRef.current);
455
+ debounceRef.current = void 0;
456
+ }
457
+ const showValueMissing = dirtyRef.current || submit || submitAttemptedRef.current;
458
+ if (fromChange) {
459
+ clearCustomValidity();
460
+ }
461
+ const representative = getRepresentativeControl();
462
+ activeValidationControlRef.current = representative;
463
+ formControlRef.current = representative?.controlRef.current ?? null;
464
+ const input = representative && getInput(representative);
465
+ let nativeState = (0, import_validation.createDefaultValidityState)(true);
466
+ let nativeMessage = "";
467
+ if (canValidateInput(input)) {
468
+ nativeState = getNativeValidity(input, showValueMissing);
469
+ nativeMessage = nativeState.valid === false ? input.validationMessage : "";
470
+ } else {
471
+ const required = Array.from(controlsRef.current.values()).some((registration) => registration.required && isEligibleRegistration(registration, formElementRef.current));
472
+ if (required && !(0, import_validation.isFilled)(value) && showValueMissing) {
473
+ nativeState = {
474
+ ...(0, import_validation.createDefaultValidityState)(false),
475
+ valueMissing: true
476
+ };
477
+ nativeMessage = "Please fill out this field.";
478
+ }
479
+ }
480
+ const initialValue = initialValueRef.current;
481
+ const makeValidityData = (customErrors) => {
482
+ if (customErrors.length) {
483
+ return {
484
+ state: {
485
+ ...nativeState,
486
+ valid: false,
487
+ customError: true
488
+ },
489
+ error: customErrors[0] ?? "",
490
+ errors: customErrors,
491
+ value,
492
+ initialValue
493
+ };
494
+ }
495
+ if (hasValidityError(nativeState)) {
496
+ return {
497
+ state: nativeState,
498
+ error: nativeMessage,
499
+ errors: nativeMessage ? [nativeMessage] : [],
500
+ value,
501
+ initialValue
502
+ };
503
+ }
504
+ return {
505
+ state: (0, import_validation.createDefaultValidityState)(true),
506
+ error: "",
507
+ errors: [],
508
+ value,
509
+ initialValue
510
+ };
511
+ };
512
+ if (nativeMessage && !fromChange) {
513
+ validationCommitterRef.current.run(makeValidityData([]));
514
+ return;
515
+ }
516
+ const result = validate ? (0, import_validation.getValidationResult)(validate, value, getFormValues()) : [];
517
+ if (result instanceof Promise) {
518
+ void validationCommitterRef.current.run(result.then((customErrors) => makeValidityData(customErrors)));
519
+ } else {
520
+ validationCommitterRef.current.run(makeValidityData(result));
521
+ }
522
+ }, [
523
+ clearCustomValidity,
524
+ formElementRef,
525
+ getFormValues,
526
+ getRepresentativeControl,
527
+ submitAttemptedRef,
528
+ validate
529
+ ]);
530
+ const registerControl = React.useCallback((registration, reportDisabled = true) => {
531
+ const source = /* @__PURE__ */ Symbol();
532
+ controlsRef.current.set(source, registration);
533
+ reportsDisabledRef.current.set(registration, reportDisabled);
534
+ activeControlRef.current = getActiveControl();
535
+ formControlRef.current = activeControlRef.current?.controlRef.current ?? null;
536
+ const value = getRegistrationValue(registration);
537
+ valueRef.current = value;
538
+ setCurrentValue(value);
539
+ if (!hasInitialValueRef.current) {
540
+ hasInitialValueRef.current = true;
541
+ initialValueRef.current = value;
542
+ validityDataRef.current = {
543
+ ...validityDataRef.current,
544
+ initialValue: value
545
+ };
546
+ setValidityData(validityDataRef.current);
547
+ }
548
+ if (!nameProp && registration.name) {
549
+ setRegisteredName(registration.name);
550
+ }
551
+ setFilled((0, import_validation.isFilled)(value));
552
+ syncControlDisabled();
553
+ return () => {
554
+ controlsRef.current.delete(source);
555
+ activeControlRef.current = getActiveControl();
556
+ activeValidationControlRef.current = void 0;
557
+ formControlRef.current = activeControlRef.current?.controlRef.current ?? null;
558
+ const next = activeControlRef.current;
559
+ const nextValue = getRegistrationValue(next);
560
+ valueRef.current = nextValue;
561
+ setCurrentValue(nextValue);
562
+ setFilled((0, import_validation.isFilled)(nextValue));
563
+ if (!nameProp) {
564
+ setRegisteredName(next?.name);
565
+ }
566
+ syncControlDisabled();
567
+ };
568
+ }, [
569
+ getActiveControl,
570
+ nameProp,
571
+ syncControlDisabled
572
+ ]);
573
+ const onFocus = React.useCallback(() => {
574
+ setFocused(true);
575
+ }, []);
576
+ const onBlur = React.useCallback((value = valueRef.current) => {
577
+ valueRef.current = value;
578
+ setCurrentValue(value);
579
+ setTouched(true);
580
+ setFocused(false);
581
+ if (validationMode === "onBlur") {
582
+ validateValue(value);
583
+ }
584
+ }, [validateValue, validationMode]);
585
+ const onChange = React.useCallback((value) => {
586
+ valueRef.current = value;
587
+ setCurrentValue(value);
588
+ validationCommitterRef.current.invalidate();
589
+ if (debounceRef.current) {
590
+ clearTimeout(debounceRef.current);
591
+ debounceRef.current = void 0;
592
+ }
593
+ const nextDirty = !Object.is(value, initialValueRef.current);
594
+ dirtyRef.current = nextDirty;
595
+ setDirty(nextDirty);
596
+ setFilled((0, import_validation.isFilled)(value));
597
+ clearFormErrors(effectiveNameRef.current);
598
+ const validateOnChange = (0, import_validation.shouldValidateOnChange)(validationMode, submitAttemptedRef.current);
599
+ if (validateOnChange) {
600
+ if (validationMode === "onChange" && validationDebounceTime > 0 && value !== "") {
601
+ debounceRef.current = setTimeout(() => {
602
+ validateValue(value, false, true);
603
+ }, validationDebounceTime);
604
+ } else {
605
+ validateValue(value, false, true);
606
+ }
607
+ return;
608
+ }
609
+ if (stateRef.current.valid === false) {
610
+ const required = Array.from(controlsRef.current.values()).some((registration) => registration.required && isEligibleRegistration(registration, formElementRef.current));
611
+ if (required && !(0, import_validation.isFilled)(value) && dirtyRef.current) {
612
+ validateValue(value);
613
+ return;
614
+ }
615
+ clearCustomValidity();
616
+ publishValidity({
617
+ state: (0, import_validation.createDefaultValidityState)(true),
618
+ error: "",
619
+ errors: [],
620
+ value,
621
+ initialValue: initialValueRef.current
622
+ });
623
+ }
624
+ }, [
625
+ clearFormErrors,
626
+ clearCustomValidity,
627
+ formElementRef,
628
+ publishValidity,
629
+ submitAttemptedRef,
630
+ validateValue,
631
+ validationDebounceTime,
632
+ validationMode
633
+ ]);
634
+ const onDisabledChange = React.useCallback((nextDisabled) => {
635
+ setControlDisabled(nextDisabled);
636
+ }, []);
637
+ React.useEffect(() => {
638
+ return () => {
639
+ validationCommitterRef.current?.invalidate();
640
+ if (debounceRef.current) {
641
+ clearTimeout(debounceRef.current);
642
+ }
643
+ };
644
+ }, []);
645
+ const formRegistration = React.useMemo(() => ({
646
+ controlRef: formControlRef,
647
+ validityData: formValidityDataRef.current,
648
+ get name() {
649
+ return stateRef.current.disabled ? void 0 : effectiveNameRef.current;
650
+ },
651
+ get controlId() {
652
+ return activeValidationControlRef.current?.id ?? getRepresentativeControl()?.id ?? association.controlId;
653
+ },
654
+ getValue() {
655
+ return getRegistrationValue(getActiveControl()) ?? valueRef.current;
656
+ },
657
+ validate() {
658
+ validateValue(getRegistrationValue(getActiveControl()) ?? valueRef.current, true);
659
+ }
660
+ }), [
661
+ association.controlId,
662
+ getActiveControl,
663
+ getRepresentativeControl,
664
+ validateValue
665
+ ]);
666
+ React.useEffect(() => {
667
+ return registerFormField(fieldId, formRegistration);
668
+ }, [
669
+ fieldId,
670
+ formRegistration,
671
+ registerFormField
672
+ ]);
673
+ const rootContext = React.useMemo(() => ({
674
+ state,
675
+ validityData,
676
+ name: effectiveName,
677
+ rootDisabled: disabledProp,
678
+ registerControl,
679
+ onFocus,
680
+ onBlur,
681
+ onChange,
682
+ onDisabledChange
683
+ }), [
684
+ disabledProp,
685
+ effectiveName,
686
+ onBlur,
687
+ onChange,
688
+ onDisabledChange,
689
+ onFocus,
690
+ registerControl,
691
+ state,
692
+ validityData
693
+ ]);
694
+ const controlContext = useControlContext(rootContext, association);
695
+ const styleState = getStyleState(state);
696
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_FieldContext.FieldStateContext.Provider, {
697
+ value: state,
698
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldRootContext.Provider, {
699
+ value: rootContext,
700
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AssociationContext.Provider, {
701
+ value: association,
702
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_FieldContext.FieldControlContext.Provider, {
703
+ value: controlContext,
704
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_FieldContext.FieldStyledContext.Provider, {
705
+ ...styleState,
706
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldFrame, {
707
+ ...fieldProps,
708
+ ...getDataProps(state),
709
+ disabled,
710
+ ref: forwardedRef,
711
+ children
712
+ })
713
+ })
714
+ })
715
+ })
716
+ })
717
+ });
718
+ });
719
+ function usePartContexts() {
720
+ const root = React.useContext(FieldRootContext);
721
+ const association = React.useContext(AssociationContext);
722
+ const itemDisabled = React.useContext(FieldItemContext);
723
+ if (!root || !association) {
724
+ throw new Error("Field parts must be rendered inside <Field>.");
725
+ }
726
+ return {
727
+ root,
728
+ association,
729
+ itemDisabled
730
+ };
731
+ }
732
+ const FieldLabel = (0, import_core.createStyledHOC)(FieldLabelFrame, function FieldLabel2({ id: idProp, children, onPress, onMouseDown, ...labelProps }, forwardedRef) {
733
+ const { root, association, itemDisabled } = usePartContexts();
734
+ const generatedId = React.useId().replace(/:/g, "");
735
+ const id = idProp ?? `field-label-${generatedId}`;
736
+ const text = getText(children);
737
+ const disabled = root.state.disabled || itemDisabled;
738
+ (0, import_core.useIsomorphicLayoutEffect)(() => {
739
+ return association.registerLabel(id, text);
740
+ }, [
741
+ association.registerLabel,
742
+ id,
743
+ text
744
+ ]);
745
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldLabelFrame, {
746
+ ...labelProps,
747
+ ...getDataProps(root.state, disabled),
748
+ id,
749
+ ref: forwardedRef,
750
+ ...import_core.isWeb ? { htmlFor: association.controlId } : void 0,
751
+ ...!import_core.isWeb && disabled ? { accessibilityState: { disabled: true } } : void 0,
752
+ onMouseDown: (event) => {
753
+ onMouseDown?.(event);
754
+ if (!event.defaultPrevented && event.detail > 1) {
755
+ event.preventDefault();
756
+ }
757
+ },
758
+ onPress: (event) => {
759
+ onPress?.(event);
760
+ if (!import_core.isWeb && !event?.defaultPrevented) {
761
+ (0, import_focusable.focusFocusable)(association.controlId);
762
+ }
763
+ },
764
+ children
765
+ });
766
+ });
767
+ const FieldDescription = (0, import_core.createStyledHOC)(FieldDescriptionFrame, function FieldDescription2({ id: idProp, children, ...descriptionProps }, forwardedRef) {
768
+ const { root, association, itemDisabled } = usePartContexts();
769
+ const generatedId = React.useId().replace(/:/g, "");
770
+ const id = idProp ?? `field-description-${generatedId}`;
771
+ const text = getText(children);
772
+ const disabled = root.state.disabled || itemDisabled;
773
+ (0, import_core.useIsomorphicLayoutEffect)(() => {
774
+ return association.registerMessage(id, text);
775
+ }, [
776
+ association.registerMessage,
777
+ id,
778
+ text
779
+ ]);
780
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldDescriptionFrame, {
781
+ ...descriptionProps,
782
+ ...getDataProps(root.state, disabled),
783
+ id,
784
+ ref: forwardedRef,
785
+ children
786
+ });
787
+ });
788
+ const FieldError = (0, import_core.createStyledHOC)(FieldErrorFrame, function FieldError2({ id: idProp, children, match, ...errorProps }, forwardedRef) {
789
+ const { root, association, itemDisabled } = usePartContexts();
790
+ const generatedId = React.useId().replace(/:/g, "");
791
+ const id = idProp ?? `field-error-${generatedId}`;
792
+ const disabled = root.state.disabled || itemDisabled;
793
+ const rendered = match === true || !disabled && (typeof match === "string" ? Boolean(root.validityData.state[match]) : root.state.valid === false);
794
+ const message = children ?? root.state.errors.join("\n");
795
+ const text = getText(message);
796
+ (0, import_core.useIsomorphicLayoutEffect)(() => {
797
+ if (!rendered) {
798
+ return;
799
+ }
800
+ return association.registerMessage(id, text);
801
+ }, [
802
+ association.registerMessage,
803
+ id,
804
+ rendered,
805
+ text
806
+ ]);
807
+ if (!rendered) {
808
+ return null;
809
+ }
810
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldErrorFrame, {
811
+ ...errorProps,
812
+ ...getDataProps(root.state, disabled),
813
+ id,
814
+ ref: forwardedRef,
815
+ children: message
816
+ });
817
+ });
818
+ const FieldItem = (0, import_core.createStyledHOC)(FieldItemFrame, function FieldItem2({ disabled: disabledProp = false, children, ...itemProps }, forwardedRef) {
819
+ const root = React.useContext(FieldRootContext);
820
+ const parentAssociation = React.useContext(AssociationContext);
821
+ const reactId = React.useId().replace(/:/g, "");
822
+ const association = useAssociation(`field-item-${reactId}`, parentAssociation);
823
+ if (!root || !parentAssociation) {
824
+ throw new Error("Field.Item must be rendered inside <Field>.");
825
+ }
826
+ const disabled = root.state.disabled || disabledProp;
827
+ const controlContext = useControlContext(root, association, disabledProp, true);
828
+ const styleState = getStyleState(root.state, disabled);
829
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldItemContext.Provider, {
830
+ value: disabledProp,
831
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AssociationContext.Provider, {
832
+ value: association,
833
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_FieldContext.FieldControlContext.Provider, {
834
+ value: controlContext,
835
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_FieldContext.FieldStyledContext.Provider, {
836
+ ...styleState,
837
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldItemFrame, {
838
+ ...itemProps,
839
+ ...getDataProps(root.state, disabled),
840
+ disabled,
841
+ ref: forwardedRef,
842
+ children
843
+ })
844
+ })
845
+ })
846
+ })
847
+ });
848
+ });
849
+ const Field2 = (0, import_core.withStaticProperties)(FieldComponent, {
850
+ Label: FieldLabel,
851
+ Description: FieldDescription,
852
+ Error: FieldError,
853
+ Item: FieldItem,
854
+ useFieldState: import_FieldContext.useFieldState,
855
+ useFieldControl: import_FieldContext.useFieldControl
856
+ });