import { FileRejection } from 'react-dropzone'; import { FieldValues, useController, UseControllerProps } from 'react-hook-form'; import { isBoolean, isFunction, isString } from 'lodash'; import { useDefaultProps } from '../../hooks'; import { useLocalization } from '../../localization'; import { Upload } from '../upload'; import { UploadProps } from '../upload'; export type RHFUploadProps = Omit< UploadProps, 'onDrop' | 'onDelete' | 'onRemove' | 'onRemoveAll' | 'onUpload' | 'value' | 'disabled' | 'error' > & UseControllerProps & { onChange?: (value: TMultiple extends true ? File[] : File) => void; onUpload?: (value: TMultiple extends true ? File[] : File) => void; transform?: ( value: TMultiple extends true ? File[] : File ) => TMultiple extends true ? File[] | Promise : File | Promise; }; function RHFUpload( inProps: RHFUploadProps ) { const { /** React Hook Form */ name, rules, control, disabled, defaultValue, shouldUnregister, /** React Hook Form */ multiple = false, helperText, label, onChange, required, transform, onUpload: onUploadFromProps, ...other } = useDefaultProps({ name: 'ReevolveRHFUpload', props: inProps }); const { translate } = useLocalization(); const { field, fieldState: { error } } = useController({ name, control, defaultValue, disabled, shouldUnregister, rules: rules && { ...rules, required: rules?.required === true ? translate('validation.required', { label }) : rules?.required } }); function changeHandler(value: any) { field.onChange(value); onChange?.(value); } async function onDrop(acceptedFiles: File[], rejectionFiles: FileRejection[]) { if (rejectionFiles.length) { return; } let value = multiple ? [...(field.value ?? []), ...acceptedFiles] : acceptedFiles[0]; if (isFunction(transform)) { try { value = await transform(value as any); } catch { return; } } changeHandler(value); } return ( changeHandler(null)} onRemove={(file) => { changeHandler(field.value.filter((v: File) => v !== file)); }} onRemoveAll={() => changeHandler([])} {...(isFunction(onUploadFromProps) && { onUpload: () => { onUploadFromProps(field.value); } })} /> ); } declare module '@mui/material' { interface Components { ReevolveRHFUpload?: { defaultProps?: Partial; }; } } export default RHFUpload;