@tanstack/form-core 0.0.9 → 0.0.11

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.
@@ -10,6 +10,75 @@
10
10
  */
11
11
  import { Store } from '@tanstack/store';
12
12
 
13
+ function _defineProperty(obj, key, value) {
14
+ if (key in obj) {
15
+ Object.defineProperty(obj, key, {
16
+ value: value,
17
+ enumerable: true,
18
+ configurable: true,
19
+ writable: true
20
+ });
21
+ } else {
22
+ obj[key] = value;
23
+ }
24
+
25
+ return obj;
26
+ }
27
+
28
+ function _classPrivateFieldGet(receiver, privateMap) {
29
+ var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get");
30
+
31
+ return _classApplyDescriptorGet(receiver, descriptor);
32
+ }
33
+
34
+ function _classPrivateFieldSet(receiver, privateMap, value) {
35
+ var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set");
36
+
37
+ _classApplyDescriptorSet(receiver, descriptor, value);
38
+
39
+ return value;
40
+ }
41
+
42
+ function _classExtractFieldDescriptor(receiver, privateMap, action) {
43
+ if (!privateMap.has(receiver)) {
44
+ throw new TypeError("attempted to " + action + " private field on non-instance");
45
+ }
46
+
47
+ return privateMap.get(receiver);
48
+ }
49
+
50
+ function _classApplyDescriptorGet(receiver, descriptor) {
51
+ if (descriptor.get) {
52
+ return descriptor.get.call(receiver);
53
+ }
54
+
55
+ return descriptor.value;
56
+ }
57
+
58
+ function _classApplyDescriptorSet(receiver, descriptor, value) {
59
+ if (descriptor.set) {
60
+ descriptor.set.call(receiver, value);
61
+ } else {
62
+ if (!descriptor.writable) {
63
+ throw new TypeError("attempted to set read only private field");
64
+ }
65
+
66
+ descriptor.value = value;
67
+ }
68
+ }
69
+
70
+ function _checkPrivateRedeclaration(obj, privateCollection) {
71
+ if (privateCollection.has(obj)) {
72
+ throw new TypeError("Cannot initialize the same private elements twice on an object");
73
+ }
74
+ }
75
+
76
+ function _classPrivateFieldInitSpec(obj, privateMap, value) {
77
+ _checkPrivateRedeclaration(obj, privateMap);
78
+
79
+ privateMap.set(obj, value);
80
+ }
81
+
13
82
  function functionalUpdate(updater, input) {
14
83
  return typeof updater === 'function' ? updater(input) : updater;
15
84
  }
