frontPanel/src/ui_kit/CustomTextField.tsx

142 lines
3.3 KiB
TypeScript
Raw Normal View History

2023-12-25 12:02:35 +00:00
import React, { useEffect, useState } from "react";
import {
Box,
FormControl,
TextField,
Typography,
useTheme,
Input,
InputLabel,
2023-12-25 12:02:35 +00:00
} from "@mui/material";
2023-09-12 09:56:15 +00:00
import type { ChangeEvent, KeyboardEvent, FocusEvent } from "react";
import type { InputProps, SxProps, Theme } from "@mui/material";
interface CustomTextFieldProps {
2023-09-12 09:56:15 +00:00
placeholder: string;
2023-09-12 14:36:22 +00:00
value?: string;
2023-09-12 15:57:48 +00:00
error?: string;
2023-12-19 11:23:09 +00:00
emptyError?: boolean;
2023-09-12 09:56:15 +00:00
onChange?: (event: ChangeEvent<HTMLInputElement>) => void;
onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void;
onBlur?: (event: FocusEvent<HTMLInputElement>) => void;
text?: string;
maxLength?: number;
2023-09-12 09:56:15 +00:00
sx?: SxProps<Theme>;
sxForm?: SxProps<Theme>;
2023-10-12 15:51:39 +00:00
InputProps?: Partial<InputProps>;
2023-12-31 02:53:25 +00:00
type?: string;
rows?: number;
className?:string;
}
2023-09-12 09:56:15 +00:00
export default function CustomTextField({
placeholder,
2023-12-25 12:02:35 +00:00
value = "",
2023-09-12 09:56:15 +00:00
onChange,
onKeyDown,
onBlur,
text,
sx,
error,
2023-12-19 11:23:09 +00:00
emptyError,
2023-10-12 15:51:39 +00:00
InputProps,
maxLength = 200,
2023-12-31 02:53:25 +00:00
type = "",
rows = 0,
sxForm,
className
2023-09-12 09:56:15 +00:00
}: CustomTextFieldProps) {
const theme = useTheme();
2023-12-25 12:02:35 +00:00
const [inputValue, setInputValue] = useState("");
const [isInputActive, setIsInputActive] = useState(false);
2023-12-25 12:02:35 +00:00
useEffect(() => {
setInputValue(value);
}, [value]);
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const inputValue = event.target.value;
2023-12-31 02:53:25 +00:00
if (type === "number") {
setInputValue(inputValue.replace(/\D/g, ""));
} else {
setInputValue(inputValue);
}
if (onChange) {
onChange(event);
}
};
const handleInputFocus = () => {
setIsInputActive(true);
};
const handleInputBlur = (event: React.FocusEvent<HTMLInputElement>) => {
setIsInputActive(false);
if (onBlur) {
onBlur(event);
}
};
2023-09-12 09:56:15 +00:00
return (
<FormControl fullWidth variant="standard" sx={{ p: 0, ...sxForm }} className={className || ""}>
{error && (
<InputLabel
sx={{
fontSize: "13.5px",
marginTop: "3px",
}}
>
{error}
</InputLabel>
)}
<Input
2023-09-12 09:56:15 +00:00
defaultValue={text}
fullWidth
value={inputValue}
2023-09-12 09:56:15 +00:00
placeholder={placeholder}
onChange={handleInputChange}
2023-12-19 11:23:09 +00:00
error={!!error || emptyError}
onFocus={handleInputFocus}
onBlur={handleInputBlur}
2023-09-12 09:56:15 +00:00
onKeyDown={onKeyDown}
multiline={rows > 0}
rows={rows}
disableUnderline
2023-09-12 09:56:15 +00:00
sx={{
maxLength: maxLength,
borderRadius: "10px",
fontSize: "18px",
lineHeight: "21px",
p: "13px",
border: `${isInputActive ? "black 2px" : "#9A9AAF 1px"} solid`,
backgroundColor: theme.palette.background.default,
height: "48px",
...sx,
2023-09-12 09:56:15 +00:00
}}
2023-11-06 14:41:50 +00:00
data-cy="textfield"
2023-09-12 09:56:15 +00:00
/>
{isInputActive && inputValue.length >= maxLength - 7 && (
<Box
sx={{
display: "flex",
marginTop: "5px",
marginLeft: "auto",
position: "absolute",
bottom: "-25px",
right: "0",
}}
>
<Typography fontSize="14px">{inputValue.length}</Typography>
<span>/</span>
<Typography fontSize="14px">{maxLength}</Typography>
</Box>
)}
2023-09-12 09:56:15 +00:00
</FormControl>
);
}