I make React datetime picker with MUI TextField every thing work properly but when I provide validation rule It's can not focus and highlight element with red border and I got error like image below
here is my custom component datetime picker
import { Controller, useForm, FieldValues, RegisterOptions, UseFormStateReturn } from 'react-hook-form'
import { IconButton, InputAdornment, TextField, useTheme } from '@mui/material'
import DatePicker, { ReactDatePickerProps, registerLocale } from 'react-datepicker'
import DatePickerWrapper from 'src/@core/styles/libs/react-datepicker'
import moment from 'moment'
import Icon from 'src/@core/components/icon'
import th from 'date-fns/locale/th'
registerLocale('th', th)
export const DateFormatSQL = `DD-MMM-YYYY`
export const DateFormatInput = `dd/MM/yyyy`
export const TimeFormat = `HH:mm:ss`
export enum DatetimeMode {
DATE,
DATETIME,
TIME
}
type Props = {
name: string
control?: any
label: string
id?: string
onChange?: (value: Date | null | string) => void
isClearAble?: boolean
mode?: DatetimeMode
popperPlacement?: ReactDatePickerProps['popperPlacement'] // Add this line
value?: Date
isReadOnly?: boolean
formState?: UseFormStateReturn<FieldValues>
validationRules?: RegisterOptions
disableValidate?: boolean
}
const DatetimePickerInput: React.FC<Props> = ({
label,
name,
control,
id = 'datePicker-controller',
isClearAble = false,
isReadOnly = false,
mode = DatetimeMode.DATE,
popperPlacement, // Add this prop
value = null,
onChange,
formState,
validationRules = null,
disableValidate = false
}) => {
const { control: formControl } = useForm()
const theme = useTheme()
const { direction } = theme
const _popperPlacement: ReactDatePickerProps['popperPlacement'] = direction === 'ltr' ? 'bottom-start' : 'bottom-end'
const timeFormat = ` ${TimeFormat}`
const formatSql = `${DateFormatSQL}${mode === DatetimeMode.DATETIME ? timeFormat : ''}`
const formatInput = `${DateFormatInput}${mode === DatetimeMode.DATETIME ? timeFormat : ''}`
const isRequiredValue = () => (validationRules?.required && !isReadOnly ? true : false)
const customTextFieldLabel = () => {
return (
<span>
{label}{' '}
{isRequiredValue() ? (
// <span
// style={{
// color: 'red',
// fontWeight: 'bold',
// verticalAlign: 'middle' // Align the asterisk in the middle vertically
// }}
// >
// **
// </span>
<></>
) : null}
</span>
)
}
return (
<DatePickerWrapper>
<Controller
name={name}
control={control || formControl}
defaultValue={''}
rules={validationRules && !disableValidate ? validationRules : {}}
render={({ field }) => {
return (
<DatePicker
{...field}
locale={'th'}
dateFormat={formatInput}
showTimeSelect={mode === DatetimeMode.DATETIME}
showTimeSelectOnly={mode === DatetimeMode.TIME}
timeIntervals={1}
timeFormat={timeFormat}
selected={field.value ? moment(field.value).toDate() : null}
isClearable={isClearAble}
readOnly={isReadOnly}
id={id}
popperPlacement={popperPlacement ?? _popperPlacement} // Pass down the prop
customInput={
<TextField
fullWidth
variant='outlined'
label={customTextFieldLabel()}
InputProps={{
size: 'small',
readOnly: true,
endAdornment: (
<InputAdornment position='end'>
<IconButton edge='end' onMouseDown={e => e.preventDefault()}>
<Icon icon={'tabler:calendar'} fontSize={20} />
</IconButton>
</InputAdornment>
)
}}
InputLabelProps={{
size: 'small'
}}
value={field.value ?? ''}
error={Boolean(formState?.errors[name])}
FormHelperTextProps={
formState && formState.errors[name] ? { style: { color: 'red', fontWeight: 'bold' } } : {}
}
helperText={formState && formState.errors[name] ? (formState!.errors[name]!.message as string) : ''}
/>
}
onChange={(date: Date) => {
const dateStr = moment(date).format(formatSql)
field.onChange(date ? dateStr : null)
if (onChange) onChange(dateStr ?? null)
}}
/>
)
}}
/>
</DatePickerWrapper>
)
}
export default DatetimePickerInput
It's seem Control can't pass ref to custiom element
anyone can help to fix this problem
thank you
here is how I user this component
<DatetimePickerInput
control={control}
name={propertyOf<ExpenseMemoForm>('useDate')}
label={'Date to use'}
formState={formState}
validationRules={{
required: 'requiered value'
}}
/>
