import * as React from 'react'; import { ReactNode } from 'react'; import { FormProvider, FieldValues, UseFormProps, SubmitHandler, } from 'react-hook-form'; import { FormGroupsProvider } from './groups/FormGroupsProvider'; import { RaRecord } from '../types'; import { useRecordContext, OptionalRecordContextProvider, SaveHandler, } from '../controller'; import { SourceContextProvider, SourceContextValue, useResourceContext, } from '../core'; import { useCanBlock } from '../routing'; import { ValidateForm } from './validation/getSimpleValidationResolver'; import { WarnWhenUnsavedChanges } from './WarnWhenUnsavedChanges'; import { useAugmentedForm } from './useAugmentedForm'; /** * Creates a form element, initialized with the current record, calling the saveContext on submit * * Wrapper around react-hook-form's useForm, FormContextProvider, and
. * Also sets up a FormGroupContext, and handles submission validation. * * @example * * const MyForm = ({ record, defaultValues, validate }) => ( * * * * * *
* ); * * @typedef {Object} Props the props you can use * @prop {Object} defaultValues * @prop {Function} validate * @prop {Function} save * * @see useForm * @see FormGroupContext * * @link https://react-hook-form.com/docs/useformcontext */ export function Form(props: FormProps) { const { children, id, className, noValidate = false, formRootPathname, warnWhenUnsavedChanges, WarnWhenUnsavedChangesComponent = WarnWhenUnsavedChanges, } = props; const record = useRecordContext(props); const resource = useResourceContext(props); const { form, formHandleSubmit } = useAugmentedForm(props); const sourceContext = React.useMemo( () => ({ getSource: (source: string) => source, getLabel: (source: string) => `resources.${resource}.fields.${source}`, }), [resource] ); const canBlock = useCanBlock(); if ( warnWhenUnsavedChanges && !canBlock && process.env.NODE_ENV === 'development' ) { console.error( 'Cannot use the warnWhenUnsavedChanges feature outside of a DataRouter. ' + 'The warnWhenUnsavedChanges feature is disabled. ' + 'Remove the warnWhenUnsavedChanges prop or convert your custom router to a Data Router.' ); } return (
{children}
{warnWhenUnsavedChanges && canBlock && ( )}
); } export type FormProps = FormOwnProps & Omit< UseFormProps, 'onSubmit' | 'validate' > & { validate?: ValidateForm; noValidate?: boolean; WarnWhenUnsavedChangesComponent?: React.ComponentType<{ enable?: boolean; formRootPathName?: string; formControl?: any; }>; }; export interface FormOwnProps { children: ReactNode; className?: string; defaultValues?: any; formRootPathname?: string; id?: string; record?: Partial; resource?: string; onSubmit?: SubmitHandler | SaveHandler; warnWhenUnsavedChanges?: boolean; sanitizeEmptyValues?: boolean; disableInvalidFormNotification?: boolean; }