import * as React from 'react'; import { ReactNode } from 'react'; import { useWatch, useFormContext, FieldValues } from 'react-hook-form'; import get from 'lodash/get'; /** * Get the current (edited) value of the record from the form and pass it * to a child function * * @example * * const PostEdit = (props) => ( * * > * * * {({ formData, ...rest }) => formData.hasEmail && * * } * * * * ); * * @example * * const OrderEdit = (props) => ( * * * * > * {({ formData, ...rest }) => * * } * * * * ); */ const FormDataConsumer = ( props: ConnectedProps ) => { const { getValues } = useFormContext(); let formData = (useWatch() as unknown) as TFieldValues; //useWatch will initially return the provided defaultValues of the form. //We must get the initial formData from getValues if (Object.keys(formData).length === 0) { formData = getValues(); } return ( formData={formData} {...props} /> ); }; export const FormDataConsumerView = < TFieldValues extends FieldValues = FieldValues >( props: Props ) => { const { children, form, formData, source, index, ...rest } = props; let ret; // If we have an index, we are in an iterator like component (such as the SimpleFormIterator) if (typeof index !== 'undefined' && source) { const scopedFormData = get(formData, source); const getSource = (scopedSource: string) => `${source}.${scopedSource}`; ret = children({ formData, scopedFormData, getSource, ...rest }); } else { ret = children({ formData, ...rest }); } return ret === undefined ? null : ret; }; export default FormDataConsumer; export interface FormDataConsumerRenderParams< TFieldValues extends FieldValues = FieldValues > { formData: TFieldValues; scopedFormData?: any; getSource?: (source: string) => string; } export type FormDataConsumerRender< TFieldValues extends FieldValues = FieldValues > = (params: FormDataConsumerRenderParams) => ReactNode; interface ConnectedProps { children: FormDataConsumerRender; form?: string; record?: any; source?: string; [key: string]: any; } interface Props extends ConnectedProps { formData: TFieldValues; index?: number; }