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
* );
*
* @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 (
{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;
}