/* eslint-disable no-underscore-dangle */ /* eslint-disable import/no-unresolved */ import Visibility from '@mui/icons-material/Visibility' import VisibilityOff from '@mui/icons-material/VisibilityOff' import IconButton from '@mui/material/IconButton' import InputAdornment from '@mui/material/InputAdornment' import MenuItem from '@mui/material/MenuItem' import TextField from '@mui/material/TextField' import { useTheme } from '@mui/styles' import { FieldInputProps, FormikProps } from 'formik' import _get from 'lodash/get' import _includes from 'lodash/includes' import _isFunction from 'lodash/isFunction' import _isObject from 'lodash/isObject' import _map from 'lodash/map' import React, { useEffect, useRef, useState } from 'react' export interface ISelectOption { label: string | number; value?: string | number; [key: string]: any; } export interface ICustomField { onChange?: (e: React.ChangeEvent) => void; label: string; field: FieldInputProps; form: FormikProps; theme: 'dark' | 'light'; // optional type?: string; selectOptions?: ISelectOption[]; inputRef?: | { current: HTMLInputElement | null } | ((node: HTMLInputElement | null) => void); multiline?: boolean; minRows?: string | number; maxRows?: string | number; } export interface IOtherProps { [key: string]: any; } export const CustomField = ({ label, type = 'text', field, selectOptions = [] as ISelectOption[], form: { touched, errors, submitCount }, theme, inputProps: pInputProps = {}, InputProps = {}, inputRef, onChange, multiline = false, minRows = 3, maxRows, disabled, }: ICustomField & IOtherProps) => { const [isShrinked, setIsShrinked] = useState(Boolean(field.value)) const [showPassword, setShowPassword] = useState(false) const _ref = useRef(null) const isAutoFilled = _ref.current?.matches ? _ref.current?.matches(':-webkit-autofill') : false const isSelectField = type === 'select' const isPasswordField = type === 'password' const error = _get(errors, field.name) const isTouched = Boolean(_get(touched, field.name)) || (_includes(field.name, 'holder') && !!error && !!submitCount) const customTheme: any = useTheme() const inputProps: any = { sx: customTheme?.input } const handleClickShowPassword = () => { setShowPassword(!showPassword) } const handleMouseDownPassword = (event: React.MouseEvent) => { event.preventDefault() } const finalInputProps = isPasswordField ? { ...InputProps, endAdornment: ( {showPassword ? : } ), } : InputProps useEffect(() => { if (_isFunction(inputRef)) { inputRef(_ref.current) } else if (_isObject(inputRef)) { inputRef.current = _ref.current } }) return ( { setIsShrinked(true) }} SelectProps={{ native: false, className: theme, MenuProps: { className: theme, PaperProps: { sx: { '& .MuiMenuItem-root': { paddingLeft: '16px', paddingRight: '16px', }, }, }, }, }} InputLabelProps={{ sx: customTheme?.input, shrink: isSelectField || isShrinked || Boolean(field.value) || isAutoFilled, }} InputProps={finalInputProps} inputProps={{ ...inputProps, ...pInputProps }} inputRef={_ref} multiline={multiline} minRows={minRows} maxRows={maxRows} {...field} onBlur={(e: React.FocusEvent) => { setIsShrinked(Boolean(field.value)) if (field.onBlur) { field.onBlur(e) } }} onChange={onChange ?? field.onChange} > {isSelectField ? _map(selectOptions, option => ( {option.label} )) : null} ) }