@tanstack/form-core 1.8.0 → 1.9.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.
package/src/FieldApi.ts CHANGED
@@ -652,6 +652,10 @@ export type FieldMetaDerived<
652
652
  * A flag that is `true` if the field's value has not been modified by the user. Opposite of `isDirty`.
653
653
  */
654
654
  isPristine: boolean
655
+ /**
656
+ * A boolean indicating if the field is valid. Evaluates `true` if there are no field errors.
657
+ */
658
+ isValid: boolean
655
659
  }
656
660
 
657
661
  export type AnyFieldMetaDerived = FieldMetaDerived<
@@ -1213,7 +1217,7 @@ export class FieldApi<
1213
1217
  */
1214
1218
  setMeta = (
1215
1219
  updater: Updater<
1216
- FieldMeta<
1220
+ FieldMetaBase<
1217
1221
  TParentData,
1218
1222
  TName,
1219
1223
  TData,
@@ -1667,17 +1671,24 @@ export class FieldApi<
1667
1671
  /**
1668
1672
  * Updates the field's errorMap
1669
1673
  */
1670
- setErrorMap(errorMap: ValidationErrorMap) {
1671
- this.setMeta(
1672
- (prev) =>
1673
- ({
1674
- ...prev,
1675
- errorMap: {
1676
- ...prev.errorMap,
1677
- ...errorMap,
1678
- },
1679
- }) as never,
1680
- )
1674
+ setErrorMap(
1675
+ errorMap: ValidationErrorMap<
1676
+ UnwrapFieldValidateOrFn<TName, TOnMount, TFormOnMount>,
1677
+ UnwrapFieldValidateOrFn<TName, TOnChange, TFormOnChange>,
1678
+ UnwrapFieldAsyncValidateOrFn<TName, TOnChangeAsync, TFormOnChangeAsync>,
1679
+ UnwrapFieldValidateOrFn<TName, TOnBlur, TFormOnBlur>,
1680
+ UnwrapFieldAsyncValidateOrFn<TName, TOnBlurAsync, TFormOnBlurAsync>,
1681
+ UnwrapFieldValidateOrFn<TName, TOnSubmit, TFormOnSubmit>,
1682
+ UnwrapFieldAsyncValidateOrFn<TName, TOnSubmitAsync, TFormOnSubmitAsync>
1683
+ >,
1684
+ ) {
1685
+ this.setMeta((prev) => ({
1686
+ ...prev,
1687
+ errorMap: {
1688
+ ...prev.errorMap,
1689
+ ...errorMap,
1690
+ },
1691
+ }))
1681
1692
  }
1682
1693
 
1683
1694
  /**
package/src/FormApi.ts CHANGED
@@ -607,7 +607,7 @@ export type DerivedFormState<
607
607
  */
608
608
  isFieldsValidating: boolean
609
609
  /**
610
- * A boolean indicating if all the form fields are valid.
610
+ * A boolean indicating if all the form fields are valid. Evaluates `true` if there are no field errors.
611
611
  */
612
612
  isFieldsValid: boolean
613
613
  /**
@@ -619,15 +619,15 @@ export type DerivedFormState<
619
619
  */
620
620
  isBlurred: boolean
621
621
  /**
622
- * A boolean indicating if any of the form's fields' values have been modified by the user. `True` if the user have modified at least one of the fields. Opposite of `isPristine`.
622
+ * A boolean indicating if any of the form's fields' values have been modified by the user. Evaluates `true` if the user have modified at least one of the fields. Opposite of `isPristine`.
623
623
  */
624
624
  isDirty: boolean
625
625
  /**
626
- * A boolean indicating if none of the form's fields' values have been modified by the user. `True` if the user have not modified any of the fields. Opposite of `isDirty`.
626
+ * A boolean indicating if none of the form's fields' values have been modified by the user. Evaluates `true` if the user have not modified any of the fields. Opposite of `isDirty`.
627
627
  */
628
628
  isPristine: boolean
629
629
  /**
630
- * A boolean indicating if the form and all its fields are valid.
630
+ * A boolean indicating if the form and all its fields are valid. Evaluates `true` if there are no errors.
631
631
  */
632
632
  isValid: boolean
633
633
  /**
@@ -911,12 +911,14 @@ export class FormApi<
911
911
  }
912
912
  }
913
913
 
914
- // As a primitive, we don't need to aggressively persist the same referential value for performance reasons
914
+ // As primitives, we don't need to aggressively persist the same referential value for performance reasons
915
915
  const isFieldPristine = !currBaseVal.isDirty
916
+ const isFieldValid = !isNonEmptyArray(fieldErrors ?? [])
916
917
 
917
918
  if (
918
919
  prevFieldInfo &&
919
920
  prevFieldInfo.isPristine === isFieldPristine &&
921
+ prevFieldInfo.isValid === isFieldValid &&
920
922
  prevFieldInfo.errors === fieldErrors &&
921
923
  currBaseVal === prevBaseVal
922
924
  ) {
@@ -929,6 +931,7 @@ export class FormApi<
929
931
  ...currBaseVal,
930
932
  errors: fieldErrors,
931
933
  isPristine: isFieldPristine,
934
+ isValid: isFieldValid,
932
935
  } as AnyFieldMeta
933
936
  }
934
937
 
@@ -963,31 +966,27 @@ export class FormApi<
963
966
  | undefined
964
967
  const prevBaseStore = prevDepVals?.[0]
965
968
  const currBaseStore = currDepVals[0]
969
+ const currFieldMeta = currDepVals[1]
966
970
 
967
971
  // Computed state
968
- const fieldMetaValues = Object.values(currBaseStore.fieldMetaBase) as (
969
- | AnyFieldMeta
970
- | undefined
971
- )[]
972
+ const fieldMetaValues = Object.values(currFieldMeta).filter(
973
+ Boolean,
974
+ ) as AnyFieldMeta[]
972
975
 
973
976
  const isFieldsValidating = fieldMetaValues.some(
974
- (field) => field?.isValidating,
977
+ (field) => field.isValidating,
975
978
  )
976
979
 
977
- const isFieldsValid = !fieldMetaValues.some(
978
- (field) =>
979
- field?.errorMap &&
980
- isNonEmptyArray(Object.values(field.errorMap).filter(Boolean)),
981
- )
980
+ const isFieldsValid = fieldMetaValues.every((field) => field.isValid)
982
981
 
983
- const isTouched = fieldMetaValues.some((field) => field?.isTouched)
984
- const isBlurred = fieldMetaValues.some((field) => field?.isBlurred)
982
+ const isTouched = fieldMetaValues.some((field) => field.isTouched)
983
+ const isBlurred = fieldMetaValues.some((field) => field.isBlurred)
985
984
 
986
985
  const shouldInvalidateOnMount =
987
986
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
988
- isTouched && currBaseStore?.errorMap?.onMount
987
+ isTouched && currBaseStore.errorMap?.onMount
989
988
 
990
- const isDirty = fieldMetaValues.some((field) => field?.isDirty)
989
+ const isDirty = fieldMetaValues.some((field) => field.isDirty)
991
990
  const isPristine = !isDirty
992
991
 
993
992
  const hasOnMountError = Boolean(
@@ -1845,7 +1844,7 @@ export class FormApi<
1845
1844
  */
1846
1845
  setFieldMeta = <TField extends DeepKeys<TFormData>>(
1847
1846
  field: TField,
1848
- updater: Updater<AnyFieldMeta>,
1847
+ updater: Updater<AnyFieldMetaBase>,
1849
1848
  ) => {
1850
1849
  this.baseStore.setState((prev) => {
1851
1850
  return {
@@ -2124,25 +2123,23 @@ export class FormApi<
2124
2123
  */
2125
2124
  setErrorMap(
2126
2125
  errorMap: ValidationErrorMap<
2127
- TOnMount,
2128
- TOnChange,
2129
- TOnChangeAsync,
2130
- TOnBlur,
2131
- TOnBlurAsync,
2132
- TOnSubmit,
2133
- TOnSubmitAsync
2126
+ UnwrapFormValidateOrFn<TOnMount>,
2127
+ UnwrapFormValidateOrFn<TOnChange>,
2128
+ UnwrapFormAsyncValidateOrFn<TOnChangeAsync>,
2129
+ UnwrapFormValidateOrFn<TOnBlur>,
2130
+ UnwrapFormAsyncValidateOrFn<TOnBlurAsync>,
2131
+ UnwrapFormValidateOrFn<TOnSubmit>,
2132
+ UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>,
2133
+ UnwrapFormAsyncValidateOrFn<TOnServer>
2134
2134
  >,
2135
2135
  ) {
2136
- this.baseStore.setState(
2137
- (prev) =>
2138
- ({
2139
- ...prev,
2140
- errorMap: {
2141
- ...prev.errorMap,
2142
- ...errorMap,
2143
- },
2144
- }) as never,
2145
- )
2136
+ this.baseStore.setState((prev) => ({
2137
+ ...prev,
2138
+ errorMap: {
2139
+ ...prev.errorMap,
2140
+ ...errorMap,
2141
+ },
2142
+ }))
2146
2143
  }
2147
2144
 
2148
2145
  /**
package/src/metaHelper.ts CHANGED
@@ -14,6 +14,7 @@ export const defaultFieldMeta: AnyFieldMeta = {
14
14
  isBlurred: false,
15
15
  isDirty: false,
16
16
  isPristine: true,
17
+ isValid: true,
17
18
  errors: [],
18
19
  errorMap: {},
19
20
  errorSourceMap: {},
package/src/utils.ts CHANGED
@@ -1,11 +1,11 @@
1
+ import type { FieldValidators } from './FieldApi'
2
+ import type { FormValidators } from './FormApi'
1
3
  import type {
2
4
  GlobalFormValidationError,
3
5
  ValidationCause,
4
6
  ValidationError,
5
7
  ValidationSource,
6
8
  } from './types'
7
- import type { FormValidators } from './FormApi'
8
- import type { AnyFieldMeta, FieldValidators } from './FieldApi'
9
9
 
10
10
  export type UpdaterFn<TInput, TOutput = TInput> = (input: TInput) => TOutput
11
11