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