@tanstack/form-core 1.27.7 → 1.28.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -62,7 +62,7 @@ export declare class FieldGroupApi<in out TFormData, in out TFieldGroupData, in
62
62
  /**
63
63
  * Validates a specified field in the form using the correct handlers for a given validation type.
64
64
  */
65
- validateField: <TField extends DeepKeys<TFieldGroupData>>(field: TField, cause: ValidationCause) => unknown[] | Promise<unknown[]>;
65
+ validateField: <TField extends DeepKeys<TFieldGroupData>>(field: TField, cause: ValidationCause) => any[] | Promise<any[]>;
66
66
  /**
67
67
  * Handles the form submission, performs validation, and calls the appropriate onSubmit or onSubmitInvalid callbacks.
68
68
  */
@@ -33,7 +33,6 @@ class FormApi {
33
33
  constructor(opts) {
34
34
  this.options = {};
35
35
  this.fieldInfo = {};
36
- this.prevTransformArray = [];
37
36
  this.mount = () => {
38
37
  const cleanupFieldMetaDerived = this.fieldMetaDerived.mount();
39
38
  const cleanupStoreDerived = this.store.mount();
@@ -96,12 +95,9 @@ class FormApi {
96
95
  if (!options) return;
97
96
  const oldOptions = this.options;
98
97
  this.options = options;
99
- const shouldUpdateReeval = !!options.transform?.deps?.some(
100
- (val, i) => val !== this.prevTransformArray[i]
101
- );
102
98
  const shouldUpdateValues = options.defaultValues && !utils.evaluate(options.defaultValues, oldOptions.defaultValues) && !this.state.isTouched;
103
99
  const shouldUpdateState = !utils.evaluate(options.defaultState, oldOptions.defaultState) && !this.state.isTouched;
104
- if (!shouldUpdateValues && !shouldUpdateState && !shouldUpdateReeval) return;
100
+ if (!shouldUpdateValues && !shouldUpdateState) return;
105
101
  store.batch(() => {
106
102
  this.baseStore.setState(
107
103
  () => getDefaultFormState(
@@ -111,8 +107,7 @@ class FormApi {
111
107
  shouldUpdateState ? options.defaultState : {},
112
108
  shouldUpdateValues ? {
113
109
  values: options.defaultValues
114
- } : {},
115
- shouldUpdateReeval ? { _force_re_eval: !this.state._force_re_eval } : {}
110
+ } : {}
116
111
  )
117
112
  )
118
113
  );
@@ -185,7 +180,15 @@ class FormApi {
185
180
  };
186
181
  this.validateField = (field, cause) => {
187
182
  const fieldInstance = this.fieldInfo[field]?.instance;
188
- if (!fieldInstance) return [];
183
+ if (!fieldInstance) {
184
+ const { hasErrored } = this.validateSync(cause);
185
+ if (hasErrored && !this.options.asyncAlways) {
186
+ return this.getFieldMeta(field)?.errors ?? [];
187
+ }
188
+ return this.validateAsync(cause).then(() => {
189
+ return this.getFieldMeta(field)?.errors ?? [];
190
+ });
191
+ }
189
192
  if (!fieldInstance.state.meta.isTouched) {
190
193
  fieldInstance.setMeta((prev) => ({ ...prev, isTouched: true }));
191
194
  }
@@ -858,12 +861,42 @@ class FormApi {
858
861
  };
859
862
  this._formId = opts?.formId ?? utils.uuid();
860
863
  this._devtoolsSubmissionOverride = false;
861
- this.baseStore = new store.Store(
862
- getDefaultFormState({
863
- ...opts?.defaultState,
864
- values: opts?.defaultValues ?? opts?.defaultState?.values
865
- })
866
- );
864
+ let baseStoreVal = getDefaultFormState({
865
+ ...opts?.defaultState,
866
+ values: opts?.defaultValues ?? opts?.defaultState?.values
867
+ });
868
+ if (opts?.transform) {
869
+ baseStoreVal = opts.transform({ state: baseStoreVal }).state;
870
+ for (const errKey of Object.keys(baseStoreVal.errorMap)) {
871
+ const errKeyMap = baseStoreVal.errorMap[errKey];
872
+ if (errKeyMap === void 0 || !utils.isGlobalFormValidationError(errKeyMap)) {
873
+ continue;
874
+ }
875
+ for (const fieldName of Object.keys(errKeyMap.fields)) {
876
+ const fieldErr = errKeyMap.fields[fieldName];
877
+ if (fieldErr === void 0) {
878
+ continue;
879
+ }
880
+ const existingFieldMeta = baseStoreVal.fieldMetaBase[fieldName];
881
+ baseStoreVal.fieldMetaBase[fieldName] = {
882
+ isTouched: false,
883
+ isValidating: false,
884
+ isBlurred: false,
885
+ isDirty: false,
886
+ ...existingFieldMeta ?? {},
887
+ errorSourceMap: {
888
+ ...existingFieldMeta?.["errorSourceMap"] ?? {},
889
+ onChange: "form"
890
+ },
891
+ errorMap: {
892
+ ...existingFieldMeta?.["errorMap"] ?? {},
893
+ [errKey]: fieldErr
894
+ }
895
+ };
896
+ }
897
+ }
898
+ }
899
+ this.baseStore = new store.Store(baseStoreVal);
867
900
  this.fieldMetaDerived = new store.Derived({
868
901
  deps: [this.baseStore],
869
902
  fn: ({ prevDepVals, currDepVals, prevVal: _prevVal }) => {
@@ -885,7 +918,7 @@ class FormApi {
885
918
  (val) => val !== void 0
886
919
  );
887
920
  const fieldInstance = this.getFieldInfo(fieldName)?.instance;
888
- if (fieldInstance && !fieldInstance.options.disableErrorFlat) {
921
+ if (!fieldInstance || !fieldInstance.options.disableErrorFlat) {
889
922
  fieldErrors = fieldErrors.flat(1);
890
923
  }
891
924
  }
@@ -976,7 +1009,7 @@ class FormApi {
976
1009
  if (prevVal && prevBaseStore && prevVal.errorMap === errorMap && prevVal.fieldMeta === this.fieldMetaDerived.state && prevVal.errors === errors && prevVal.isFieldsValidating === isFieldsValidating && prevVal.isFieldsValid === isFieldsValid && prevVal.isFormValid === isFormValid && prevVal.isValid === isValid && prevVal.canSubmit === canSubmit && prevVal.isTouched === isTouched && prevVal.isBlurred === isBlurred && prevVal.isPristine === isPristine && prevVal.isDefaultValue === isDefaultValue && prevVal.isDirty === isDirty && utils.evaluate(prevBaseStore, currBaseStore)) {
977
1010
  return prevVal;
978
1011
  }
979
- let state = {
1012
+ const state = {
980
1013
  ...currBaseStore,
981
1014
  errorMap,
982
1015
  fieldMeta: this.fieldMetaDerived.state,
@@ -992,14 +1025,6 @@ class FormApi {
992
1025
  isDefaultValue,
993
1026
  isDirty
994
1027
  };
995
- const transformArray = this.options.transform?.deps ?? [];
996
- const shouldTransform = transformArray.length !== this.prevTransformArray.length || transformArray.some((val, i) => val !== this.prevTransformArray[i]);
997
- if (shouldTransform) {
998
- const newObj = Object.assign({}, this, { state });
999
- this.options.transform?.fn(newObj);
1000
- state = newObj.state;
1001
- this.prevTransformArray = transformArray;
1002
- }
1003
1028
  return state;
1004
1029
  }
1005
1030
  });