From 8ae1f76a065a94375e2bf0143f8adcd981a63230 Mon Sep 17 00:00:00 2001 From: Welly Shen Date: Tue, 2 Mar 2021 18:12:31 +0800 Subject: [PATCH] Fix(useForm): single checkbox input with valid `value` attribute, the value will be a string array --- .changeset/angry-ducks-vanish.md | 5 +++ src/useForm.test.tsx | 54 ++++++++++++++++++++++++++------ src/useForm.ts | 14 +++++---- 3 files changed, 58 insertions(+), 15 deletions(-) create mode 100644 .changeset/angry-ducks-vanish.md diff --git a/.changeset/angry-ducks-vanish.md b/.changeset/angry-ducks-vanish.md new file mode 100644 index 00000000..d6b95eea --- /dev/null +++ b/.changeset/angry-ducks-vanish.md @@ -0,0 +1,5 @@ +--- +"react-cool-form": patch +--- + +Fix(useForm): single checkbox input with valid `value` attribute, the value will be a string array diff --git a/src/useForm.test.tsx b/src/useForm.test.tsx index 7b061bbe..da94ca06 100644 --- a/src/useForm.test.tsx +++ b/src/useForm.test.tsx @@ -662,7 +662,7 @@ describe("useForm", () => { describe("handle change", () => { it.each(["text", "number", "range"])( - "should handle %s change correctly", + "should handle %s correctly", async (type) => { renderHelper({ defaultValues: { foo: "" }, @@ -684,7 +684,7 @@ describe("useForm", () => { } ); - it("should handle checkbox change correctly", async () => { + it("should handle checkbox with boolean correctly", async () => { const { getState } = renderHelper({ defaultValues: { foo: false }, onSubmit, @@ -711,7 +711,43 @@ describe("useForm", () => { expect(getState("isDirty")).toBeFalsy(); }); - it("should handle checkboxes change correctly", async () => { + it.each(["valid", "invalid"])( + "should handle checkbox with array correctly", + async (type) => { + const value = "🍎"; + renderHelper({ + onSubmit, + children: ( + + ), + }); + const foo = getByTestId("foo"); + const form = getByTestId("form"); + + userEvent.click(foo); + fireEvent.submit(form); + await waitFor(() => + expect(onSubmit).toHaveBeenCalledWith({ + foo: type === "valid" ? [value] : foo.checked, + }) + ); + + userEvent.click(foo); + fireEvent.submit(form); + await waitFor(() => + expect(onSubmit).toHaveBeenCalledWith({ + foo: type === "valid" ? [] : foo.checked, + }) + ); + } + ); + + it("should handle checkboxes correctly", async () => { const { getState } = renderHelper({ defaultValues: { foo: [] }, onSubmit, @@ -754,7 +790,7 @@ describe("useForm", () => { expect(getState("isDirty")).toBeFalsy(); }); - it("should handle radio buttons change correctly", async () => { + it("should handle radio buttons correctly", async () => { renderHelper({ defaultValues: { foo: "" }, onSubmit, @@ -782,7 +818,7 @@ describe("useForm", () => { ); }); - it("should handle textarea change correctly", async () => { + it("should handle textarea correctly", async () => { renderHelper({ defaultValues: { foo: "" }, onSubmit, @@ -798,7 +834,7 @@ describe("useForm", () => { ); }); - it("should handle select change correctly", async () => { + it("should handle select correctly", async () => { renderHelper({ defaultValues: { foo: "🍎" }, onSubmit, @@ -833,7 +869,7 @@ describe("useForm", () => { ); }); - it("should handle multiple select change correctly", async () => { + it("should handle multiple select correctly", async () => { renderHelper({ defaultValues: { foo: [] }, onSubmit, @@ -880,7 +916,7 @@ describe("useForm", () => { await waitFor(() => expect(onSubmit).toHaveBeenCalledWith({ foo: [] })); }); - it("should handle file change correctly", async () => { + it("should handle file correctly", async () => { renderHelper({ defaultValues: { foo: null }, onSubmit, @@ -902,7 +938,7 @@ describe("useForm", () => { ); }); - it("should handle files change correctly", async () => { + it("should handle files correctly", async () => { renderHelper({ defaultValues: { foo: null }, onSubmit, diff --git a/src/useForm.ts b/src/useForm.ts index 9844e771..db81fc5b 100644 --- a/src/useForm.ts +++ b/src/useForm.ts @@ -188,13 +188,15 @@ export default ({ if (isCheckboxInput(field)) { const checkboxes = options as HTMLInputElement[]; + const checkbox = checkboxes[0]; - value = - checkboxes.length > 1 - ? checkboxes - .filter((checkbox) => checkbox.checked) - .map((checkbox) => checkbox.value) - : checkboxes[0].checked; + if (checkboxes.length > 1) { + value = checkboxes.filter((c) => c.checked).map((c) => c.value); + } else if (checkbox.hasAttribute("value") && checkbox.value) { + value = checkbox.checked ? [checkbox.value] : []; + } else { + value = checkbox.checked; + } } if (isRadioInput(field))