diff --git a/packages/forms/package.json b/packages/forms/package.json index 1e209d4202a3..b55ab6f567aa 100644 --- a/packages/forms/package.json +++ b/packages/forms/package.json @@ -24,7 +24,7 @@ "@babel/runtime-corejs3": "7.16.7", "core-js": "3.23.3", "pascalcase": "1.0.0", - "react-hook-form": "7.33.0" + "react-hook-form": "7.33.1" }, "devDependencies": { "@babel/cli": "7.16.7", diff --git a/packages/forms/src/FormError.tsx b/packages/forms/src/FormError.tsx index 18d6071b4bb4..7cf8665fd900 100644 --- a/packages/forms/src/FormError.tsx +++ b/packages/forms/src/FormError.tsx @@ -12,7 +12,7 @@ interface ServerError extends Error { result: Record } -interface RWGqlError { +export interface RWGqlError { message: string graphQLErrors: ReadonlyArray networkError: Error | ServerParseError | ServerError | null diff --git a/packages/forms/src/index.tsx b/packages/forms/src/index.tsx index 323932d68add..f9e322bd93e5 100644 --- a/packages/forms/src/index.tsx +++ b/packages/forms/src/index.tsx @@ -58,7 +58,7 @@ import { UseFormProps, } from 'react-hook-form' -import FormError from './FormError' +import FormError, { RWGqlError } from './FormError' /** * We slightly extend `react-hook-form`'s `RegisterOptions` to make working with GraphQL easier. @@ -484,19 +484,20 @@ interface ServerErrorsContextProps { const ServerErrorsContext = React.createContext({} as ServerErrorsContextProps) -export interface FormProps +export interface FormProps extends Omit, 'onSubmit'> { error?: any /** * The methods returned by `useForm`. - * This props's only necessary if you've called `useForm` yourself to get access to one of it's functions, like `reset`. + * This prop is only necessary if you've called `useForm` yourself to get + * access to one of its functions, like `reset`. * * @example * - * ```javascript - * const formMethods = useForm() + * ```typescript + * const formMethods = useForm() * - * const onSubmit = (data) => { + * const onSubmit = (data: FormData) => { * sendDataToServer(data) * formMethods.reset() * } @@ -506,7 +507,7 @@ export interface FormProps * ) * ``` */ - formMethods?: UseFormReturn + formMethods?: UseFormReturn /** * Configures how React Hook Form performs validation, among other things. * @@ -518,50 +519,59 @@ export interface FormProps * * @see {@link https://react-hook-form.com/api/useform} */ - config?: UseFormProps - onSubmit?: ( - value: Record, - event?: React.BaseSyntheticEvent - ) => void + config?: UseFormProps + onSubmit?: (value: TFieldValues, event?: React.BaseSyntheticEvent) => void } /** * Renders a `
` with the required context. */ -const Form = forwardRef( - ( - { - config, - error: errorProps, - formMethods: propFormMethods, - onSubmit, - children, - ...rest - }: FormProps, - ref: ForwardedRef - ) => { - const hookFormMethods = useForm(config) - const formMethods = propFormMethods || hookFormMethods +function FormInner( + { + config, + error: errorProps, + formMethods: propFormMethods, + onSubmit, + children, + ...rest + }: FormProps, + ref: ForwardedRef +) { + const hookFormMethods = useForm(config) + const formMethods = propFormMethods || hookFormMethods - return ( - - onSubmit?.(data, event) - )} + return ( + + onSubmit?.(data, event) + )} + > + - - {children} - - - ) - } -) + {children} + + + ) +} + +// Sorry about the `as` type assertion (type cast) here. Normally I'd redeclare +// forwardRef to only return a plain function, allowing us to use TypeScript's +// Higher-order Function Type Inference. But that gives us problems with the +// ForwardRefExoticComponent type we use for our InputComponents. So instead +// of changing that type (because it's correct) I use a type assertion here. +// forwardRef is notoriously difficult to use with UI component libs. +// Chakra-UI also says: +// > To be honest, the forwardRef type is quite complex [...] I'd recommend +// > that you cast the type +// https://github.com/chakra-ui/chakra-ui/issues/4528#issuecomment-902566185 +const Form = forwardRef(FormInner) as ( + props: FormProps & React.RefAttributes +) => React.ReactElement | null export interface LabelProps extends Pick, @@ -621,7 +631,7 @@ const DEFAULT_MESSAGES = { * * @example Displaying a validation error message with `` * - * `` doesnt render (i.e. returns `null`) when there's no error on ``. + * `` doesn't render (i.e. returns `null`) when there's no error on ``. * * ```jsx *