/* eslint-disable react/display-name */ /* eslint-disable react-hooks/rules-of-hooks */ "use client"; import type { ForwardedRef, PropsWithChildren } from "react"; import { forwardRef, useCallback, useImperativeHandle } from "react"; import type { DefaultValues, FieldValues, SubmitHandler, UseFormReturn, ValidationMode, } from "react-hook-form"; import { FormProvider, useForm } from "react-hook-form"; export interface FormHandles { submit: VoidFunction; onlyValidate: VoidFunction; } interface Props extends PropsWithChildren { methods?: UseFormReturn; defaultValues?: DefaultValues; onSubmit: SubmitHandler; onChange?: (values: T) => void; mode?: keyof ValidationMode | undefined; shouldAutoScroll?: boolean; } export type SubmitFunction = SubmitHandler; const Form = ( props: Props, ref: ForwardedRef, ) => { const methods = // eslint-disable-next-line react-hooks/rules-of-hooks props.methods ?? useForm({ defaultValues: props.defaultValues, mode: props.mode ?? "onSubmit", }); const { formState: { errors }, trigger, } = methods; async function onSubmit() { if (props.shouldAutoScroll) { await trigger(); const firstErrorKey = Object.keys(errors)[0]; if (firstErrorKey) { const firstErrorElement = document.getElementById(firstErrorKey); if (firstErrorElement) { firstErrorElement.scrollIntoView({ behavior: "smooth", }); } } } methods.handleSubmit(props.onSubmit)(); } const handleChange = useCallback(() => { return props?.onChange?.(methods?.getValues()); }, [props, methods]); useImperativeHandle(ref, () => ({ submit: onSubmit, onlyValidate: methods.handleSubmit(() => {}), })); return (
setTimeout(() => handleChange(), 500)} autoComplete="none" > {props.children}
); }; export default forwardRef(Form) as ( props: Props & { ref?: ForwardedRef }, ) => ReturnType;