import React, { type ReactNode, useImperativeHandle, useRef } from 'react'; import { Box, InputAdornment, TextField, Typography, Stack, useMediaQuery, useTheme } from '@mui/material'; import get from 'lodash/get'; import { Controller, useFormContext } from 'react-hook-form'; import type { TextFieldProps } from '@mui/material'; import type { RegisterOptions } from 'react-hook-form'; import FormLabel from './label'; type InputProps = TextFieldProps & { name: string; label?: ReactNode; placeholder?: string; errorPosition?: 'right' | 'bottom'; rules?: RegisterOptions; wrapperStyle?: React.CSSProperties; required?: boolean; tooltip?: ReactNode | string; description?: ReactNode | string; layout?: 'vertical' | 'horizontal'; }; function FormInputError({ error }: { error: string }) { return ( {error} ); } export default function FormInput({ ref = undefined, name, label = '', placeholder = '', rules = {}, errorPosition = 'bottom', wrapperStyle = {}, inputProps = {}, required = false, tooltip = '', description = '', layout = 'vertical', slotProps, ...rest }: InputProps & { ref?: React.RefObject; inputProps?: TextFieldProps['inputProps']; }) { const { control, formState } = useFormContext(); const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down('sm')); const inputRef = useRef(null); useImperativeHandle(ref, () => { return inputRef.current as HTMLInputElement; }); const error = get(formState.errors, name)?.message as string; const isHorizontal = layout === 'horizontal' && !isMobile; const mergedSlotProps = { htmlInput: { ...inputProps, ...slotProps?.htmlInput }, input: Object.assign( rest.InputProps || {}, slotProps?.input || {}, errorPosition === 'right' && error ? { endAdornment: } : {} ), }; const renderLabel = () => { if (!label) return null; return ( {label} ); }; return ( ( {isHorizontal ? ( {renderLabel()} ) : ( <> {renderLabel()} )} )} /> ); }