I create MUI TextField component and integration with 3rd party input mask libraries. Then I integrate my component with React Hook Form. Everything works as expected except that once I type any 1 character into the input, the input loses focus.
Here is the TextField component
import { TextFieldStyled } from "./styled";
import { CustomProps, InputTextProps } from "./type";
import React from "react";
import { IMaskInput } from "react-imask";
export const AppInputText = (props: InputTextProps) => {
const {
value,
patternOnPress,
onChange,
maxLength,
mask,
...restProps
} = props;
const TextMaskCustom = React.forwardRef<HTMLInputElement, CustomProps>(
function TextMaskCustom(props, ref) {
const { onChange, ...other } = props;
return (
<IMaskInput
{...other}
mask={mask}
definitions={{
'#': /[6,8,9]/,
}}
inputRef={ref}
onAccept={(value: any) => onChange({ target: { name: props.name, value } })}
overwrite
/>
);
},
);
const handleKeyDown = (event: any) => {
if (patternOnPress) {
if (!patternOnPress.test(event.key)
&& event.key !== "Backspace"
&& event.key !== "ArrowLeft"
&& event.key !== "ArrowRight"
) {
event.preventDefault();
}
}
};
return (
<TextFieldStyled
{...restProps}
inputProps={{
maxLength: maxLength,
}}
InputProps={{
inputComponent: mask ? TextMaskCustom as any : undefined,
}}
value={value}
onKeyDown={handleKeyDown}
onChange={onChange}
/>
);
}
Here is the React Hook Form
import { Controller } from "react-hook-form";
import { FormInputTextProps } from "./type";
import { FormContainer, LabelContainer, LabelStyled } from "../styled";
import { AppInputText } from "../../Input/InputText";
import React from "react";
import { AppInfoIcon } from "../../../custom/InfoIcon";
import Typography from "@mui/material/Typography";
import colors from "../../../../constant/colors";
export const FormInputText = React.forwardRef((props: FormInputTextProps, ref) => {
const {
name,
control,
label,
labelInfo,
placeholder,
direction = "vertical",
autoComplete,
required,
onChange: onChangeCallBack,
...restProps
} = props;
return (
<Controller
name={name}
control={control}
render={({
field: { onChange, value },
fieldState: { error }
}) => (
<FormContainer direction={direction}>
{label &&
<LabelContainer>
<LabelStyled>
{label}
{required &&
<Typography color={colors.LINE_ERROR}>*</Typography>
}
</LabelStyled>
{labelInfo &&
<AppInfoIcon info={labelInfo} />
}
</LabelContainer>
}
<AppInputText
{...restProps}
helperText={error ? error?.message : null}
error={!!error}
fullWidth
onChange={(event: any) => {
onChange(event);
onChangeCallBack?.(event);
}}
value={value}
placeholder={placeholder}
autoComplete={autoComplete ? name : "off"}
/>
</FormContainer>
)}
/>
);
});
How do I resolve this issue?