From 5b13c0f571901d5336a6af7efe6ead026b0b6b12 Mon Sep 17 00:00:00 2001 From: Alem Tuzlak Date: Tue, 15 Oct 2024 12:51:20 +0200 Subject: [PATCH] File array support and bug fix --- package.json | 2 +- src/hook/index.test.tsx | 44 ++++++++++++++++++++ src/hook/index.tsx | 59 ++++++++++++++------------- src/testing-app/app/routes/_index.tsx | 23 +++++++---- src/testing-app/package.json | 4 +- src/utilities/index.test.ts | 39 ++++++++++++++++++ src/utilities/index.ts | 10 +++++ 7 files changed, 143 insertions(+), 38 deletions(-) diff --git a/package.json b/package.json index a126e8d..bb85223 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "remix-hook-form", - "version": "5.1.0", + "version": "5.1.1", "description": "Utility wrapper around react-hook-form for use with Remix.run", "type": "module", "main": "./dist/index.cjs", diff --git a/src/hook/index.test.tsx b/src/hook/index.test.tsx index ecb4aea..2942700 100644 --- a/src/hook/index.test.tsx +++ b/src/hook/index.test.tsx @@ -280,7 +280,9 @@ describe("useRemixForm", () => { let streetFieldProps = result.current.register("address.street"); expect(nameFieldProps.defaultValue).toBe("Default name"); + expect(nameFieldProps.defaultChecked).toBe(undefined); expect(streetFieldProps.defaultValue).toBe("Default street"); + expect(streetFieldProps.defaultChecked).toBe(undefined); useActionDataMock.mockReturnValue({ defaultValues: { @@ -298,7 +300,49 @@ describe("useRemixForm", () => { streetFieldProps = result.current.register("address.street"); expect(nameFieldProps.defaultValue).toBe("Updated name"); + expect(nameFieldProps.defaultChecked).toBe(undefined); expect(streetFieldProps.defaultValue).toBe("Updated street"); + expect(streetFieldProps.defaultChecked).toBe(undefined); + }); + + it("should return defaultChecked from the register function when a boolean", async () => { + const { result, rerender } = renderHook(() => + useRemixForm({ + resolver: () => ({ + values: { name: "", address: { street: "" }, boolean: true }, + errors: {}, + }), + defaultValues: { + name: "Default name", + boolean: true, + address: { + street: "Default street", + }, + }, + }), + ); + + let booleanFieldProps = result.current.register("boolean"); + + expect(booleanFieldProps.defaultChecked).toBe(true); + expect(booleanFieldProps.defaultValue).toBe(undefined); + + useActionDataMock.mockReturnValue({ + defaultValues: { + name: "Updated name", + address: { + street: "Updated street", + }, + boolean: false, + }, + errors: { name: "Enter another name" }, + }); + + rerender(); + + booleanFieldProps = result.current.register("boolean"); + expect(booleanFieldProps.defaultChecked).toBe(false); + expect(booleanFieldProps.defaultValue).toBe(undefined); }); }); diff --git a/src/hook/index.tsx b/src/hook/index.tsx index 14136a3..a698abe 100644 --- a/src/hook/index.tsx +++ b/src/hook/index.tsx @@ -1,3 +1,12 @@ +import { + type FetcherWithComponents, + type FormEncType, + type FormMethod, + type SubmitFunction, + useActionData, + useNavigation, + useSubmit, +} from "@remix-run/react"; import React, { type FormEvent, type ReactNode, @@ -6,30 +15,21 @@ import React, { useState, } from "react"; import { - type FetcherWithComponents, - type SubmitFunction, - useActionData, - useSubmit, - useNavigation, - type FormEncType, - type FormMethod, -} from "@remix-run/react"; -import { - type SubmitErrorHandler, - type SubmitHandler, - useFormContext, - useForm, - FormProvider, - get, type DefaultValues, type FieldValues, + FormProvider, type FormState, type KeepStateOptions, type Path, type RegisterOptions, + type SubmitErrorHandler, + type SubmitHandler, type UseFormHandleSubmit, type UseFormProps, type UseFormReturn, + get, + useForm, + useFormContext, } from "react-hook-form"; import { createFormData } from "../utilities"; @@ -71,9 +71,7 @@ export const useRemixForm = ({ () => Boolean( (navigation.state !== "idle" && navigation.formData !== undefined) || - (fetcher && - fetcher.state !== "idle" && - fetcher.formData !== undefined), + (fetcher?.state !== "idle" && fetcher?.formData !== undefined), ), [navigation.state, navigation.formData, fetcher?.state, fetcher?.formData], ); @@ -180,16 +178,21 @@ export const useRemixForm = ({ options?: RegisterOptions & { disableProgressiveEnhancement?: boolean; }, - ) => ({ - ...methods.register(name, options), - ...(!options?.disableProgressiveEnhancement && { - defaultValue: - get(data?.defaultValues, name) ?? - get(methods.formState.defaultValues, name) ?? - "", - }), - }), - [methods.register, data?.defaultValues, methods.formState], + ) => { + const defaultValue = + get(data?.defaultValues, name) ?? + get(methods.formState.defaultValues, name); + return { + ...methods.register(name, options), + ...(!options?.disableProgressiveEnhancement && { + defaultValue: + typeof defaultValue === "string" ? defaultValue : undefined, + defaultChecked: + typeof defaultValue === "boolean" ? defaultValue : undefined, + }), + }; + }, + [methods.register, data?.defaultValues, methods.formState.defaultValues], ); const handleSubmit = useMemo( diff --git a/src/testing-app/app/routes/_index.tsx b/src/testing-app/app/routes/_index.tsx index 909bcc6..6e8ff95 100644 --- a/src/testing-app/app/routes/_index.tsx +++ b/src/testing-app/app/routes/_index.tsx @@ -1,20 +1,20 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { - json, type ActionFunctionArgs, - unstable_parseMultipartFormData, type LoaderFunctionArgs, type UploadHandler, + json, + unstable_parseMultipartFormData, } from "@remix-run/node"; import { Form, useFetcher } from "@remix-run/react"; import { useEffect } from "react"; import { + RemixFormProvider, + getFormDataFromSearchParams, getValidatedFormData, - useRemixForm, parseFormData, - getFormDataFromSearchParams, + useRemixForm, validateFormData, - RemixFormProvider, } from "remix-hook-form"; import { z } from "zod"; @@ -84,12 +84,21 @@ export default function Index() { }); const { register, handleSubmit, formState, watch, setError } = methods; - console.log(formState.errors); + const checkbox = watch("boolean"); + console.log(checkbox, typeof checkbox); return (

Add a thing...

-
+ + +