@tanstack/react-form 0.0.10 → 0.0.12

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 (87) hide show
  1. package/build/lib/_virtual/_rollupPluginBabelHelpers.cjs +19 -0
  2. package/build/lib/_virtual/_rollupPluginBabelHelpers.cjs.map +1 -0
  3. package/build/{cjs → lib}/_virtual/_rollupPluginBabelHelpers.js +1 -17
  4. package/build/lib/_virtual/_rollupPluginBabelHelpers.js.map +1 -0
  5. package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.cjs +19 -0
  6. package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.cjs.map +1 -0
  7. package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.js +17 -0
  8. package/build/lib/_virtual/_rollupPluginBabelHelpers.legacy.js.map +1 -0
  9. package/build/lib/createFormFactory.cjs +20 -0
  10. package/build/lib/createFormFactory.cjs.map +1 -0
  11. package/build/{types/react-form/src → lib}/createFormFactory.d.ts +1 -0
  12. package/build/lib/createFormFactory.d.ts.map +1 -0
  13. package/build/lib/createFormFactory.js +18 -0
  14. package/build/{cjs → lib}/createFormFactory.js.map +1 -1
  15. package/build/lib/createFormFactory.legacy.cjs +20 -0
  16. package/build/lib/createFormFactory.legacy.cjs.map +1 -0
  17. package/build/lib/createFormFactory.legacy.js +18 -0
  18. package/build/lib/createFormFactory.legacy.js.map +1 -0
  19. package/build/{cjs/formContext.js → lib/formContext.cjs} +4 -19
  20. package/build/lib/formContext.cjs.map +1 -0
  21. package/build/{types/react-form/src → lib}/formContext.d.ts +1 -0
  22. package/build/lib/formContext.d.ts.map +1 -0
  23. package/build/lib/formContext.js +13 -0
  24. package/build/{cjs → lib}/formContext.js.map +1 -1
  25. package/build/lib/formContext.legacy.cjs +35 -0
  26. package/build/lib/formContext.legacy.cjs.map +1 -0
  27. package/build/lib/formContext.legacy.js +13 -0
  28. package/build/lib/formContext.legacy.js.map +1 -0
  29. package/build/{cjs/index.js → lib/index.cjs} +4 -16
  30. package/build/lib/index.cjs.map +1 -0
  31. package/build/{types/react-form/src → lib}/index.d.ts +1 -0
  32. package/build/lib/index.d.ts.map +1 -0
  33. package/build/lib/index.js +5 -0
  34. package/build/{cjs → lib}/index.js.map +1 -1
  35. package/build/lib/index.legacy.cjs +26 -0
  36. package/build/lib/index.legacy.cjs.map +1 -0
  37. package/build/lib/index.legacy.js +5 -0
  38. package/build/lib/index.legacy.js.map +1 -0
  39. package/build/lib/tests/createFormFactory.test.d.ts +2 -0
  40. package/build/lib/tests/createFormFactory.test.d.ts.map +1 -0
  41. package/build/lib/tests/useForm.test.d.ts +2 -0
  42. package/build/lib/tests/useForm.test.d.ts.map +1 -0
  43. package/build/{cjs/useField.js → lib/useField.cjs} +22 -24
  44. package/build/lib/useField.cjs.map +1 -0
  45. package/build/{types/react-form/src → lib}/useField.d.ts +1 -1
  46. package/build/lib/useField.d.ts.map +1 -0
  47. package/build/lib/useField.js +74 -0
  48. package/build/lib/useField.js.map +1 -0
  49. package/build/lib/useField.legacy.cjs +96 -0
  50. package/build/lib/useField.legacy.cjs.map +1 -0
  51. package/build/lib/useField.legacy.js +74 -0
  52. package/build/lib/useField.legacy.js.map +1 -0
  53. package/build/lib/useForm.cjs +50 -0
  54. package/build/lib/useForm.cjs.map +1 -0
  55. package/build/{types/react-form/src → lib}/useForm.d.ts +1 -0
  56. package/build/lib/useForm.d.ts.map +1 -0
  57. package/build/lib/useForm.js +48 -0
  58. package/build/lib/useForm.js.map +1 -0
  59. package/build/lib/useForm.legacy.cjs +50 -0
  60. package/build/lib/useForm.legacy.cjs.map +1 -0
  61. package/build/lib/useForm.legacy.js +48 -0
  62. package/build/lib/useForm.legacy.js.map +1 -0
  63. package/package.json +30 -12
  64. package/src/tests/createFormFactory.test.tsx +39 -0
  65. package/src/tests/useForm.test.tsx +75 -0
  66. package/src/useField.tsx +2 -2
  67. package/src/useForm.tsx +3 -2
  68. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +0 -1
  69. package/build/cjs/createFormFactory.js +0 -31
  70. package/build/cjs/useField.js.map +0 -1
  71. package/build/cjs/useForm.js +0 -67
  72. package/build/cjs/useForm.js.map +0 -1
  73. package/build/esm/index.js +0 -154
  74. package/build/esm/index.js.map +0 -1
  75. package/build/stats-html.html +0 -2689
  76. package/build/stats-react.json +0 -355
  77. package/build/types/form-core/src/FieldApi.d.ts +0 -79
  78. package/build/types/form-core/src/FormApi.d.ts +0 -78
  79. package/build/types/form-core/src/index.d.ts +0 -3
  80. package/build/types/form-core/src/utils.d.ts +0 -22
  81. package/build/types/index.d.ts +0 -74
  82. package/build/types/react-form/src/tests/test.test.d.ts +0 -0
  83. package/build/umd/index.development.js +0 -991
  84. package/build/umd/index.development.js.map +0 -1
  85. package/build/umd/index.production.js +0 -43
  86. package/build/umd/index.production.js.map +0 -1
  87. package/src/tests/test.test.tsx +0 -5