@@ -104,14 +173,24 @@ function getDefaultFormState(defaultState) {
104
173
 
105
174
  class FormApi {
106
175
  // // This carries the context for nested fields
176
+ // Do not use __state directly, as it is not reactive.
177
+ // Please use form.useStore() utility to subscribe to state
107
178
  constructor(_opts) {
108
179
  var _opts$defaultValues, _opts$defaultState;
109
180
 
110
- this.options = {};
111
- this.fieldInfo = {};
112
- this.validationMeta = {};
181
+ _defineProperty(this, "options", {});
182
+
183
+ _defineProperty(this, "store", void 0);
113
184
 
114
- this.update = options => {
185
+ _defineProperty(this, "state", void 0);
186
+
187
+ _defineProperty(this, "fieldInfo", {});
188
+
189
+ _defineProperty(this, "fieldName", void 0);
190
+
191
+ _defineProperty(this, "validationMeta", {});
192
+
193
+ _defineProperty(this, "update", options => {
115
194
  if (!options) return;
116
195
  this.store.batch(() => {
117
196
  if (options.defaultState && options.defaultState !== this.options.defaultState) {
@@ -121,17 +200,15 @@ class FormApi {
121
200
  }
122
201
 
123
202
  if (options.defaultValues !== this.options.defaultValues) {
124
- this.store.setState(prev => ({ ...prev,
125
- values: options.defaultValues
126
- }));
203
+ this.store.setState(() => getDefaultFormState(options.defaultValues));
127
204
  }
128
205
  });
129
206
  this.options = options;
130
- };
207
+ });
131
208
 
132
- this.reset = () => this.store.setState(() => getDefaultFormState(this.options.defaultValues));
209
+ _defineProperty(this, "reset", () => this.store.setState(() => getDefaultFormState(this.options.defaultValues)));
133
210
 
134
- this.validateAllFields = async () => {
211
+ _defineProperty(this, "validateAllFields", async cause => {
135
212
  const fieldValidationPromises = [];
136
213
  this.store.batch(() => {
137
214
  void Object.values(this.fieldInfo).forEach(field => {
@@ -143,71 +220,15 @@ class FormApi {
143
220
  isTouched: true
144
221
  })); // Validate the field
145
222
 
146
- if (instance.options.validate) {
147
- fieldValidationPromises.push(instance.validate());
148
- }
223
+ fieldValidationPromises.push(Promise.resolve().then(() => instance.validate(cause)));
149
224
  }
150
225
  });
151
226
  });
152
227
  });
153
228
  return Promise.all(fieldValidationPromises);
154
- };
155
-
156
- this.validateForm = async () => {
157
- const {
158
- validate
159
- } = this.options;
160
-
161
- if (!validate) {
162
- return;
163
- } // Use the formValidationCount for all field instances to
164
- // track freshness of the validation
165
-
166
-
167
- this.store.setState(prev => ({ ...prev,
168
- isValidating: true,
169
- formValidationCount: prev.formValidationCount + 1
170
- }));
171
- const formValidationCount = this.state.formValidationCount;
172
-
173
- const checkLatest = () => formValidationCount === this.state.formValidationCount;
174
-
175
- if (!this.validationMeta.validationPromise) {
176
- this.validationMeta.validationPromise = new Promise((resolve, reject) => {
177
- this.validationMeta.validationResolve = resolve;
178
- this.validationMeta.validationReject = reject;
179
- });
180
- }
181
-
182
- const doValidation = async () => {
183
- try {
184
- const error = await validate(this.state.values, this);
185
-
186
- if (checkLatest()) {
187
- var _this$validationMeta$, _this$validationMeta;
188
-
189
- this.store.setState(prev => ({ ...prev,
190
- isValidating: false,
191
- error: error ? typeof error === 'string' ? error : 'Invalid Form Values' : null
192
- }));
193
- (_this$validationMeta$ = (_this$validationMeta = this.validationMeta).validationResolve) == null ? void 0 : _this$validationMeta$.call(_this$validationMeta, error);
194
- }
195
- } catch (err) {
196
- if (checkLatest()) {
197
- var _this$validationMeta$2, _this$validationMeta2;
198
-
199
- (_this$validationMeta$2 = (_this$validationMeta2 = this.validationMeta).validationReject) == null ? void 0 : _this$validationMeta$2.call(_this$validationMeta2, err);
200
- }
201
- } finally {
202
- delete this.validationMeta.validationPromise;
203
- }
204
- };
205
-
206
- doValidation();
207
- return this.validationMeta.validationPromise;
208
- };
229
+ });
209
230
 
