diff --git a/.changeset/fix-4996-resetfield-undefined.md b/.changeset/fix-4996-resetfield-undefined.md new file mode 100644 index 000000000..c1f86fee2 --- /dev/null +++ b/.changeset/fix-4996-resetfield-undefined.md @@ -0,0 +1,5 @@ +--- +"vee-validate": patch +--- + +Fix resetField({ value: undefined }) preventing form from becoming valid (#4996) diff --git a/packages/vee-validate/src/useForm.ts b/packages/vee-validate/src/useForm.ts index f5e7329b8..0c477e236 100644 --- a/packages/vee-validate/src/useForm.ts +++ b/packages/vee-validate/src/useForm.ts @@ -779,6 +779,7 @@ export function useForm< const pathState = findPathState(field); if (pathState) { pathState.__flags.pendingReset = true; + pathState.validated = false; } setFieldInitialValue(field, deepCopy(newValue), true); @@ -790,6 +791,8 @@ export function useForm< if (pathState) { pathState.__flags.pendingReset = false; } + + validateField(field, { mode: 'silent' }); }); } diff --git a/packages/vee-validate/tests/useForm.spec.ts b/packages/vee-validate/tests/useForm.spec.ts index 09671b183..069417e2b 100644 --- a/packages/vee-validate/tests/useForm.spec.ts +++ b/packages/vee-validate/tests/useForm.spec.ts @@ -1489,4 +1489,54 @@ describe('useForm()', () => { form.setValues({ file: f2 }); expect(form.values.file).toEqual(f2); }); + + // #4996 + test('resetField with undefined value should not prevent form from becoming valid', async () => { + let form!: FormContext<{ name: string }>; + + mountWithHoc({ + setup() { + form = useForm({ + validationSchema: z.object({ + name: z.string().min(1), + }), + }); + + form.defineField('name'); + + return {}; + }, + template: ` +
+ `, + }); + + await flushPromises(); + + // Fill in a valid value and validate + form.setFieldValue('name', 'John'); + await flushPromises(); + + const pending1 = form.validate(); + await flushPromises(); + const result1 = await pending1; + expect(result1.valid).toBe(true); + expect(form.meta.value.valid).toBe(true); + + // Reset field with undefined value using form-level resetField + form.resetField('name', { value: undefined }); + await flushPromises(); + + // After reset, validated should be false so that subsequent validation works correctly + const pathState = form.getPathState('name'); + expect(pathState?.validated).toBe(false); + + // Now fill in a valid value again + form.setFieldValue('name', 'Jane'); + await flushPromises(); + + // The form should be valid again + expect(form.meta.value.valid).toBe(true); + expect(form.errors.value.name).toBeUndefined(); + }); });