From a130394a841a2da397a0dd4ad006dbb4639e5065 Mon Sep 17 00:00:00 2001 From: IntelCore0607 Date: Mon, 29 May 2023 23:49:27 -0400 Subject: [PATCH 1/5] =?UTF-8?q?=E2=9C=A8=20feat(FieldArray):=20add=20field?= =?UTF-8?q?=20array=20context?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/form.ts | 15 +++++++++++++-- src/useFormContext.tsx | 18 +++++++++++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/types/form.ts b/src/types/form.ts index 4442ce46..74dd1114 100644 --- a/src/types/form.ts +++ b/src/types/form.ts @@ -4,7 +4,7 @@ import { Subject, Subscription } from '../utils/createSubject'; import { ErrorOption, FieldError, FieldErrors } from './errors'; import { EventType } from './events'; -import { FieldArray } from './fieldArray'; +import { FieldArray, UseFieldArrayReturn } from './fieldArray'; import { FieldRefs, FieldValue, @@ -838,10 +838,21 @@ export type UseWatchProps = { exact?: boolean; }; +export type FieldArrayContextProps = { + fieldArrays?: Record< + FieldArrayPath, + UseFieldArrayReturn + >; +}; + +export type FieldArrayContextReturn = + Required>; + export type FormProviderProps< TFieldValues extends FieldValues = FieldValues, TContext = any, TTransformedValues extends FieldValues | undefined = undefined, > = { children: React.ReactNode | React.ReactNode[]; -} & UseFormReturn; +} & UseFormReturn & + FieldArrayContextProps; diff --git a/src/useFormContext.tsx b/src/useFormContext.tsx index 17bdd2b9..057e49e9 100644 --- a/src/useFormContext.tsx +++ b/src/useFormContext.tsx @@ -1,6 +1,11 @@ import React from 'react'; -import { FieldValues, FormProviderProps, UseFormReturn } from './types'; +import { + FieldArrayContextReturn, + FieldValues, + FormProviderProps, + UseFormReturn, +} from './types'; const HookFormContext = React.createContext(null); @@ -36,12 +41,15 @@ const HookFormContext = React.createContext(null); */ export const useFormContext = < TFieldValues extends FieldValues, + // TODO: add missing a TContext type. We provide TransformedValues type as TContext to UseFormReturn, which is not correct. TransformedValues extends FieldValues | undefined = undefined, >(): UseFormReturn => + // TODO: we can probably get rid of the "as" cast here by providing a correct Context type to createContext React.useContext(HookFormContext) as UseFormReturn< TFieldValues, TransformedValues - >; + > & + FieldArrayContextReturn; /** * A provider component that propagates the `useForm` methods to all children components via [React Context](https://reactjs.org/docs/context.html) API. To be used with {@link useFormContext}. @@ -82,7 +90,11 @@ export const FormProvider = < ) => { const { children, ...data } = props; return ( - + + } + > {children} ); From e41c61a7d05fa63bd1ae6aefe003345369718b2c Mon Sep 17 00:00:00 2001 From: IntelCore0607 Date: Mon, 29 May 2023 23:50:25 -0400 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=94=A7=20chore:=20change=20config=20t?= =?UTF-8?q?o=20option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/__tests__/useForm/formState.test.tsx | 2 +- src/__tests__/useForm/setValue.test.tsx | 2 +- src/useForm.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/__tests__/useForm/formState.test.tsx b/src/__tests__/useForm/formState.test.tsx index 25ece874..3afe5684 100644 --- a/src/__tests__/useForm/formState.test.tsx +++ b/src/__tests__/useForm/formState.test.tsx @@ -667,7 +667,7 @@ describe('formState', () => { expect(dirtyFieldsState).toEqual({}); }); - describe('when delay config is set', () => { + describe('when delay option is set', () => { const message = 'required.'; it('should only show error after 500ms with register', async () => { diff --git a/src/__tests__/useForm/setValue.test.tsx b/src/__tests__/useForm/setValue.test.tsx index 1e0ae9a9..bdcfbf43 100644 --- a/src/__tests__/useForm/setValue.test.tsx +++ b/src/__tests__/useForm/setValue.test.tsx @@ -786,7 +786,7 @@ describe('setValue', () => { }); describe('with touched', () => { - it('should update touched with shouldTouched config', () => { + it('should update touched with shouldTouched option', () => { const App = () => { const { setValue, diff --git a/src/useForm.ts b/src/useForm.ts index 11a637d4..74bdf5f2 100644 --- a/src/useForm.ts +++ b/src/useForm.ts @@ -20,7 +20,7 @@ import { useSubscribe } from './useSubscribe'; * @remarks * [API](https://react-hook-form.com/api/useform) • [Demo](https://codesandbox.io/s/react-hook-form-get-started-ts-5ksmm) • [Video](https://www.youtube.com/watch?v=RkXv4AXXC_4) * - * @param props - form configuration and validation parameters. + * @param props - form options and validation parameters. * * @returns methods - individual functions to manage the form state. {@link UseFormReturn} * From ed53b46f818da36b022b01f685aa7f6061e251d3 Mon Sep 17 00:00:00 2001 From: IntelCore0607 Date: Mon, 29 May 2023 23:55:57 -0400 Subject: [PATCH 3/5] =?UTF-8?q?=E2=9C=85=20test(FieldArray):=20add=20field?= =?UTF-8?q?=20array=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/__tests__/useFormContext.test.tsx | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/__tests__/useFormContext.test.tsx b/src/__tests__/useFormContext.test.tsx index 3e28d84c..db0a77fc 100644 --- a/src/__tests__/useFormContext.test.tsx +++ b/src/__tests__/useFormContext.test.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { useController } from '../useController'; +import { useFieldArray } from '../useFieldArray'; import { useForm } from '../useForm'; import { FormProvider, useFormContext } from '../useFormContext'; import { useFormState } from '../useFormState'; @@ -229,4 +230,45 @@ describe('FormProvider', () => { await waitFor(() => screen.getByText('This is required')); }); + + it('should work correctly with field array', () => { + type FormValues = { + test: { name: string }[]; + }; + + const Test = () => { + const context = useFormContext(); + + return ( + <> + {context?.fieldArrays?.test.fields.map((field) => ( + + ))} + + ); + }; + + const App = () => { + const methods = useForm(); + const testField = useFieldArray({ + control: methods.control, + name: 'test', + }); + + return ( + +
+ + +
+ ); + }; + + render(); + }); }); From 75c91f5c0cac729657a88d225810c75863d0d285 Mon Sep 17 00:00:00 2001 From: IntelCore0607 Date: Tue, 30 May 2023 00:05:08 -0400 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=90=9B=20fix(FieldArray):=20add=20fie?= =?UTF-8?q?ld=20array=20context=20to=20context=20hook=20return=20type?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/useFormContext.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/useFormContext.tsx b/src/useFormContext.tsx index 057e49e9..3ef0eebe 100644 --- a/src/useFormContext.tsx +++ b/src/useFormContext.tsx @@ -43,7 +43,7 @@ export const useFormContext = < TFieldValues extends FieldValues, // TODO: add missing a TContext type. We provide TransformedValues type as TContext to UseFormReturn, which is not correct. TransformedValues extends FieldValues | undefined = undefined, ->(): UseFormReturn => +>(): UseFormReturn & FieldArrayContextReturn => // TODO: we can probably get rid of the "as" cast here by providing a correct Context type to createContext React.useContext(HookFormContext) as UseFormReturn< TFieldValues, From 162d2b62c38af944d8c8a17eb24c49a513b4a8e5 Mon Sep 17 00:00:00 2001 From: IntelCore0607 Date: Tue, 30 May 2023 00:29:58 -0400 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=93=9D=20docs(FieldArray):=20generate?= =?UTF-8?q?=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- reports/api-extractor.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/reports/api-extractor.md b/reports/api-extractor.md index 325066ab..1f30cb2a 100644 --- a/reports/api-extractor.md +++ b/reports/api-extractor.md @@ -171,6 +171,14 @@ export type Field = { // @public (undocumented) export type FieldArray = FieldArrayPath> = FieldArrayPathValue extends ReadonlyArray | null | undefined ? U : never; +// @public (undocumented) +export type FieldArrayContextProps = { + fieldArrays?: Record, UseFieldArrayReturn>; +}; + +// @public (undocumented) +export type FieldArrayContextReturn = Required>; + // @public export type FieldArrayMethodProps = { shouldFocus?: boolean; @@ -273,7 +281,7 @@ export const FormProvider: = { children: React_2.ReactNode | React_2.ReactNode[]; -} & UseFormReturn; +} & UseFormReturn & FieldArrayContextProps; // @public (undocumented) export type FormState = { @@ -621,7 +629,7 @@ export function useForm = (name?: FieldPath | FieldPath[] | readonly FieldPath[] | `root.${string}` | 'root') => void; // @public -export const useFormContext: () => UseFormReturn; +export const useFormContext: () => UseFormReturn & Required>; // @public export type UseFormGetFieldState = >(name: TFieldName, formState?: FormState) => {