From 557ab66b4af80b390975ec32f730282a4f578ebd Mon Sep 17 00:00:00 2001 From: Julian Schleemann Date: Wed, 14 Feb 2024 14:40:07 +0100 Subject: [PATCH] add docs --- README.md | 32 +++++++++++++++++++++++++++++++- src/formbuilder.test.tsx | 21 ++++++++++++--------- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index d6bfd5b..f2bbf67 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,36 @@ const AddressSubform: FC<{field: FormBuilder
}> = ({field}) => { } ``` +## Field arrays + +Fields which are typed as arrays provide a `$useFieldArray()` hook which can be used to map over the contents, as well +as mutate them using operations such as `append`, `insert`, `move` and `remove`. + +The `fields` returned by `$useFieldArray` are themselves `FormBuilder`s that can be registered on inputs or passed to +other Subform components. + +```tsx +import { FC } from "react"; + +const AddressesSubform: FC<{field: FormBuilder}> = ({field}) => { + const {fields, append} = field.$useFieldArray(); + const add = () => { + append({state: '', city: '', /* etc. */}); + } + return
+ {fields.map(f => )} + +
+} +``` + +The `$key` contains a unique id for the array item and must be passed as the `key` when [rendering the list](https://react.dev/learn/rendering-lists). + +Note: Field arrays are intended for use with arrays of objects. When dealing with arrays of primitives, you can either +wrap the primitive in an object, or use a controller (`$useController`) to implement your own array logic. + +For more information, see the React Hook Form docs on [`useFieldArray`](https://react-hook-form.com/docs/usefieldarray). + ## Compatibility with `useForm` Currently, `useFormBuilder` is almost compatible with `useForm`. This means you get the entire bag of tools provided by @@ -107,4 +137,4 @@ streamline this API and increase its type-safety. ## License -MIT \ No newline at end of file +MIT diff --git a/src/formbuilder.test.tsx b/src/formbuilder.test.tsx index add71fb..4708ed7 100644 --- a/src/formbuilder.test.tsx +++ b/src/formbuilder.test.tsx @@ -66,7 +66,7 @@ describe("useFormBuilder", () => { list: [ { id: "0", action: "frobnicate" }, { id: "1", action: "skedaddle" }, - ] + ], }; beforeAll(() => { @@ -159,7 +159,10 @@ describe("useFormBuilder", () => { await waitFor(() => { expect(watchedRoot).toHaveTextContent( - JSON.stringify({...defaultValues, person: {...defaultValues.person, firstName: "Joe"}}) + JSON.stringify({ + ...defaultValues, + person: { ...defaultValues.person, firstName: "Joe" }, + }) ); expect(watchedRoot).toHaveTextContent("Smith"); expect(watchedFirstName).toHaveTextContent("Joe"); @@ -231,17 +234,17 @@ describe("useFormBuilder", () => { const harness = createHarness({ defaultValues }, (builder) => { const { fields } = builder.fields.list.$useFieldArray(); - return
- { - fields.map((field, i) => ( + return ( +
+ {fields.map((field, i) => ( - )) - } -
+ ))} +
+ ); }); render(); @@ -250,5 +253,5 @@ describe("useFormBuilder", () => { expect(screen.getByLabelText("action-0")).toHaveValue("frobnicate"); expect(screen.getByLabelText("action-1")).toHaveValue("skedaddle"); }); - }) + }); });