Skip to content

Commit

Permalink
feat: added handleReset fn on the form returns closes #141
Browse files Browse the repository at this point in the history
  • Loading branch information
logaretm committed Mar 2, 2025
1 parent 38a039d commit accc2e8
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/sour-plants-develop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@formwerk/core': patch
---

feat: added handleReset fn
62 changes: 62 additions & 0 deletions packages/core/src/useForm/useForm.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,68 @@ describe('form reset', () => {
expect(values).toEqual({ foo: 'baz' });
expect(isTouched('foo')).toBe(true);
});

test('handleReset creates a handler that resets the form and calls afterReset', async () => {
const afterResetMock = vi.fn();
const { values, handleReset, setValue } = await renderSetup(() => {
return useForm({ initialValues: { foo: 'bar' } });
});

setValue('foo', 'changed');
expect(values).toEqual({ foo: 'changed' });

const resetEvent = new Event('reset');
const preventDefaultSpy = vi.spyOn(resetEvent, 'preventDefault');

const resetHandler = handleReset(afterResetMock);
await resetHandler(resetEvent);

expect(preventDefaultSpy).toHaveBeenCalledOnce();
expect(values).toEqual({ foo: 'bar' });
expect(afterResetMock).toHaveBeenCalledOnce();
});

test('handleReset works without afterReset callback and without event', async () => {
const { values, handleReset, setValue } = await renderSetup(() => {
return useForm({ initialValues: { foo: 'bar' } });
});

setValue('foo', 'changed');
expect(values).toEqual({ foo: 'changed' });

const resetHandler = handleReset();
await resetHandler();

expect(values).toEqual({ foo: 'bar' });
});

test('handleReset can be used with a form element reset event', async () => {
const afterResetMock = vi.fn();

await render({
template: `
<form v-bind="formProps" data-testid="form">
<button type="reset">Reset</button>
</form>
`,
setup() {
const form = useForm({ initialValues: { foo: 'bar' } });
const formProps = {
...form.formProps,
onReset: form.handleReset(afterResetMock),
};

form.setValue('foo', 'changed');

return { formProps };
},
});

await fireEvent.click(screen.getByText('Reset'));
await flush();

expect(afterResetMock).toHaveBeenCalledOnce();
});
});

describe('form submit', () => {
Expand Down
19 changes: 19 additions & 0 deletions packages/core/src/useForm/useFormActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ export interface FormActions<TForm extends FormObject, TOutput extends FormObjec
handleSubmit: (
onSuccess: (payload: ConsumableData<TOutput>, ctx: SubmitContext) => MaybeAsync<void>,
) => (e?: Event) => Promise<void>;

/**
* Creates a reset handler for the form.
* @example
* ```ts
* const onReset = handleReset();
* ```
*/
handleReset: (afterReset?: () => MaybeAsync<void>) => (e?: Event) => Promise<void>;

/**
* Resets the form to its initial state.
*/
Expand Down Expand Up @@ -120,6 +130,14 @@ export function useFormActions<TForm extends FormObject = FormObject, TOutput ex
};
}

function handleReset(afterReset?: () => MaybeAsync<void>) {
return async function resetHandler(e?: Event) {
e?.preventDefault();
await reset();
await afterReset?.();
};
}

function updateSubmitValidationStateFromResult(errors: IssueCollection[]) {
form.clearSubmitErrors();
applySubmitErrors(errors);
Expand Down Expand Up @@ -182,6 +200,7 @@ export function useFormActions<TForm extends FormObject = FormObject, TOutput ex

const actions: FormActions<TForm, TOutput> = {
handleSubmit,
handleReset,
reset,
validate,
};
Expand Down

0 comments on commit accc2e8

Please sign in to comment.