Skip to content

Commit

Permalink
Add wasSubmitted to useFormActions and update useForm to expose…
Browse files Browse the repository at this point in the history
… it (#91)

* feat: add wasSubmitted to useFormActions and update useForm to expose it

* feat: expose wasSubmitted in useFormActions and reset it on form revert

* chore: adding changeset

* test: add tests for wasSubmitted state in useForm

* test: add test to persist wasSubmitted state on submission failure
  • Loading branch information
s8n11c authored Dec 29, 2024
1 parent 2c9180d commit 67cc35c
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/eleven-eagles-talk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@formwerk/core': minor
---

feat: Add `wasSubmitted` to `useForm`
43 changes: 43 additions & 0 deletions packages/core/src/useForm/useForm.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,49 @@ describe('form submit', () => {
await reset();
expect(submitAttemptsCount.value).toBe(0);
});

test('Can detect wether the form was submitted or not ', async () => {
const { wasSubmitted, handleSubmit } = await renderSetup(() => {
return useForm({ initialValues: { foo: 'bar' } });
});

const cb = vi.fn();
const onSubmit = handleSubmit(v => cb(v.toObject()));

expect(wasSubmitted.value).toBe(false);
await onSubmit(new Event('submit'));
expect(wasSubmitted.value).toBe(true);
});

test('Can reset the was submitted state', async () => {
const { wasSubmitted, handleSubmit, reset } = await renderSetup(() => {
return useForm({ initialValues: { foo: 'bar' } });
});

const cb = vi.fn();
const onSubmit = handleSubmit(v => cb(v.toObject()));

expect(wasSubmitted.value).toBe(false);
await onSubmit(new Event('submit'));
expect(wasSubmitted.value).toBe(true);
await reset();
expect(wasSubmitted.value).toBe(false);
});

test('Can persist the was submitted state when a submission fails', async () => {
const { wasSubmitted, handleSubmit } = await renderSetup(() => {
return useForm({ initialValues: { foo: 'bar' } });
});
try {
const cb = vi.fn(() => Promise.reject());
const onSubmit = handleSubmit(() => cb());

expect(wasSubmitted.value).toBe(false);
await onSubmit(new Event('submit'));
} catch {
expect(wasSubmitted.value).toBe(false);
}
});
});

describe('form dirty state', () => {
Expand Down
9 changes: 8 additions & 1 deletion packages/core/src/useForm/useForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,10 @@ export function useForm<
}

const transactionsManager = useFormTransactions(ctx);
const { actions, isSubmitting, submitAttemptsCount, ...privateActions } = useFormActions<TInput, TOutput>(ctx, {
const { actions, isSubmitting, submitAttemptsCount, wasSubmitted, ...privateActions } = useFormActions<
TInput,
TOutput
>(ctx, {
disabled,
schema: props?.schema as StandardSchema<TInput, TOutput>,
scrollToInvalidFieldOnSubmit: props?.scrollToInvalidFieldOnSubmit ?? true,
Expand Down Expand Up @@ -217,6 +220,10 @@ export function useForm<
* The number of times the form has been submitted, regardless of the form's validity.
*/
submitAttemptsCount,
/**
* Whether the form was submitted, which is true if the form was submitted and the submission was successful.
*/
wasSubmitted,
/**
* Whether the specified field is dirty.
*/
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/useForm/useFormActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export function useFormActions<TForm extends FormObject = FormObject, TOutput ex
) {
const isSubmitting = shallowRef(false);
const submitAttemptsCount = shallowRef(0);
const wasSubmitted = shallowRef(false);
const [dispatchSubmit, onSubmitAttempt] = createEventDispatcher<void>('submit');
const {
validate: _validate,
Expand Down Expand Up @@ -109,6 +110,7 @@ export function useFormActions<TForm extends FormObject = FormObject, TOutput ex

const result = await onSuccess(withConsumers(output), { event: e, form: e?.target as HTMLFormElement });
isSubmitting.value = false;
wasSubmitted.value = true;

return result;
};
Expand Down Expand Up @@ -144,6 +146,8 @@ export function useFormActions<TForm extends FormObject = FormObject, TOutput ex
form.setInitialTouched(state.touched, opts);
}

wasSubmitted.value = false;

form.revertValues();
form.revertTouched();
submitAttemptsCount.value = 0;
Expand Down Expand Up @@ -172,6 +176,7 @@ export function useFormActions<TForm extends FormObject = FormObject, TOutput ex
onValidationDone,
isSubmitting,
submitAttemptsCount,
wasSubmitted,
};
}

Expand Down

0 comments on commit 67cc35c

Please sign in to comment.