210
- this.handleSubmit = async e => {
231
+ _defineProperty(this, "handleSubmit", async e => {
211
232
  e.preventDefault();
212
233
  e.stopPropagation(); // Check to see that the form and all fields have been touched
213
234
  // If they have not, touch them all and run validation
@@ -233,32 +254,31 @@ class FormApi {
233
254
  }; // Validate all fields
234
255
 
235
256
 
236
- await this.validateAllFields(); // Fields are invalid, do not submit
257
+ await this.validateAllFields('submit'); // Fields are invalid, do not submit
237
258
 
238
259
  if (!this.state.isFieldsValid) {
239
- var _this$options$onInval, _this$options;
260
+ var _this$options$onSubmi, _this$options;
240
261
 
241
262
  done();
242
- (_this$options$onInval = (_this$options = this.options).onInvalidSubmit) == null ? void 0 : _this$options$onInval.call(_this$options, this.state.values, this);
263
+ (_this$options$onSubmi = (_this$options = this.options).onSubmitInvalid) == null ? void 0 : _this$options$onSubmi.call(_this$options, this.state.values, this);
243
264
  return;
244
265
  } // Run validation for the form
266
+ // await this.validateForm()
245
267
 
246
268
 
247
- await this.validateForm();
248
-
249
269
  if (!this.state.isValid) {
250
- var _this$options$onInval2, _this$options2;
270
+ var _this$options$onSubmi2, _this$options2;
251
271
 
252
272
  done();
253
- (_this$options$onInval2 = (_this$options2 = this.options).onInvalidSubmit) == null ? void 0 : _this$options$onInval2.call(_this$options2, this.state.values, this);
273
+ (_this$options$onSubmi2 = (_this$options2 = this.options).onSubmitInvalid) == null ? void 0 : _this$options$onSubmi2.call(_this$options2, this.state.values, this);
254
274
  return;
255
275
  }
256
276
 
257
277
  try {
258
- var _this$options$onSubmi, _this$options3;
278
+ var _this$options$onSubmi3, _this$options3;
259
279
 
260
280
  // Run the submit code
261
- await ((_this$options$onSubmi = (_this$options3 = this.options).onSubmit) == null ? void 0 : _this$options$onSubmi.call(_this$options3, this.state.values, this));
281
+ await ((_this$options$onSubmi3 = (_this$options3 = this.options).onSubmit) == null ? void 0 : _this$options$onSubmi3.call(_this$options3, this.state.values, this));
262
282
  this.store.batch(() => {
263
283
  this.store.setState(prev => ({ ...prev,
264
284
  isSubmitted: true
@@ -269,23 +289,23 @@ class FormApi {
269
289
  done();
270
290
  throw err;
271
291
  }
272
- };
292
+ });
273
293
 
274
- this.getFieldValue = field => getBy(this.state.values, field);
294
+ _defineProperty(this, "getFieldValue", field => getBy(this.state.values, field));
275
295
 
276
- this.getFieldMeta = field => {
296
+ _defineProperty(this, "getFieldMeta", field => {
277
297
  return this.state.fieldMeta[field];
278
- };
298
+ });
279
299
 
280
- this.getFieldInfo = field => {
300
+ _defineProperty(this, "getFieldInfo", field => {
281
301
  var _this$fieldInfo;
282
302
 
283
303
  return (_this$fieldInfo = this.fieldInfo)[field] || (_this$fieldInfo[field] = {
284
304
  instances: {}
285
305
  });
286
- };
306
+ });
287
307
 
288
- this.setFieldMeta = (field, updater) => {
308
+ _defineProperty(this, "setFieldMeta", (field, updater) => {
289
309
  this.store.setState(prev => {
290
310
  return { ...prev,
291
311
  fieldMeta: { ...prev.fieldMeta,
@@ -293,85 +313,76 @@ class FormApi {
293
313
  }
294
314
  };
295
315
  });
296
- };
297
-
298
- this.setFieldValue = (field, updater, opts) => {
299
- var _opts$touch;
316
+ });
300
317
 
301
- const touch = (_opts$touch = opts == null ? void 0 : opts.touch) != null ? _opts$touch : true;
318
+ _defineProperty(this, "setFieldValue", (field, updater, opts) => {
319
+ const touch = opts == null ? void 0 : opts.touch;
302
320
  this.store.batch(() => {
303
- this.store.setState(prev => {
304
- return { ...prev,
305
- values: setBy(prev.values, field, updater)
306
- };
307
- });
308
-
309
321
  if (touch) {
310
322
  this.setFieldMeta(field, prev => ({ ...prev,
311
323
  isTouched: true
312
324
  }));
313
325
  }
326
+
327
+ this.store.setState(prev => {
328
+ return { ...prev,
329
+ values: setBy(prev.values, field, updater)
330
+ };
331
+ });
314
332
  });
315
- };
333
+ });
316
334
 
317
- this.pushFieldValue = (field, value, opts) => {
335
+ _defineProperty(this, "pushFieldValue", (field, value, opts) => {
318
336
  return this.setFieldValue(field, prev => [...(Array.isArray(prev) ? prev : []), value], opts);
319
- };
337
+ });
320
338
 
321
- this.insertFieldValue = (field, index, value, opts) => {
339
+ _defineProperty(this, "insertFieldValue", (field, index, value, opts) => {
322
340
  this.setFieldValue(field, prev => {
323
- // invariant( // TODO: bring in invariant
324
- // Array.isArray(prev),
325
- // `Cannot insert a field value into a non-array field. Check that this field's existing value is an array: ${field}.`
326
- // )
327
341
  return prev.map((d, i) => i === index ? value : d);
328
342
  }, opts);
329
- };
343
+ });
330
344
 
331
- this.removeFieldValue = (field, index, opts) => {
345
+ _defineProperty(this, "removeFieldValue", (field, index, opts) => {
332
346
  this.setFieldValue(field, prev => {
333
- // invariant( // TODO: bring in invariant
334
- // Array.isArray(prev),
335
- // `Cannot insert a field value into a non-array field. Check that this field's existing value is an array: ${field}.`
336
- // )
337
347
  return prev.filter((_d, i) => i !== index);
338
348
  }, opts);
339
- };
349
+ });
340
350
 
341
- this.swapFieldValues = (field, index1, index2) => {
351
+ _defineProperty(this, "swapFieldValues", (field, index1, index2) => {
342
352
  this.setFieldValue(field, prev => {
343
353
  const prev1 = prev[index1];
344
354
  const prev2 = prev[index2];
345
355
  return setBy(setBy(prev, [index1], prev2), [index2], prev1);
346
356
  });
347
- };
357
+ });
348
358
 
349
359
  this.store = new Store(getDefaultFormState({ ...(_opts == null ? void 0 : _opts.defaultState),
350
360
  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,
351
- isFormValid: !(_opts != null && _opts.validate)
361
+ isFormValid: true
352
362
  }), {
353
- onUpdate: next => {
354
- // Computed state
355
- const fieldMetaValues = Object.values(next.fieldMeta);
363
+ onUpdate: () => {
364
+ let {
365
+ state
366
+ } = this.store; // Computed state
367
+
368
+ const fieldMetaValues = Object.values(state.fieldMeta);
356
369
  const isFieldsValidating = fieldMetaValues.some(field => field == null ? void 0 : field.isValidating);
357
370
  const isFieldsValid = !fieldMetaValues.some(field => field == null ? void 0 : field.error);
358
371
  const isTouched = fieldMetaValues.some(field => field == null ? void 0 : field.isTouched);
359
- const isValidating = isFieldsValidating || next.isFormValidating;
360
- const isFormValid = !next.formError;
372
+ const isValidating = isFieldsValidating || state.isFormValidating;
373
+ const isFormValid = !state.formError;
361
374
  const isValid = isFieldsValid && isFormValid;
362
- const canSubmit = next.submissionAttempts === 0 && !isTouched || !isValidating && !next.isSubmitting && isValid;
363
- next = { ...next,
375
+ const canSubmit = state.submissionAttempts === 0 && !isTouched || !isValidating && !state.isSubmitting && isValid;
376
+ state = { ...state,
364
377
  isFieldsValidating,
365
378
  isFieldsValid,
366
379
  isFormValid,
367
380
  isValid,
368
381
  canSubmit,
369
382
  isTouched
370
- }; // Create a shortcut for the state
371
- // Write it back to the store
372
-
373
- this.store.state = next;
374
- this.state = next;
383
+ };
384
+ this.store.state = state;
385
+ this.state = state;
375
386
  }
376
387
  });
377
388
  this.state = this.store.state;
@@ -380,51 +391,39 @@ class FormApi {
380
391
 
381
392
  }
382
393
 
383
- var id = 0;
384
-
385
- function _classPrivateFieldLooseKey(name) {
386
- return "__private_" + id++ + "_" + name;
387
- }
388
-
389
- function _classPrivateFieldLooseBase(receiver, privateKey) {
390
- if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
391
- throw new TypeError("attempted to use private field on non-instance");
392
- }
393
-
394
- return receiver;
395
- }
396
-
397
394
  let uid = 0;
398
395
 
399
- var _updateStore = /*#__PURE__*/_classPrivateFieldLooseKey("updateStore");
396
+ var _prevState = /*#__PURE__*/new WeakMap();
400
397
 
401
- var _leaseValidateAsync = /*#__PURE__*/_classPrivateFieldLooseKey("leaseValidateAsync");
398
+ var _leaseValidateAsync = /*#__PURE__*/new WeakMap();
402
399
 
403
400
  class FieldApi {
404
401
  constructor(_opts) {
405
402
  var _this$getMeta;
406
403
 
407
- this.options = {};
404
+ _defineProperty(this, "uid", void 0);
408
405
 
409
- this.mount = () => {
410
- const info = this.getInfo();
411
- info.instances[this.uid] = this;
412
- const unsubscribe = this.form.store.subscribe(() => {
413
- _classPrivateFieldLooseBase(this, _updateStore)[_updateStore]();
414
- });
415
- return () => {
416
- unsubscribe();
417
- delete info.instances[this.uid];
406
+ _defineProperty(this, "form", void 0);
418
407
 
419
- if (!Object.keys(info.instances).length) {
420
- delete this.form.fieldInfo[this.name];
421
- }
422
- };
423
- };
408
+ _defineProperty(this, "name", void 0);
409
+
410
+ _defineProperty(this, "store", void 0);
424
411
 
425
- Object.defineProperty(this, _updateStore, {
412
+ _defineProperty(this, "state", void 0);
413
+
414
+ _classPrivateFieldInitSpec(this, _prevState, {
426
415
  writable: true,
427
- value: () => {
416
+ value: void 0
417
+ });
418
+
419
+ _defineProperty(this, "options", {});
420
+
421
+ _defineProperty(this, "mount", () => {
422
+ var _this$options$onMount, _this$options;
423
+
424
+ const info = this.getInfo();
425
+ info.instances[this.uid] = this;
426
+ const unsubscribe = this.form.store.subscribe(() => {
428
427
  this.store.batch(() => {
429
428
  const nextValue = this.getValue();
430
429
  const nextMeta = this.getMeta();
@@ -441,17 +440,25 @@ class FieldApi {
441
440
  }));
442
441
  }
443
442
  });
444
- }
443
+ });
444
+ (_this$options$onMount = (_this$options = this.options).onMount) == null ? void 0 : _this$options$onMount.call(_this$options, this);
445
+ return () => {
446
+ unsubscribe();
447
+ delete info.instances[this.uid];
448
+
449
+ if (!Object.keys(info.instances).length) {
450
+ delete this.form.fieldInfo[this.name];
451
+ }
452
+ };
445
453
  });
446
454
 
447
- this.update = opts => {
448
- var _this$form$options$de, _this$form$options$de2, _this$form$options$de3, _this$form$options$de4;
455
+ _defineProperty(this, "update", opts => {
456
+ var _this$form$options$as, _this$form$options$on, _this$form$options$on2;
449
457
 
450
458
  this.options = {
451
- validatePristine: (_this$form$options$de = this.form.options.defaultValidatePristine) != null ? _this$form$options$de : false,
452
- validateOn: (_this$form$options$de2 = this.form.options.defaultValidateOn) != null ? _this$form$options$de2 : 'change',
453
- validateAsyncOn: (_this$form$options$de3 = this.form.options.defaultValidateAsyncOn) != null ? _this$form$options$de3 : 'blur',
454
- validateAsyncDebounceMs: (_this$form$options$de4 = this.form.options.defaultValidateAsyncDebounceMs) != null ? _this$form$options$de4 : 0,
459
+ asyncDebounceMs: (_this$form$options$as = this.form.options.asyncDebounceMs) != null ? _this$form$options$as : 0,
460
+ onChangeAsyncDebounceMs: (_this$form$options$on = this.form.options.onChangeAsyncDebounceMs) != null ? _this$form$options$on : 0,
461
+ onBlurAsyncDebounceMs: (_this$form$options$on2 = this.form.options.onBlurAsyncDebounceMs) != null ? _this$form$options$on2 : 0,
455
462
  ...opts
456
463
  }; // Default Value
457
464
 
@@ -464,44 +471,42 @@ class FieldApi {
464
471
  if (this.getMeta() === undefined) {
465
472
  this.setMeta(this.state.meta);
466
473
  }
467
- };
474
+ });
468
475
 
469
- this.getValue = () => {
476
+ _defineProperty(this, "getValue", () => {
470
477
  return this.form.getFieldValue(this.name);
471
- };
478
+ });
472
479
 
473
- this.setValue = (updater, options) => this.form.setFieldValue(this.name, updater, options);
480
+ _defineProperty(this, "setValue", (updater, options) => this.form.setFieldValue(this.name, updater, options));
474
481
 
475
- this.getMeta = () => this.form.getFieldMeta(this.name);
482
+ _defineProperty(this, "getMeta", () => this.form.getFieldMeta(this.name));
476
483
 
477
- this.setMeta = updater => this.form.setFieldMeta(this.name, updater);
484
+ _defineProperty(this, "setMeta", updater => this.form.setFieldMeta(this.name, updater));
478
485
 
479
- this.getInfo = () => this.form.getFieldInfo(this.name);
486
+ _defineProperty(this, "getInfo", () => this.form.getFieldInfo(this.name));
480
487
 
481
- this.pushValue = value => this.form.pushFieldValue(this.name, value);
488
+ _defineProperty(this, "pushValue", value => this.form.pushFieldValue(this.name, value));
482
489
 
483
- this.insertValue = (index, value) => this.form.insertFieldValue(this.name, index, value);
490
+ _defineProperty(this, "insertValue", (index, value) => this.form.insertFieldValue(this.name, index, value));
484
491
 
485
- this.removeValue = index => this.form.removeFieldValue(this.name, index);
492
+ _defineProperty(this, "removeValue", index => this.form.removeFieldValue(this.name, index));
486
493
 
487
- this.swapValues = (aIndex, bIndex) => this.form.swapFieldValues(this.name, aIndex, bIndex);
494
+ _defineProperty(this, "swapValues", (aIndex, bIndex) => this.form.swapFieldValues(this.name, aIndex, bIndex));
488
495
 
489
- this.getSubField = name => new FieldApi({
496
+ _defineProperty(this, "getSubField", name => new FieldApi({
490
497
  name: this.name + "." + name,
491
498
  form: this.form
492
- });
499
+ }));
493
500
 
494
- this.validateSync = async (value = this.state.value) => {
501
+ _defineProperty(this, "validateSync", async (value = this.state.value, cause) => {
495
502
  const {
496
- validate
503
+ onChange,
504
+ onBlur
497
505
  } = this.options;
498
-
499
- if (!validate) {
500
- return;
501
- } // Use the validationCount for all field instances to
506
+ const validate = cause === 'submit' ? undefined : cause === 'change' ? onChange : onBlur;
507
+ if (!validate) return; // Use the validationCount for all field instances to
502
508
  // track freshness of the validation
503
509
 
504
-
505
510
  const validationCount = (this.getInfo().validationCount || 0) + 1;
506
511
  this.getInfo().validationCount = validationCount;
507
512
  const error = normalizeError(validate(value, this));
@@ -516,9 +521,9 @@ class FieldApi {
516
521
  if (this.state.meta.error) {
517
522
  this.cancelValidateAsync();
518
523
  }
519
- };
524
+ });
520
525
 
521
- Object.defineProperty(this, _leaseValidateAsync, {
526
+ _classPrivateFieldInitSpec(this, _leaseValidateAsync, {
522
527
  writable: true,
523
528
  value: () => {
524
529
  const count = (this.getInfo().validationAsyncCount || 0) + 1;
@@ -527,32 +532,36 @@ class FieldApi {
527
532
  }
528
533
  });
529
534
 
530
- this.cancelValidateAsync = () => {
535
+ _defineProperty(this, "cancelValidateAsync", () => {
531
536
  // Lease a new validation count to ignore any pending validations
532
- _classPrivateFieldLooseBase(this, _leaseValidateAsync)[_leaseValidateAsync](); // Cancel any pending validation state
537
+ _classPrivateFieldGet(this, _leaseValidateAsync).call(this); // Cancel any pending validation state
533
538
 
534
539
 
535
540
  this.setMeta(prev => ({ ...prev,
536
541
  isValidating: false
537
542
  }));
538
- };
543
+ });
544
+
545
+ _defineProperty(this, "validateAsync", async (value = this.state.value, cause) => {
546
+ var _ref, _ref2;
539
547
 
540
- this.validateAsync = async (value = this.state.value) => {
541
548
  const {
542
- validateAsync,
543
- validateAsyncDebounceMs
549
+ onChangeAsync,
550
+ onBlurAsync,
551
+ onSubmitAsync,
552
+ asyncDebounceMs,
553
+ onBlurAsyncDebounceMs,
554
+ onChangeAsyncDebounceMs
544
555
  } = this.options;
545
-
546
- if (!validateAsync) {
547
- return;
548
- }
549
-
556
+ const validate = cause === 'change' ? onChangeAsync : cause === 'submit' ? onSubmitAsync : onBlurAsync;
557
+ if (!validate) return;
558
+ const debounceMs = cause === 'submit' ? 0 : (_ref = (_ref2 = cause === 'change' ? onChangeAsyncDebounceMs : onBlurAsyncDebounceMs) != null ? _ref2 : asyncDebounceMs) != null ? _ref : 500;
550
559
  if (this.state.meta.isValidating !== true) this.setMeta(prev => ({ ...prev,
551
560
  isValidating: true
552
561
  })); // Use the validationCount for all field instances to
553
562
  // track freshness of the validation
554
563
 
555
- const validationAsyncCount = _classPrivateFieldLooseBase(this, _leaseValidateAsync)[_leaseValidateAsync]();
564
+ const validationAsyncCount = _classPrivateFieldGet(this, _leaseValidateAsync).call(this);
556
565
 
557
566
  const checkLatest = () => validationAsyncCount === this.getInfo().validationAsyncCount;
558
567
 
@@ -563,14 +572,14 @@ class FieldApi {
563
572
  });
564
573
  }
565
574
 
566
- if (validateAsyncDebounceMs > 0) {
567
- await new Promise(r => setTimeout(r, validateAsyncDebounceMs));
575
+ if (debounceMs > 0) {
576
+ await new Promise(r => setTimeout(r, debounceMs));
568
577
  } // Only kick off validation if this validation is the latest attempt
569
578
 
570
579
 
571
580
  if (checkLatest()) {
572
581
  try {
573
- const rawError = await validateAsync(value, this);
582
+ const rawError = await validate(value, this);
574
583
 
575
584
  if (checkLatest()) {
576
585
  var _this$getInfo$validat, _this$getInfo;
@@ -601,43 +610,25 @@ class FieldApi {
601
610
 
602
611
 
603
612
  return this.getInfo().validationPromise;
604
- };
605
-
606
- this.shouldValidate = (isAsync, cause) => {
607
- const {
608
- validateOn,
609
- validateAsyncOn
610
- } = this.options;
611
- const level = getValidationCauseLevel(cause); // Must meet *at least* the validation level to validate,
612
- // e.g. if validateOn is 'change' and validateCause is 'blur',
613
- // the field will still validate
614
-
615
- return Object.keys(validateCauseLevels).some(d => isAsync ? validateAsyncOn : validateOn === d && level >= validateCauseLevels[d]);
616
- };
613
+ });
617
614
 
618
- this.validate = async (cause, value) => {
615
+ _defineProperty(this, "validate", (cause, value) => {
619
616
  // If the field is pristine and validatePristine is false, do not validate
620
- if (!this.options.validatePristine && !this.state.meta.isTouched) return; // Attempt to sync validate first
621
-
622
- if (this.shouldValidate(false, cause)) {
623
- this.validateSync(value);
624
- } // If there is an error, return it, do not attempt async validation
617
+ if (!this.state.meta.isTouched) return; // Attempt to sync validate first
625
618
 
619
+ this.validateSync(value, cause); // If there is an error, return it, do not attempt async validation
626
620
 
627
621
  if (this.state.meta.error) {
628
- return this.state.meta.error;
622
+ if (!this.options.asyncAlways) {
623
+ return this.state.meta.error;
624
+ }
629
625
  } // No error? Attempt async validation
630
626
 
631
627
 
632
- if (this.shouldValidate(true, cause)) {
633
- return this.validateAsync(value);
634
- } // If there is no sync error or async validation attempt, there is no error
635
-
636
-
637
- return undefined;
638
- };
628
+ return this.validateAsync(value, cause);
629
+ });
639
630
 
640
- this.getChangeProps = (props = {}) => {
631
+ _defineProperty(this, "getChangeProps", (props = {}) => {
641
632
  return { ...props,
642
633
  value: this.state.value,
643
634
  onChange: value => {
@@ -645,16 +636,21 @@ class FieldApi {
645
636
  props.onChange == null ? void 0 : props.onChange(value);
646
637
  },
647
638
  onBlur: e => {
639
+ const prevTouched = this.state.meta.isTouched;
648
640
  this.setMeta(prev => ({ ...prev,
649
641
  isTouched: true
650
642
  }));
643
+
644
+ if (!prevTouched) {
645
+ this.validate('change');
646
+ }
647
+
651
648
  this.validate('blur');
652
- props.onBlur == null ? void 0 : props.onBlur(e);
653
649
  }
654
650
  };
655
- };
651
+ });
656
652
 
657
- this.getInputProps = (props = {}) => {
653
+ _defineProperty(this, "getInputProps", (props = {}) => {
658
654
  return { ...props,
659
655
  value: String(this.state.value),
660
656
  onChange: e => {
@@ -663,7 +659,7 @@ class FieldApi {
663
659
  },
664
660
  onBlur: this.getChangeProps(props).onBlur
665
661
  };
666
- };
662
+ });
667
663
 
668
664
  this.form = _opts.form;
669
665
  this.uid = uid++; // Support field prefixing from FieldScope
@@ -682,31 +678,27 @@ class FieldApi {
682
678
  ...this.options.defaultMeta
683
679
  }
684
680
  }, {
685
- onUpdate: next => {
686
- next.meta.touchedError = next.meta.isTouched ? next.meta.error : undefined; // Do not validate pristine fields
687
-
688
- const prevState = this.state;
689
- this.state = next;
681
+ onUpdate: () => {
682
+ const state = this.store.state;
683
+ state.meta.touchedError = state.meta.isTouched ? state.meta.error : undefined;
690
684
 
691
- if (next.value !== prevState.value) {
692
- this.validate('change', next.value);
685
+ if (state.value !== _classPrivateFieldGet(this, _prevState).value) {
686
+ this.validate('change', state.value);
693
687
  }
688
+
689
+ _classPrivateFieldSet(this, _prevState, state);
690
+
691
+ this.state = state;
694
692
  }
695
693
  });
696
694
  this.state = this.store.state;
695
+
696
+ _classPrivateFieldSet(this, _prevState, this.state);
697
+
697
698
  this.update(_opts);
698
699
  }
699
700
 
700
701
  }
701
- const validateCauseLevels = {
702
- change: 0,
703
- blur: 1,
704
- submit: 2
705
- };
706
-
707
- function getValidationCauseLevel(cause) {
708
- return !cause ? 3 : validateCauseLevels[cause];
709
- }
710
702
 
711
703
  function normalizeError(rawError) {
712
704
  if (rawError) {