@@ -1,991 +0,0 @@
1
- /**
2
- * react-form
3
- *
4
- * Copyright (c) TanStack
5
- *
6
- * This source code is licensed under the MIT license found in the
7
- * LICENSE.md file in the root directory of this source tree.
8
- *
9
- * @license MIT
10
- */
11
- (function (global, factory) {
12
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('use-sync-external-store/shim/with-selector'), require('react')) :
13
- typeof define === 'function' && define.amd ? define(['exports', 'use-sync-external-store/shim/with-selector', 'react'], factory) :
14
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ReactForm = {}, global.withSelector, global.React));
15
- })(this, (function (exports, withSelector, React) { 'use strict';
16
-
17
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
18
-
19
- function _interopNamespace(e) {
20
- if (e && e.__esModule) return e;
21
- var n = Object.create(null);
22
- if (e) {
23
- Object.keys(e).forEach(function (k) {
24
- if (k !== 'default') {
25
- var d = Object.getOwnPropertyDescriptor(e, k);
26
- Object.defineProperty(n, k, d.get ? d : {
27
- enumerable: true,
28
- get: function () { return e[k]; }
29
- });
30
- }
31
- });
32
- }
33
- n["default"] = e;
34
- return Object.freeze(n);
35
- }
36
-
37
- var React__namespace = /*#__PURE__*/_interopNamespace(React);
38
- var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
39
-
40
- /**
41
- * store
42
- *
43
- * Copyright (c) TanStack
44
- *
45
- * This source code is licensed under the MIT license found in the
46
- * LICENSE.md file in the root directory of this source tree.
47
- *
48
- * @license MIT
49
- */
50
- class Store {
51
- listeners = new Set();
52
- batching = false;
53
- queue = [];
54
- constructor(initialState, options) {
55
- this.state = initialState;
56
- this.options = options;
57
- }
58
- subscribe = listener => {
59
- this.listeners.add(listener);
60
- const unsub = this.options?.onSubscribe?.(listener, this);
61
- return () => {
62
- this.listeners.delete(listener);
63
- unsub?.();
64
- };
65
- };
66
- setState = updater => {
67
- const previous = this.state;
68
- this.state = this.options?.updateFn ? this.options.updateFn(previous)(updater) : updater(previous);
69
- if (this.state === previous) return;
70
- this.options?.onUpdate?.(this.state, previous);
71
- this.queue.push(() => {
72
- this.listeners.forEach(listener => listener(this.state, previous));
73
- });
74
- this.#flush();
75
- };
76
- #flush = () => {
77
- if (this.batching) return;
78
- this.queue.forEach(cb => cb());
79
- this.queue = [];
80
- };
81
- batch = cb => {
82
- this.batching = true;
83
- cb();
84
- this.batching = false;
85
- this.#flush();
86
- };
87
- }
88
-
89
- /**
90
- * form-core
91
- *
92
- * Copyright (c) TanStack
93
- *
94
- * This source code is licensed under the MIT license found in the
95
- * LICENSE.md file in the root directory of this source tree.
96
- *
97
- * @license MIT
98
- */
99
-
100
- function functionalUpdate(updater, input) {
101
- return typeof updater === 'function' ? updater(input) : updater;
102
- }
103
- function getBy(obj, path) {
104
- const pathArray = makePathArray(path);
105
- const pathObj = pathArray;
106
- return pathObj.reduce((current, pathPart) => {
107
- if (typeof current !== 'undefined') {
108
- return current[pathPart];
109
- }
110
-
111
- return undefined;
112
- }, obj);
113
- }
114
- function setBy(obj, _path, updater) {
115
- const path = makePathArray(_path);
116
-
117
- function doSet(parent) {
118
- if (!path.length) {
119
- return functionalUpdate(updater, parent);
120
- }
121
-
122
- const key = path.shift();
123
-
124
- if (typeof key === 'string') {
125
- if (typeof parent === 'object') {
126
- return { ...parent,
127
- [key]: doSet(parent[key])
128
- };
129
- }
130
-
131
- return {
132
- [key]: doSet()
133
- };
134
- }
135
-
136
- if (typeof key === 'number') {
137
- if (Array.isArray(parent)) {
138
- const prefix = parent.slice(0, key);
139
- return [...(prefix.length ? prefix : new Array(key)), doSet(parent[key]), ...parent.slice(key + 1)];
140
- }
141
-
142
- return [...new Array(key), doSet()];
143
- }
144
-
145
- throw new Error('Uh oh!');
146
- }
147
-
148
- return doSet(obj);
149
- }
150
- const reFindNumbers0 = /^(\d*)$/gm;
151
- const reFindNumbers1 = /\.(\d*)\./gm;
152
- const reFindNumbers2 = /^(\d*)\./gm;
153
- const reFindNumbers3 = /\.(\d*$)/gm;
154
- const reFindMultiplePeriods = /\.{2,}/gm;
155
- const intPrefix = '__int__';
156
- const intReplace = intPrefix + "$1";
157
-
158
- function makePathArray(str) {
159
- if (typeof str !== 'string') {
160
- throw new Error();
161
- }
162
-
163
- return str.replace('[', '.').replace(']', '').replace(reFindNumbers0, intReplace).replace(reFindNumbers1, "." + intReplace + ".").replace(reFindNumbers2, intReplace + ".").replace(reFindNumbers3, "." + intReplace).replace(reFindMultiplePeriods, '.').split('.').map(d => {
164
- if (d.indexOf(intPrefix) === 0) {
165
- return parseInt(d.substring(intPrefix.length), 10);
166
- }
167
-
168
- return d;
169
- });
170
- }
171
-
172
- function getDefaultFormState(defaultState) {
173
- return {
174
- values: {},
175
- fieldMeta: {},
176
- canSubmit: true,
177
- isFieldsValid: false,
178
- isFieldsValidating: false,
179
- isFormValid: false,
180
- isFormValidating: false,
181
- isSubmitted: false,
182
- isSubmitting: false,
183
- isTouched: false,
184
- isValid: false,
185
- isValidating: false,
186
- submissionAttempts: 0,
187
- formValidationCount: 0,
188
- ...defaultState
189
- };
190
- }
191
-
192
- class FormApi {
193
- // // This carries the context for nested fields
194
- constructor(_opts) {
195
- var _opts$defaultValues, _opts$defaultState;
196
-
197
- this.options = {};
198
- this.fieldInfo = {};
199
- this.validationMeta = {};
200
-
201
- this.update = options => {
202
- if (!options) return;
203
- this.store.batch(() => {
204
- if (options.defaultState && options.defaultState !== this.options.defaultState) {
205
- this.store.setState(prev => ({ ...prev,
206
- ...options.defaultState
207
- }));
208
- }
209
-
210
- if (options.defaultValues !== this.options.defaultValues) {
211
- this.store.setState(prev => ({ ...prev,
212
- values: options.defaultValues
213
- }));
214
- }
215
- });
216
- this.options = options;
217
- };
218
-
219
- this.reset = () => this.store.setState(() => getDefaultFormState(this.options.defaultValues));
220
-
221
- this.validateAllFields = async () => {
222
- const fieldValidationPromises = [];
223
- this.store.batch(() => {
224
- void Object.values(this.fieldInfo).forEach(field => {
225
- Object.values(field.instances).forEach(instance => {
226
- // If any fields are not touched
227
- if (!instance.state.meta.isTouched) {
228
- // Mark them as touched
229
- instance.setMeta(prev => ({ ...prev,
230
- isTouched: true
231
- })); // Validate the field
232
-
233
- if (instance.options.validate) {
234
- fieldValidationPromises.push(instance.validate());
235
- }
236
- }
237
- });
238
- });
239
- });
240
- return Promise.all(fieldValidationPromises);
241
- };
242
-
243
- this.validateForm = async () => {
244
- const {
245
- validate
246
- } = this.options;
247
-
248
- if (!validate) {
249
- return;
250
- } // Use the formValidationCount for all field instances to
251
- // track freshness of the validation
252
-
253
-
254
- this.store.setState(prev => ({ ...prev,
255
- isValidating: true,
256
- formValidationCount: prev.formValidationCount + 1
257
- }));
258
- const formValidationCount = this.state.formValidationCount;
259
-
260
- const checkLatest = () => formValidationCount === this.state.formValidationCount;
261
-
262
- if (!this.validationMeta.validationPromise) {
263
- this.validationMeta.validationPromise = new Promise((resolve, reject) => {
264
- this.validationMeta.validationResolve = resolve;
265
- this.validationMeta.validationReject = reject;
266
- });
267
- }
268
-
269
- const doValidation = async () => {
270
- try {
271
- const error = await validate(this.state.values, this);
272
-
273
- if (checkLatest()) {
274
- var _this$validationMeta$, _this$validationMeta;
275
-
276
- this.store.setState(prev => ({ ...prev,
277
- isValidating: false,
278
- error: error ? typeof error === 'string' ? error : 'Invalid Form Values' : null
279
- }));
280
- (_this$validationMeta$ = (_this$validationMeta = this.validationMeta).validationResolve) == null ? void 0 : _this$validationMeta$.call(_this$validationMeta, error);
281
- }
282
- } catch (err) {
283
- if (checkLatest()) {
284
- var _this$validationMeta$2, _this$validationMeta2;
285
-
286
- (_this$validationMeta$2 = (_this$validationMeta2 = this.validationMeta).validationReject) == null ? void 0 : _this$validationMeta$2.call(_this$validationMeta2, err);
287
- }
288
- } finally {
289
- delete this.validationMeta.validationPromise;
290
- }
291
- };
292
-
293
- doValidation();
294
- return this.validationMeta.validationPromise;
295
- };
296
-
297
- this.handleSubmit = async e => {
298
- e.preventDefault();
299
- e.stopPropagation(); // Check to see that the form and all fields have been touched
300
- // If they have not, touch them all and run validation
301
- // Run form validation
302
- // Submit the form
303
-
304
- this.store.setState(old => ({ ...old,
305
- // Submittion attempts mark the form as not submitted
306
- isSubmitted: false,
307
- // Count submission attempts
308
- submissionAttempts: old.submissionAttempts + 1
309
- })); // Don't let invalid forms submit
310
-
311
- if (!this.state.canSubmit) return;
312
- this.store.setState(d => ({ ...d,
313
- isSubmitting: true
314
- }));
315
-
316
- const done = () => {
317
- this.store.setState(prev => ({ ...prev,
318
- isSubmitting: false
319
- }));
320
- }; // Validate all fields
321
-
322
-
323
- await this.validateAllFields(); // Fields are invalid, do not submit
324
-
325
- if (!this.state.isFieldsValid) {
326
- var _this$options$onInval, _this$options;
327
-
328
- done();
329
- (_this$options$onInval = (_this$options = this.options).onInvalidSubmit) == null ? void 0 : _this$options$onInval.call(_this$options, this.state.values, this);
330
- return;
331
- } // Run validation for the form
332
-
333
-
334
- await this.validateForm();
335
-
336
- if (!this.state.isValid) {
337
- var _this$options$onInval2, _this$options2;
338
-
339
- done();
340
- (_this$options$onInval2 = (_this$options2 = this.options).onInvalidSubmit) == null ? void 0 : _this$options$onInval2.call(_this$options2, this.state.values, this);
341
- return;
342
- }
343
-
344
- try {
345
- var _this$options$onSubmi, _this$options3;
346
-
347
- // Run the submit code
348
- await ((_this$options$onSubmi = (_this$options3 = this.options).onSubmit) == null ? void 0 : _this$options$onSubmi.call(_this$options3, this.state.values, this));
349
- this.store.batch(() => {
350
- this.store.setState(prev => ({ ...prev,
351
- isSubmitted: true
352
- }));
353
- done();
354
- });
355
- } catch (err) {
356
- done();
357
- throw err;
358
- }
359
- };
360
-
361
- this.getFieldValue = field => getBy(this.state.values, field);
362
-
363
- this.getFieldMeta = field => {
364
- return this.state.fieldMeta[field];
365
- };
366
-
367
- this.getFieldInfo = field => {
368
- var _this$fieldInfo;
369
-
370
- return (_this$fieldInfo = this.fieldInfo)[field] || (_this$fieldInfo[field] = {
371
- instances: {}
372
- });
373
- };
374
-
375
- this.setFieldMeta = (field, updater) => {
376
- this.store.setState(prev => {
377
- return { ...prev,
378
- fieldMeta: { ...prev.fieldMeta,
379
- [field]: functionalUpdate(updater, prev.fieldMeta[field])
380
- }
381
- };
382
- });
383
- };
384
-
385
- this.setFieldValue = (field, updater, opts) => {
386
- var _opts$touch;
387
-
388
- const touch = (_opts$touch = opts == null ? void 0 : opts.touch) != null ? _opts$touch : true;
389
- this.store.batch(() => {
390
- this.store.setState(prev => {
391
- return { ...prev,
392
- values: setBy(prev.values, field, updater)
393
- };
394
- });
395
-
396
- if (touch) {
397
- this.setFieldMeta(field, prev => ({ ...prev,
398
- isTouched: true
399
- }));
400
- }
401
- });
402
- };
403
-
404
- this.pushFieldValue = (field, value, opts) => {
405
- return this.setFieldValue(field, prev => [...(Array.isArray(prev) ? prev : []), value], opts);
406
- };
407
-
408
- this.insertFieldValue = (field, index, value, opts) => {
409
- this.setFieldValue(field, prev => {
410
- // invariant( // TODO: bring in invariant
411
- // Array.isArray(prev),
412
- // `Cannot insert a field value into a non-array field. Check that this field's existing value is an array: ${field}.`
413
- // )
414
- return prev.map((d, i) => i === index ? value : d);
415
- }, opts);
416
- };
417
-
418
- this.removeFieldValue = (field, index, opts) => {
419
- this.setFieldValue(field, prev => {
420
- // invariant( // TODO: bring in invariant
421
- // Array.isArray(prev),
422
- // `Cannot insert a field value into a non-array field. Check that this field's existing value is an array: ${field}.`
423
- // )
424
- return prev.filter((_d, i) => i !== index);
425
- }, opts);
426
- };
427
-
428
- this.swapFieldValues = (field, index1, index2) => {
429
- this.setFieldValue(field, prev => {
430
- const prev1 = prev[index1];
431
- const prev2 = prev[index2];
432
- return setBy(setBy(prev, [index1], prev2), [index2], prev1);
433
- });
434
- };
435
-
436
- this.store = new Store(getDefaultFormState({ ...(_opts == null ? void 0 : _opts.defaultState),
437
- values: (_opts$defaultValues = _opts == null ? void 0 : _opts.defaultValues) != null ? _opts$defaultValues : _opts == null ? void 0 : (_opts$defaultState = _opts.defaultState) == null ? void 0 : _opts$defaultState.values,
438
- isFormValid: !(_opts != null && _opts.validate)
439
- }), {
440
- onUpdate: next => {
441
- // Computed state
442
- const fieldMetaValues = Object.values(next.fieldMeta);
443
- const isFieldsValidating = fieldMetaValues.some(field => field == null ? void 0 : field.isValidating);
444
- const isFieldsValid = !fieldMetaValues.some(field => field == null ? void 0 : field.error);
445
- const isTouched = fieldMetaValues.some(field => field == null ? void 0 : field.isTouched);
446
- const isValidating = isFieldsValidating || next.isFormValidating;
447
- const isFormValid = !next.formError;
448
- const isValid = isFieldsValid && isFormValid;
449
- const canSubmit = next.submissionAttempts === 0 && !isTouched || !isValidating && !next.isSubmitting && isValid;
450
- next = { ...next,
451
- isFieldsValidating,
452
- isFieldsValid,
453
- isFormValid,
454
- isValid,
455
- canSubmit,
456
- isTouched
457
- }; // Create a shortcut for the state
458
- // Write it back to the store
459
-
460
- this.store.state = next;
461
- this.state = next;
462
- }
463
- });
464
- this.state = this.store.state;
465
- this.update(_opts || {});
466
- }
467
-
468
- }
469
-
470
- var id = 0;
471
-
472
- function _classPrivateFieldLooseKey(name) {
473
- return "__private_" + id++ + "_" + name;
474
- }
475
-
476
- function _classPrivateFieldLooseBase(receiver, privateKey) {
477
- if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
478
- throw new TypeError("attempted to use private field on non-instance");
479
- }
480
-
481
- return receiver;
482
- }
483
-
484
- let uid = 0;
485
-
486
- var _updateStore = /*#__PURE__*/_classPrivateFieldLooseKey("updateStore");
487
-
488
- var _leaseValidateAsync = /*#__PURE__*/_classPrivateFieldLooseKey("leaseValidateAsync");
489
-
490
- class FieldApi {
491
- constructor(_opts) {
492
- var _this$getMeta;
493
-
494
- this.options = {};
495
-
496
- this.mount = () => {
497
- const info = this.getInfo();
498
- info.instances[this.uid] = this;
499
- const unsubscribe = this.form.store.subscribe(() => {
500
- _classPrivateFieldLooseBase(this, _updateStore)[_updateStore]();
501
- });
502
- return () => {
503
- unsubscribe();
504
- delete info.instances[this.uid];
505
-
506
- if (!Object.keys(info.instances).length) {
507
- delete this.form.fieldInfo[this.name];
508
- }
509
- };
510
- };
511
-
512
- Object.defineProperty(this, _updateStore, {
513
- writable: true,
514
- value: () => {
515
- this.store.batch(() => {
516
- const nextValue = this.getValue();
517
- const nextMeta = this.getMeta();
518
-
519
- if (nextValue !== this.state.value) {
520
- this.store.setState(prev => ({ ...prev,
521
- value: nextValue
522
- }));
523
- }
524
-
525
- if (nextMeta !== this.state.meta) {
526
- this.store.setState(prev => ({ ...prev,
527
- meta: nextMeta
528
- }));
529
- }
530
- });
531
- }
532
- });
533
-
534
- this.update = opts => {
535
- var _this$form$options$de, _this$form$options$de2, _this$form$options$de3, _this$form$options$de4;
536
-
537
- this.options = {
538
- validatePristine: (_this$form$options$de = this.form.options.defaultValidatePristine) != null ? _this$form$options$de : false,
539
- validateOn: (_this$form$options$de2 = this.form.options.defaultValidateOn) != null ? _this$form$options$de2 : 'change',
540
- validateAsyncOn: (_this$form$options$de3 = this.form.options.defaultValidateAsyncOn) != null ? _this$form$options$de3 : 'blur',
541
- validateAsyncDebounceMs: (_this$form$options$de4 = this.form.options.defaultValidateAsyncDebounceMs) != null ? _this$form$options$de4 : 0,
542
- ...opts
543
- }; // Default Value
544
-
545
- if (this.state.value === undefined && this.options.defaultValue !== undefined) {
546
- this.setValue(this.options.defaultValue);
547
- } // Default Meta
548
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
549
-
550
-
551
- if (this.getMeta() === undefined) {
552
- this.setMeta(this.state.meta);
553
- }
554
- };
555
-
556
- this.getValue = () => {
557
- return this.form.getFieldValue(this.name);
558
- };
559
-
560
- this.setValue = (updater, options) => this.form.setFieldValue(this.name, updater, options);
561
-
562
- this.getMeta = () => this.form.getFieldMeta(this.name);
563
-
564
- this.setMeta = updater => this.form.setFieldMeta(this.name, updater);
565
-
566
- this.getInfo = () => this.form.getFieldInfo(this.name);
567
-
568
- this.pushValue = value => this.form.pushFieldValue(this.name, value);
569
-
570
- this.insertValue = (index, value) => this.form.insertFieldValue(this.name, index, value);
571
-
572
- this.removeValue = index => this.form.removeFieldValue(this.name, index);
573
-
574
- this.swapValues = (aIndex, bIndex) => this.form.swapFieldValues(this.name, aIndex, bIndex);
575
-
576
- this.getSubField = name => new FieldApi({
577
- name: this.name + "." + name,
578
- form: this.form
579
- });
580
-
581
- this.validateSync = async (value = this.state.value) => {
582
- const {
583
- validate
584
- } = this.options;
585
-
586
- if (!validate) {
587
- return;
588
- } // Use the validationCount for all field instances to
589
- // track freshness of the validation
590
-
591
-
592
- const validationCount = (this.getInfo().validationCount || 0) + 1;
593
- this.getInfo().validationCount = validationCount;
594
- const error = normalizeError(validate(value, this));
595
-
596
- if (this.state.meta.error !== error) {
597
- this.setMeta(prev => ({ ...prev,
598
- error
599
- }));
600
- } // If a sync error is encountered, cancel any async validation
601
-
602
-
603
- if (this.state.meta.error) {
604
- this.cancelValidateAsync();
605
- }
606
- };
607
-
608
- Object.defineProperty(this, _leaseValidateAsync, {
609
- writable: true,
610
- value: () => {
611
- const count = (this.getInfo().validationAsyncCount || 0) + 1;
612
- this.getInfo().validationAsyncCount = count;
613
- return count;
614
- }
615
- });
616
-
617
- this.cancelValidateAsync = () => {
618
- // Lease a new validation count to ignore any pending validations
619
- _classPrivateFieldLooseBase(this, _leaseValidateAsync)[_leaseValidateAsync](); // Cancel any pending validation state
620
-
621
-
622
- this.setMeta(prev => ({ ...prev,
623
- isValidating: false
624
- }));
625
- };
626
-
627
- this.validateAsync = async (value = this.state.value) => {
628
- const {
629
- validateAsync,
630
- validateAsyncDebounceMs
631
- } = this.options;
632
-
633
- if (!validateAsync) {
634
- return;
635
- }
636
-
637
- if (this.state.meta.isValidating !== true) this.setMeta(prev => ({ ...prev,
638
- isValidating: true
639
- })); // Use the validationCount for all field instances to
640
- // track freshness of the validation
641
-
642
- const validationAsyncCount = _classPrivateFieldLooseBase(this, _leaseValidateAsync)[_leaseValidateAsync]();
643
-
644
- const checkLatest = () => validationAsyncCount === this.getInfo().validationAsyncCount;
645
-
646
- if (!this.getInfo().validationPromise) {
647
- this.getInfo().validationPromise = new Promise((resolve, reject) => {
648
- this.getInfo().validationResolve = resolve;
649
- this.getInfo().validationReject = reject;
650
- });
651
- }
652
-
653
- if (validateAsyncDebounceMs > 0) {
654
- await new Promise(r => setTimeout(r, validateAsyncDebounceMs));
655
- } // Only kick off validation if this validation is the latest attempt
656
-
657
-
658
- if (checkLatest()) {
659
- try {
660
- const rawError = await validateAsync(value, this);
661
-
662
- if (checkLatest()) {
663
- var _this$getInfo$validat, _this$getInfo;
664
-
665
- const error = normalizeError(rawError);
666
- this.setMeta(prev => ({ ...prev,
667
- isValidating: false,
668
- error
669
- }));
670
- (_this$getInfo$validat = (_this$getInfo = this.getInfo()).validationResolve) == null ? void 0 : _this$getInfo$validat.call(_this$getInfo, error);
671
- }
672
- } catch (error) {
673
- if (checkLatest()) {
674
- var _this$getInfo$validat2, _this$getInfo2;
675
-
676
- (_this$getInfo$validat2 = (_this$getInfo2 = this.getInfo()).validationReject) == null ? void 0 : _this$getInfo$validat2.call(_this$getInfo2, error);
677
- throw error;
678
- }
679
- } finally {
680
- if (checkLatest()) {
681
- this.setMeta(prev => ({ ...prev,
682
- isValidating: false
683
- }));
684
- delete this.getInfo().validationPromise;
685
- }
686
- }
687
- } // Always return the latest validation promise to the caller
688
-
689
-
690
- return this.getInfo().validationPromise;
691
- };
692
-
693
- this.shouldValidate = (isAsync, cause) => {
694
- const {
695
- validateOn,
696
- validateAsyncOn
697
- } = this.options;
698
- const level = getValidationCauseLevel(cause); // Must meet *at least* the validation level to validate,
699
- // e.g. if validateOn is 'change' and validateCause is 'blur',
700
- // the field will still validate
701
-
702
- return Object.keys(validateCauseLevels).some(d => isAsync ? validateAsyncOn : validateOn === d && level >= validateCauseLevels[d]);
703
- };
704
-
705
- this.validate = async (cause, value) => {
706
- // If the field is pristine and validatePristine is false, do not validate
707
- if (!this.options.validatePristine && !this.state.meta.isTouched) return; // Attempt to sync validate first
708
-
709
- if (this.shouldValidate(false, cause)) {
710
- this.validateSync(value);
711
- } // If there is an error, return it, do not attempt async validation
712
-
713
-
714
- if (this.state.meta.error) {
715
- return this.state.meta.error;
716
- } // No error? Attempt async validation
717
-
718
-
719
- if (this.shouldValidate(true, cause)) {
720
- return this.validateAsync(value);
721
- } // If there is no sync error or async validation attempt, there is no error
722
-
723
-
724
- return undefined;
725
- };
726
-
727
- this.getChangeProps = (props = {}) => {
728
- return { ...props,
729
- value: this.state.value,
730
- onChange: value => {
731
- this.setValue(value);
732
- props.onChange == null ? void 0 : props.onChange(value);
733
- },
734
- onBlur: e => {
735
- this.setMeta(prev => ({ ...prev,
736
- isTouched: true
737
- }));
738
- this.validate('blur');
739
- props.onBlur == null ? void 0 : props.onBlur(e);
740
- }
741
- };
742
- };
743
-
744
- this.getInputProps = (props = {}) => {
745
- return { ...props,
746
- value: String(this.state.value),
747
- onChange: e => {
748
- this.setValue(e.target.value);
749
- props.onChange == null ? void 0 : props.onChange(e.target.value);
750
- },
751
- onBlur: this.getChangeProps(props).onBlur
752
- };
753
- };
754
-
755
- this.form = _opts.form;
756
- this.uid = uid++; // Support field prefixing from FieldScope
757
- // let fieldPrefix = ''
758
- // if (this.form.fieldName) {
759
- // fieldPrefix = `${this.form.fieldName}.`
760
- // }
761
-
762
- this.name = _opts.name;
763
- this.store = new Store({
764
- value: this.getValue(),
765
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
766
- meta: (_this$getMeta = this.getMeta()) != null ? _this$getMeta : {
767
- isValidating: false,
768
- isTouched: false,
769
- ...this.options.defaultMeta
770
- }
771
- }, {
772
- onUpdate: next => {
773
- next.meta.touchedError = next.meta.isTouched ? next.meta.error : undefined; // Do not validate pristine fields
774
-
775
- const prevState = this.state;
776
- this.state = next;
777
-
778
- if (next.value !== prevState.value) {
779
- this.validate('change', next.value);
780
- }
781
- }
782
- });
783
- this.state = this.store.state;
784
- this.update(_opts);
785
- }
786
-
787
- }
788
- const validateCauseLevels = {
789
- change: 0,
790
- blur: 1,
791
- submit: 2
792
- };
793
-
794
- function getValidationCauseLevel(cause) {
795
- return !cause ? 3 : validateCauseLevels[cause];
796
- }
797
-
798
- function normalizeError(rawError) {
799
- if (rawError) {
800
- if (typeof rawError !== 'string') {
801
- return 'Invalid Form Values';
802
- }
803
-
804
- return rawError;
805
- }
806
-
807
- return undefined;
808
- }
809
-
810
- function _extends() {
811
- _extends = Object.assign ? Object.assign.bind() : function (target) {
812
- for (var i = 1; i < arguments.length; i++) {
813
- var source = arguments[i];
814
-
815
- for (var key in source) {
816
- if (Object.prototype.hasOwnProperty.call(source, key)) {
817
- target[key] = source[key];
818
- }
819
- }
820
- }
821
-
822
- return target;
823
- };
824
- return _extends.apply(this, arguments);
825
- }
826
-
827
- /**
828
- * react-store
829
- *
830
- * Copyright (c) TanStack
831
- *
832
- * This source code is licensed under the MIT license found in the
833
- * LICENSE.md file in the root directory of this source tree.
834
- *
835
- * @license MIT
836
- */
837
-
838
- function useStore(store, selector = d => d) {
839
- const slice = withSelector.useSyncExternalStoreWithSelector(store.subscribe, () => store.state, () => store.state, selector, shallow);
840
- return slice;
841
- }
842
- function shallow(objA, objB) {
843
- if (Object.is(objA, objB)) {
844
- return true;
845
- }
846
- if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
847
- return false;
848
- }
849
- const keysA = Object.keys(objA);
850
- if (keysA.length !== Object.keys(objB).length) {
851
- return false;
852
- }
853
- for (let i = 0; i < keysA.length; i++) {
854
- if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !Object.is(objA[keysA[i]], objB[keysA[i]])) {
855
- return false;
856
- }
857
- }
858
- return true;
859
- }
860
-
861
- const formContext = /*#__PURE__*/React__namespace.createContext(null);
862
- function useFormContext() {
863
- const formApi = React__namespace.useContext(formContext);
864
-
865
- if (!formApi) {
866
- throw new Error("You are trying to use the form API outside of a form!");
867
- }
868
-
869
- return formApi;
870
- }
871
-
872
- function useField(opts) {
873
- // Get the form API either manually or from context
874
- const {
875
- formApi,
876
- parentFieldName
877
- } = useFormContext();
878
- const [fieldApi] = React__namespace.useState(() => {
879
- const name = (typeof opts.index === 'number' ? [parentFieldName, opts.index, opts.name] : [parentFieldName, opts.name]).filter(d => d !== undefined).join('.');
880
- const api = new FieldApi({ ...opts,
881
- form: formApi,
882
- name: name
883
- });
884
- api.Field = Field;
885
- return api;
886
- }); // Keep options up to date as they are rendered
887
-
888
- fieldApi.update({ ...opts,
889
- form: formApi
890
- });
891
- useStore(fieldApi.store, opts.mode === 'array' ? state => {
892
- return [state.meta, Object.keys(state.value || []).length];
893
- } : undefined); // Instantiates field meta and removes it when unrendered
894
-
895
- React__namespace.useEffect(() => fieldApi.mount(), [fieldApi]);
896
- return fieldApi;
897
- } // export type FieldValue<TFormData, TField> = TFormData extends any[]
898
- // ? TField extends `[${infer TIndex extends number | 'i'}].${infer TRest}`
899
- // ? DeepValue<TFormData[TIndex extends 'i' ? number : TIndex], TRest>
900
- // : TField extends `[${infer TIndex extends number | 'i'}]`
901
- // ? TFormData[TIndex extends 'i' ? number : TIndex]
902
- // : never
903
- // : TField extends `${infer TPrefix}[${infer TIndex extends
904
- // | number
905
- // | 'i'}].${infer TRest}`
906
- // ? DeepValue<
907
- // DeepValue<TFormData, TPrefix>[TIndex extends 'i' ? number : TIndex],
908
- // TRest
909
- // >
910
- // : TField extends `${infer TPrefix}[${infer TIndex extends number | 'i'}]`
911
- // ? DeepValue<TFormData, TPrefix>[TIndex extends 'i' ? number : TIndex]
912
- // : DeepValue<TFormData, TField>
913
-
914
- function Field({
915
- children,
916
- ...fieldOptions
917
- }) {
918
- const fieldApi = useField(fieldOptions);
919
- return /*#__PURE__*/React__namespace.createElement(formContext.Provider, {
920
- value: {
921
- formApi: fieldApi.form,
922
- parentFieldName: fieldApi.name
923
- },
924
- children: functionalUpdate(children, fieldApi)
925
- });
926
- }
927
-
928
- function useForm(opts) {
929
- const [formApi] = React__default["default"].useState(() => {
930
- // @ts-ignore
931
- const api = new FormApi(opts);
932
-
933
- api.Provider = props => /*#__PURE__*/React__default["default"].createElement(formContext.Provider, _extends({}, props, {
934
- value: {
935
- formApi: api
936
- }
937
- }));
938
-
939
- api.getFormProps = () => {
940
- return {
941
- onSubmit: formApi.handleSubmit,
942
- disabled: api.state.isSubmitting
943
- };
944
- };
945
-
946
- api.Field = Field;
947
- api.useField = useField;
948
-
949
- api.useStore = ( // @ts-ignore
950
- selector) => {
951
- // eslint-disable-next-line react-hooks/rules-of-hooks
952
- return useStore(api.store, selector);
953
- };
954
-
955
- api.Subscribe = ( // @ts-ignore
956
- props) => {
957
- return functionalUpdate(props.children, // eslint-disable-next-line react-hooks/rules-of-hooks
958
- useStore(api.store, props.selector));
959
- };
960
-
961
- return api;
962
- });
963
- formApi.useStore(state => state.isSubmitting);
964
- formApi.update(opts);
965
- return formApi;
966
- }
967
-
968
- function createFormFactory(defaultOpts) {
969
- return {
970
- useForm: opts => {
971
- return useForm({ ...defaultOpts,
972
- ...opts
973
- });
974
- },
975
- useField: useField,
976
- Field: Field
977
- };
978
- }
979
-
980
- exports.Field = Field;
981
- exports.FieldApi = FieldApi;
982
- exports.FormApi = FormApi;
983
- exports.createFormFactory = createFormFactory;
984
- exports.functionalUpdate = functionalUpdate;
985
- exports.useField = useField;
986
- exports.useForm = useForm;
987
-
988
- Object.defineProperty(exports, '__esModule', { value: true });
989
-
990
- }));
991
- //# sourceMappingURL=index.development.js.map