@tanstack/form-core
Advanced tools
Comparing version 0.20.2 to 0.20.3
@@ -86,3 +86,3 @@ import { Store } from '@tanstack/store'; | ||
pushValue: (value: TData extends any[] ? TData[number] : never) => void; | ||
insertValue: (index: number, value: TData extends any[] ? TData[number] : never) => void; | ||
insertValue: (index: number, value: TData extends any[] ? TData[number] : never) => Promise<void>; | ||
removeValue: (index: number, opts?: { | ||
@@ -89,0 +89,0 @@ touch: boolean; |
@@ -84,5 +84,3 @@ import { Store } from "@tanstack/store"; | ||
this.insertValue = (index, value) => this.form.insertFieldValue(this.name, index, value); | ||
this.removeValue = async (index, opts2) => { | ||
await this.form.removeFieldValue(this.name, index, opts2); | ||
}; | ||
this.removeValue = (index, opts2) => this.form.removeFieldValue(this.name, index, opts2); | ||
this.swapValues = (aIndex, bIndex) => this.form.swapFieldValues(this.name, aIndex, bIndex); | ||
@@ -89,0 +87,0 @@ this.getLinkedFields = (cause) => { |
@@ -96,2 +96,4 @@ import { Store } from '@tanstack/store'; | ||
validateAllFields: (cause: ValidationCause) => Promise<ValidationError[]>; | ||
validateArrayFieldsStartingFrom: <TField extends DeepKeys<TFormData>>(field: TField, index: number, cause: ValidationCause) => Promise<ValidationError[]>; | ||
validateField: <TField extends DeepKeys<TFormData>>(field: TField, cause: ValidationCause) => ValidationError[] | Promise<ValidationError[]>; | ||
validateSync: (cause: ValidationCause) => { | ||
@@ -117,3 +119,3 @@ hasErrored: boolean; | ||
touch?: boolean; | ||
}) => void; | ||
}) => Promise<void>; | ||
removeFieldValue: <TField extends DeepKeys<TFormData>>(field: TField, index: number, opts?: { | ||
@@ -120,0 +122,0 @@ touch?: boolean; |
@@ -110,2 +110,33 @@ import { Store } from "@tanstack/store"; | ||
}; | ||
this.validateArrayFieldsStartingFrom = async (field, index, cause) => { | ||
const currentValue = this.getFieldValue(field); | ||
const lastIndex = Array.isArray(currentValue) ? Math.max(currentValue.length - 1, 0) : null; | ||
const fieldKeysToValidate = [`${field}[${index}]`]; | ||
for (let i = index + 1; i <= (lastIndex ?? 0); i++) { | ||
fieldKeysToValidate.push(`${field}[${i}]`); | ||
} | ||
const fieldsToValidate = Object.keys(this.fieldInfo).filter( | ||
(fieldKey) => fieldKeysToValidate.some((key) => fieldKey.startsWith(key)) | ||
); | ||
const fieldValidationPromises = []; | ||
this.store.batch(() => { | ||
fieldsToValidate.forEach((nestedField) => { | ||
fieldValidationPromises.push( | ||
Promise.resolve().then(() => this.validateField(nestedField, cause)) | ||
); | ||
}); | ||
}); | ||
const fieldErrorMapMap = await Promise.all(fieldValidationPromises); | ||
return fieldErrorMapMap.flat(); | ||
}; | ||
this.validateField = (field, cause) => { | ||
var _a2; | ||
const fieldInstance = (_a2 = this.fieldInfo[field]) == null ? void 0 : _a2.instance; | ||
if (!fieldInstance) | ||
return []; | ||
if (!fieldInstance.state.meta.isTouched) { | ||
fieldInstance.setMeta((prev) => ({ ...prev, isTouched: true })); | ||
} | ||
return fieldInstance.validate(cause); | ||
}; | ||
this.validateSync = (cause) => { | ||
@@ -346,3 +377,3 @@ const validates = getSyncValidatorArray(cause, this.options); | ||
this.pushFieldValue = (field, value, opts2) => { | ||
return this.setFieldValue( | ||
this.setFieldValue( | ||
field, | ||
@@ -352,4 +383,5 @@ (prev) => [...Array.isArray(prev) ? prev : [], value], | ||
); | ||
this.validateField(field, "change"); | ||
}; | ||
this.insertFieldValue = (field, index, value, opts2) => { | ||
this.insertFieldValue = async (field, index, value, opts2) => { | ||
this.setFieldValue( | ||
@@ -364,2 +396,4 @@ field, | ||
); | ||
await this.validateField(field, "change"); | ||
await this.validateArrayFieldsStartingFrom(field, index, "change"); | ||
}; | ||
@@ -385,3 +419,4 @@ this.removeFieldValue = async (field, index, opts2) => { | ||
} | ||
await this.validateAllFields("change"); | ||
await this.validateField(field, "change"); | ||
await this.validateArrayFieldsStartingFrom(field, index, "change"); | ||
}; | ||
@@ -394,2 +429,5 @@ this.swapFieldValues = (field, index1, index2) => { | ||
}); | ||
this.validateField(field, "change"); | ||
this.validateField(`${field}[${index1}]`, "change"); | ||
this.validateField(`${field}[${index2}]`, "change"); | ||
}; | ||
@@ -401,2 +439,5 @@ this.moveFieldValues = (field, index1, index2) => { | ||
}); | ||
this.validateField(field, "change"); | ||
this.validateField(`${field}[${index1}]`, "change"); | ||
this.validateField(`${field}[${index2}]`, "change"); | ||
}; | ||
@@ -403,0 +444,0 @@ this.store = new Store( |
{ | ||
"name": "@tanstack/form-core", | ||
"version": "0.20.2", | ||
"version": "0.20.3", | ||
"description": "Powerful, type-safe, framework agnostic forms.", | ||
@@ -5,0 +5,0 @@ "author": "tannerlinsley", |
@@ -480,5 +480,4 @@ import { Store } from '@tanstack/store' | ||
removeValue = async (index: number, opts?: { touch: boolean }) => { | ||
await this.form.removeFieldValue(this.name, index, opts) | ||
} | ||
removeValue = (index: number, opts?: { touch: boolean }) => | ||
this.form.removeFieldValue(this.name, index, opts) | ||
@@ -485,0 +484,0 @@ swapValues = (aIndex: number, bIndex: number) => |
@@ -373,2 +373,55 @@ import { Store } from '@tanstack/store' | ||
validateArrayFieldsStartingFrom = async <TField extends DeepKeys<TFormData>>( | ||
field: TField, | ||
index: number, | ||
cause: ValidationCause, | ||
) => { | ||
const currentValue = this.getFieldValue(field) | ||
const lastIndex = Array.isArray(currentValue) | ||
? Math.max(currentValue.length - 1, 0) | ||
: null | ||
// We have to validate all fields that have shifted (at least the current field) | ||
const fieldKeysToValidate = [`${field}[${index}]`] | ||
for (let i = index + 1; i <= (lastIndex ?? 0); i++) { | ||
fieldKeysToValidate.push(`${field}[${i}]`) | ||
} | ||
// We also have to include all fields that are nested in the shifted fields | ||
const fieldsToValidate = Object.keys(this.fieldInfo).filter((fieldKey) => | ||
fieldKeysToValidate.some((key) => fieldKey.startsWith(key)), | ||
) as DeepKeys<TFormData>[] | ||
// Validate the fields | ||
const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any | ||
this.store.batch(() => { | ||
fieldsToValidate.forEach((nestedField) => { | ||
fieldValidationPromises.push( | ||
Promise.resolve().then(() => this.validateField(nestedField, cause)), | ||
) | ||
}) | ||
}) | ||
const fieldErrorMapMap = await Promise.all(fieldValidationPromises) | ||
return fieldErrorMapMap.flat() | ||
} | ||
validateField = <TField extends DeepKeys<TFormData>>( | ||
field: TField, | ||
cause: ValidationCause, | ||
) => { | ||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
const fieldInstance = this.fieldInfo[field]?.instance | ||
if (!fieldInstance) return [] | ||
// If the field is not touched (same logic as in validateAllFields) | ||
if (!fieldInstance.state.meta.isTouched) { | ||
// Mark it as touched | ||
fieldInstance.setMeta((prev) => ({ ...prev, isTouched: true })) | ||
} | ||
return fieldInstance.validate(cause) | ||
} | ||
// TODO: This code is copied from FieldApi, we should refactor to share | ||
@@ -693,3 +746,3 @@ validateSync = (cause: ValidationCause) => { | ||
) => { | ||
return this.setFieldValue( | ||
this.setFieldValue( | ||
field, | ||
@@ -699,5 +752,6 @@ (prev) => [...(Array.isArray(prev) ? prev : []), value] as any, | ||
) | ||
this.validateField(field, 'change') | ||
} | ||
insertFieldValue = <TField extends DeepKeys<TFormData>>( | ||
insertFieldValue = async <TField extends DeepKeys<TFormData>>( | ||
field: TField, | ||
@@ -719,2 +773,6 @@ index: number, | ||
) | ||
// Validate the whole array + all fields that have shifted | ||
await this.validateField(field, 'change') | ||
await this.validateArrayFieldsStartingFrom(field, index, 'change') | ||
} | ||
@@ -753,3 +811,5 @@ | ||
await this.validateAllFields('change') | ||
// Validate the whole array + all fields that have shifted | ||
await this.validateField(field, 'change') | ||
await this.validateArrayFieldsStartingFrom(field, index, 'change') | ||
} | ||
@@ -767,2 +827,8 @@ | ||
}) | ||
// Validate the whole array | ||
this.validateField(field, 'change') | ||
// Validate the swapped fields | ||
this.validateField(`${field}[${index1}]` as DeepKeys<TFormData>, 'change') | ||
this.validateField(`${field}[${index2}]` as DeepKeys<TFormData>, 'change') | ||
} | ||
@@ -779,2 +845,8 @@ | ||
}) | ||
// Validate the whole array | ||
this.validateField(field, 'change') | ||
// Validate the moved fields | ||
this.validateField(`${field}[${index1}]` as DeepKeys<TFormData>, 'change') | ||
this.validateField(`${field}[${index2}]` as DeepKeys<TFormData>, 'change') | ||
} | ||
@@ -781,0 +853,0 @@ } |
@@ -110,2 +110,31 @@ import { describe, expect, it, vi } from 'vitest' | ||
it('should run onChange validation when pushing an array fields value', async () => { | ||
const form = new FormApi({ | ||
defaultValues: { | ||
names: ['test'], | ||
}, | ||
}) | ||
form.mount() | ||
const field = new FieldApi({ | ||
form, | ||
name: 'names', | ||
validators: { | ||
onChange: ({ value }) => { | ||
if (value.length < 3) { | ||
return 'At least 3 names are required' | ||
} | ||
return | ||
}, | ||
}, | ||
}) | ||
field.mount() | ||
field.pushValue('other') | ||
expect(field.getMeta().errors).toStrictEqual([ | ||
'At least 3 names are required', | ||
]) | ||
}) | ||
it('should insert a value into an array value correctly', () => { | ||
@@ -128,2 +157,34 @@ const form = new FormApi({ | ||
it('should run onChange validation when inserting an array fields value', () => { | ||
const form = new FormApi({ | ||
defaultValues: { | ||
names: ['test'], | ||
}, | ||
}) | ||
form.mount() | ||
const field = new FieldApi({ | ||
form, | ||
name: 'names', | ||
validators: { | ||
onChange: ({ value }) => { | ||
if (value.length < 3) { | ||
return 'At least 3 names are required' | ||
} | ||
return | ||
}, | ||
}, | ||
defaultMeta: { | ||
isTouched: true, | ||
}, | ||
}) | ||
field.mount() | ||
field.insertValue(1, 'other') | ||
expect(field.getMeta().errors).toStrictEqual([ | ||
'At least 3 names are required', | ||
]) | ||
}) | ||
it('should remove a value from an array value correctly', () => { | ||
@@ -146,2 +207,34 @@ const form = new FormApi({ | ||
it('should run onChange validation when removing an array fields value', async () => { | ||
const form = new FormApi({ | ||
defaultValues: { | ||
names: ['test'], | ||
}, | ||
}) | ||
form.mount() | ||
const field = new FieldApi({ | ||
form, | ||
name: 'names', | ||
validators: { | ||
onChange: ({ value }) => { | ||
if (value.length < 3) { | ||
return 'At least 3 names are required' | ||
} | ||
return | ||
}, | ||
}, | ||
defaultMeta: { | ||
isTouched: true, | ||
}, | ||
}) | ||
field.mount() | ||
await field.removeValue(0) | ||
expect(field.getMeta().errors).toStrictEqual([ | ||
'At least 3 names are required', | ||
]) | ||
}) | ||
it('should remove a subfield from an array field correctly', async () => { | ||
@@ -275,2 +368,34 @@ const form = new FormApi({ | ||
it('should run onChange validation when swapping an array fields value', () => { | ||
const form = new FormApi({ | ||
defaultValues: { | ||
names: ['test', 'test2'], | ||
}, | ||
}) | ||
form.mount() | ||
const field = new FieldApi({ | ||
form, | ||
name: 'names', | ||
validators: { | ||
onChange: ({ value }) => { | ||
if (value.length < 3) { | ||
return 'At least 3 names are required' | ||
} | ||
return | ||
}, | ||
}, | ||
defaultMeta: { | ||
isTouched: true, | ||
}, | ||
}) | ||
field.mount() | ||
field.swapValues(0, 1) | ||
expect(field.getMeta().errors).toStrictEqual([ | ||
'At least 3 names are required', | ||
]) | ||
}) | ||
it('should move a value from an array value correctly', () => { | ||
@@ -293,2 +418,34 @@ const form = new FormApi({ | ||
it('should run onChange validation when moving an array fields value', () => { | ||
const form = new FormApi({ | ||
defaultValues: { | ||
names: ['test', 'test2'], | ||
}, | ||
}) | ||
form.mount() | ||
const field = new FieldApi({ | ||
form, | ||
name: 'names', | ||
validators: { | ||
onChange: ({ value }) => { | ||
if (value.length < 3) { | ||
return 'At least 3 names are required' | ||
} | ||
return | ||
}, | ||
}, | ||
defaultMeta: { | ||
isTouched: true, | ||
}, | ||
}) | ||
field.mount() | ||
field.moveValue(0, 1) | ||
expect(field.getMeta().errors).toStrictEqual([ | ||
'At least 3 names are required', | ||
]) | ||
}) | ||
it('should not throw errors when no meta info is stored on a field and a form re-renders', async () => { | ||
@@ -295,0 +452,0 @@ const form = new FormApi({ |
@@ -327,2 +327,21 @@ import { describe, expect, it, vi } from 'vitest' | ||
it("should run onChange validation when pushing an array field's value", () => { | ||
const form = new FormApi({ | ||
defaultValues: { | ||
names: ['test'], | ||
}, | ||
validators: { | ||
onChange: ({ value }) => | ||
value.names.length > 3 ? undefined : 'At least 3 names are required', | ||
}, | ||
}) | ||
form.mount() | ||
// Since validation runs through the field, a field must be mounted for that array | ||
new FieldApi({ form, name: 'names' }).mount() | ||
form.pushFieldValue('names', 'other') | ||
expect(form.state.errors).toStrictEqual(['At least 3 names are required']) | ||
}) | ||
it("should insert an array field's value", () => { | ||
@@ -340,2 +359,52 @@ const form = new FormApi({ | ||
it("should run onChange validation when inserting an array field's value", () => { | ||
const form = new FormApi({ | ||
defaultValues: { | ||
names: ['test'], | ||
}, | ||
validators: { | ||
onChange: ({ value }) => | ||
value.names.length > 3 ? undefined : 'At least 3 names are required', | ||
}, | ||
}) | ||
form.mount() | ||
// Since validation runs through the field, a field must be mounted for that array | ||
new FieldApi({ form, name: 'names' }).mount() | ||
form.insertFieldValue('names', 1, 'other') | ||
expect(form.state.errors).toStrictEqual(['At least 3 names are required']) | ||
}) | ||
it("should validate all shifted fields when inserting an array field's value", async () => { | ||
const form = new FormApi({ | ||
defaultValues: { | ||
names: [{ first: 'test' }, { first: 'test2' }], | ||
}, | ||
validators: { | ||
onChange: ({ value }) => | ||
value.names.length > 3 ? undefined : 'At least 3 names are required', | ||
}, | ||
}) | ||
form.mount() | ||
// Since validation runs through the field, a field must be mounted for that array | ||
new FieldApi({ form, name: 'names' }).mount() | ||
const field1 = new FieldApi({ | ||
form, | ||
name: 'names[0].first', | ||
defaultValue: 'test', | ||
validators: { | ||
onChange: ({ value }) => value !== 'test' && 'Invalid value', | ||
}, | ||
}) | ||
field1.mount() | ||
expect(field1.state.meta.errors).toStrictEqual([]) | ||
await form.insertFieldValue('names', 0, { first: 'other' }) | ||
expect(field1.state.meta.errors).toStrictEqual(['Invalid value']) | ||
}) | ||
it("should remove an array field's value", () => { | ||
@@ -353,2 +422,75 @@ const form = new FormApi({ | ||
it("should run onChange validation when removing an array field's value", () => { | ||
const form = new FormApi({ | ||
defaultValues: { | ||
names: ['test'], | ||
}, | ||
validators: { | ||
onChange: ({ value }) => | ||
value.names.length > 1 ? undefined : 'At least 1 name is required', | ||
}, | ||
}) | ||
form.mount() | ||
// Since validation runs through the field, a field must be mounted for that array | ||
new FieldApi({ form, name: 'names' }).mount() | ||
form.removeFieldValue('names', 0) | ||
expect(form.state.errors).toStrictEqual(['At least 1 name is required']) | ||
}) | ||
it("should validate following fields when removing an array field's value", async () => { | ||
const form = new FormApi({ | ||
defaultValues: { | ||
names: ['test', 'test2', 'test3'], | ||
}, | ||
validators: { | ||
onChange: ({ value }) => | ||
value.names.length > 1 ? undefined : 'At least 1 name is required', | ||
}, | ||
}) | ||
form.mount() | ||
// Since validation runs through the field, a field must be mounted for that array | ||
new FieldApi({ form, name: 'names' }).mount() | ||
const field1 = new FieldApi({ | ||
form, | ||
name: 'names[0]', | ||
defaultValue: 'test', | ||
validators: { | ||
onChange: ({ value }) => value !== 'test' && 'Invalid value', | ||
}, | ||
}) | ||
field1.mount() | ||
const field2 = new FieldApi({ | ||
form, | ||
name: 'names[1]', | ||
defaultValue: 'test2', | ||
validators: { | ||
onChange: ({ value }) => value !== 'test2' && 'Invalid value', | ||
}, | ||
}) | ||
field2.mount() | ||
const field3 = new FieldApi({ | ||
form, | ||
name: 'names[2]', | ||
defaultValue: 'test3', | ||
validators: { | ||
onChange: ({ value }) => value !== 'test3' && 'Invalid value', | ||
}, | ||
}) | ||
field3.mount() | ||
expect(field1.state.meta.errors).toStrictEqual([]) | ||
expect(field2.state.meta.errors).toStrictEqual([]) | ||
expect(field3.state.meta.errors).toStrictEqual([]) | ||
await form.removeFieldValue('names', 1) | ||
expect(field1.state.meta.errors).toStrictEqual([]) | ||
expect(field2.state.meta.errors).toStrictEqual(['Invalid value']) | ||
// This field does not exist anymore. Therefore, its validation should also not run | ||
expect(field3.state.meta.errors).toStrictEqual([]) | ||
}) | ||
it("should swap an array field's value", () => { | ||
@@ -361,2 +503,5 @@ const form = new FormApi({ | ||
form.mount() | ||
// Since validation runs through the field, a field must be mounted for that array | ||
new FieldApi({ form, name: 'names' }).mount() | ||
form.swapFieldValues('names', 1, 2) | ||
@@ -367,2 +512,134 @@ | ||
it("should run onChange validation when swapping an array field's value", () => { | ||
const form = new FormApi({ | ||
defaultValues: { | ||
names: ['test', 'test2'], | ||
}, | ||
validators: { | ||
onChange: ({ value }) => | ||
value.names.length > 3 ? undefined : 'At least 3 names are required', | ||
}, | ||
}) | ||
form.mount() | ||
// Since validation runs through the field, a field must be mounted for that array | ||
new FieldApi({ form, name: 'names' }).mount() | ||
expect(form.state.errors).toStrictEqual([]) | ||
form.swapFieldValues('names', 1, 2) | ||
expect(form.state.errors).toStrictEqual(['At least 3 names are required']) | ||
}) | ||
it('should run validation on swapped fields', () => { | ||
const form = new FormApi({ | ||
defaultValues: { | ||
names: ['test', 'test2'], | ||
}, | ||
validators: { | ||
onChange: ({ value }) => | ||
value.names.length > 3 ? undefined : 'At least 3 names are required', | ||
}, | ||
}) | ||
form.mount() | ||
// Since validation runs through the field, a field must be mounted for that array | ||
new FieldApi({ form, name: 'names' }).mount() | ||
const field1 = new FieldApi({ | ||
form, | ||
name: 'names[0]', | ||
defaultValue: 'test', | ||
validators: { | ||
onChange: ({ value }) => value !== 'test' && 'Invalid value', | ||
}, | ||
}) | ||
field1.mount() | ||
const field2 = new FieldApi({ | ||
form, | ||
name: 'names[1]', | ||
defaultValue: 'test2', | ||
}) | ||
field2.mount() | ||
expect(field1.state.meta.errors).toStrictEqual([]) | ||
expect(field2.state.meta.errors).toStrictEqual([]) | ||
form.swapFieldValues('names', 0, 1) | ||
expect(field1.state.meta.errors).toStrictEqual(['Invalid value']) | ||
expect(field2.state.meta.errors).toStrictEqual([]) | ||
}) | ||
it("should move an array field's value", () => { | ||
const form = new FormApi({ | ||
defaultValues: { | ||
names: ['one', 'two', 'three'], | ||
}, | ||
}) | ||
form.mount() | ||
form.moveFieldValues('names', 1, 2) | ||
expect(form.getFieldValue('names')).toStrictEqual(['one', 'three', 'two']) | ||
}) | ||
it("should run onChange validation when moving an array field's value", () => { | ||
const form = new FormApi({ | ||
defaultValues: { | ||
names: ['test', 'test2'], | ||
}, | ||
validators: { | ||
onChange: ({ value }) => | ||
value.names.length > 3 ? undefined : 'At least 3 names are required', | ||
}, | ||
}) | ||
form.mount() | ||
// Since validation runs through the field, a field must be mounted for that array | ||
new FieldApi({ form, name: 'names' }).mount() | ||
expect(form.state.errors).toStrictEqual([]) | ||
form.moveFieldValues('names', 0, 1) | ||
expect(form.state.errors).toStrictEqual(['At least 3 names are required']) | ||
}) | ||
it('should run validation on moved fields', () => { | ||
const form = new FormApi({ | ||
defaultValues: { | ||
names: ['test', 'test2'], | ||
}, | ||
validators: { | ||
onChange: ({ value }) => | ||
value.names.length > 3 ? undefined : 'At least 3 names are required', | ||
}, | ||
}) | ||
form.mount() | ||
// Since validation runs through the field, a field must be mounted for that array | ||
new FieldApi({ form, name: 'names' }).mount() | ||
const field1 = new FieldApi({ | ||
form, | ||
name: 'names[0]', | ||
defaultValue: 'test', | ||
validators: { | ||
onChange: ({ value }) => value !== 'test' && 'Invalid value', | ||
}, | ||
}) | ||
field1.mount() | ||
const field2 = new FieldApi({ | ||
form, | ||
name: 'names[1]', | ||
defaultValue: 'test2', | ||
}) | ||
field2.mount() | ||
expect(field1.state.meta.errors).toStrictEqual([]) | ||
expect(field2.state.meta.errors).toStrictEqual([]) | ||
form.swapFieldValues('names', 0, 1) | ||
expect(field1.state.meta.errors).toStrictEqual(['Invalid value']) | ||
expect(field2.state.meta.errors).toStrictEqual([]) | ||
}) | ||
it('should handle fields inside an array', async () => { | ||
@@ -1060,2 +1337,31 @@ interface Employee { | ||
it('should validate a single field consistently if touched', async () => { | ||
const form = new FormApi({ | ||
defaultValues: { | ||
firstName: '', | ||
lastName: '', | ||
}, | ||
}) | ||
const field = new FieldApi({ | ||
form, | ||
name: 'firstName', | ||
validators: { | ||
onChange: ({ value }) => | ||
value.length > 0 ? undefined : 'first name is required', | ||
}, | ||
defaultMeta: { | ||
isTouched: true, | ||
}, | ||
}) | ||
field.mount() | ||
form.mount() | ||
await form.validateField('firstName', 'change') | ||
expect(field.getMeta().errorMap.onChange).toEqual('first name is required') | ||
await form.validateField('firstName', 'change') | ||
expect(field.getMeta().errorMap.onChange).toEqual('first name is required') | ||
}) | ||
it('should show onSubmit errors', async () => { | ||
@@ -1062,0 +1368,0 @@ const form = new FormApi({ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
417585
7126