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