From 13be9275aacac7c8d66fe9d1aeabc4e6175a0cc0 Mon Sep 17 00:00:00 2001 From: Sterling Camden Date: Wed, 22 Feb 2023 10:20:18 -0800 Subject: [PATCH] pass promise to handleSubmit to fix submit state tracking --- src/__tests__/createSchemaForm.test.tsx | 42 ++++++++++++++++++++++++- src/__tests__/utils/testForm.tsx | 6 ++++ src/createSchemaForm.tsx | 6 ++-- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/__tests__/createSchemaForm.test.tsx b/src/__tests__/createSchemaForm.test.tsx index 0f3e362..767708b 100644 --- a/src/__tests__/createSchemaForm.test.tsx +++ b/src/__tests__/createSchemaForm.test.tsx @@ -1,11 +1,12 @@ import React, { ReactNode, useState } from "react"; import { z } from "zod"; -import { render, screen } from "@testing-library/react"; +import { render, screen, waitFor } from "@testing-library/react"; import "@testing-library/jest-dom"; import { customFieldTestId, TestCustomFieldSchema, TestForm, + TestFormWithSubmit, textFieldTestId, } from "./utils/testForm"; import { @@ -539,6 +540,45 @@ describe("createSchemaForm", () => { expect(screen.getByDisplayValue(val)).toBeInTheDocument(); }); + it("should track submitting properly", async () => { + const testId = "id"; + const val = "true"; + let submitPromiseResolve : () => void = () => {}; + const submitPromise = new Promise((resolve) => { + submitPromiseResolve = resolve; + }) + let submitting =false; + function Component() { + const form = useForm({ + defaultValues: { + v: val, + }, + }); + submitting = form.formState.isSubmitting; + return ( + {return submitPromise}} + props={{ + v: { + testId: testId, + }, + }} + /> + ); + } + + render(); + const button = screen.getByText("submit"); + await userEvent.click(button); + expect(submitting).toBe(true); + submitPromiseResolve(); + waitFor(() => expect(submitting).toBe(false)); + }); + it("should throw an error if useTsController is called outside of a @ts-react/form rendered component", () => { // hello 100% test coverage =D jest.spyOn(console, "error").mockImplementation(() => {}); diff --git a/src/__tests__/utils/testForm.tsx b/src/__tests__/utils/testForm.tsx index ef37425..b3d987d 100644 --- a/src/__tests__/utils/testForm.tsx +++ b/src/__tests__/utils/testForm.tsx @@ -96,3 +96,9 @@ const propsMap = [ export const TestForm = createTsForm(mapping, { propsMap: propsMap, }); + +const FormWithSubmit = ({children,...props} : {children : JSX.Element[], onSubmit: () => void;}) =>
{children}
; +export const TestFormWithSubmit = createTsForm(mapping, { + propsMap: propsMap, + FormComponent: FormWithSubmit +}); diff --git a/src/createSchemaForm.tsx b/src/createSchemaForm.tsx index cba1c92..c9297d0 100644 --- a/src/createSchemaForm.tsx +++ b/src/createSchemaForm.tsx @@ -245,7 +245,7 @@ export function createTsForm< /** * A callback function that will be called with the data once the form has been submitted and validated successfully. */ - onSubmit: (values: z.infer) => void; + onSubmit: (values: z.infer) => void | Promise; /** * Initializes your form with default values. Is a deep partial, so all properties and nested properties are optional. */ @@ -377,10 +377,10 @@ export function createTsForm< } function _submit(data: z.infer) { - resolver(removeUndefined(data), {} as any, {} as any).then((e) => { + return resolver(removeUndefined(data), {} as any, {} as any).then(async (e) => { const errorKeys = Object.keys(e.errors); if (!errorKeys.length) { - onSubmit(data); + await onSubmit(data); return; } for (const key of errorKeys) {