import PropTypes from "prop-types"; import { forwardRef, useState } from "react"; import { useTheme } from "@emotion/react"; import { IconButton, InputAdornment, Stack, TextField, Typography } from "@mui/material"; import VisibilityOff from "@mui/icons-material/VisibilityOff"; import Visibility from "@mui/icons-material/Visibility"; import "./index.css"; /** * @param {Object} props * @param {string} [props.type] - Type of input field (e.g., 'text', 'password'). * @param {string} props.id - ID of the input field. * @param {string} props.name - Name of the input field. * @param {string} [props.label] - Label for the input field. * @param {boolean} [props.https] - Indicates if it should display http or https. * @param {boolean} [props.isRequired] - Indicates if the field is required, will display a red asterisk. * @param {boolean} [props.isOptional] - Indicates if the field is optional, will display optional text. * @param {string} [props.optionalLabel] - Optional label for the input field. * @param {string} [props.autoComplete] - Autocomplete value for the input field. * @param {string} [props.placeholder] - Placeholder text for the input field. * @param {string} props.value - Value of the input field. * @param {function} props.onChange - Function called on input change. * @param {string} [props.error] - Error message to display for the input field. * @param {boolean} [props.disabled] - Indicates if the input field is disabled. * @param {boolean} [props.hidden] - Indicates if the input field is hidden. * @param {React.Ref} [ref] - Ref forwarded to the underlying `TextField` component. Allows for direct interactions such as focusing. */ const Field = forwardRef( ( { type = "text", id, name, label, https, isRequired, isOptional, optionalLabel, autoComplete, placeholder, value, onChange, onBlur, onInput, error, disabled, hidden, }, ref ) => { const theme = useTheme(); const [isVisible, setVisible] = useState(false); return ( ), endAdornment: type === "password" && ( setVisible((show) => !show)} sx={{ color: theme.palette.border.dark, padding: theme.spacing(1), "&:focus-visible": { outline: `2px solid ${theme.palette.primary.main}`, outlineOffset: `2px`, }, "& .MuiTouchRipple-root": { pointerEvents: "none", display: "none", }, }} > {!isVisible ? : } ), }} /> {error && ( {error} )} ); } ); Field.displayName = "Field"; Field.propTypes = { type: PropTypes.oneOf(["text", "password", "url", "email", "description", "number"]), id: PropTypes.string.isRequired, name: PropTypes.string, label: PropTypes.string, https: PropTypes.bool, isRequired: PropTypes.bool, isOptional: PropTypes.bool, optionalLabel: PropTypes.string, autoComplete: PropTypes.string, placeholder: PropTypes.string, value: PropTypes.string.isRequired, onChange: PropTypes.func, onBlur: PropTypes.func, onInput: PropTypes.func, error: PropTypes.string, disabled: PropTypes.bool, hidden: PropTypes.bool, }; export default Field;