import { mdiEye, mdiEyeOff } from '@mdi/js'; import classnames from 'classnames'; import { Component, createRef, InputHTMLAttributes, ReactElement, RefObject, KeyboardEvent, } from 'react'; import withStyles, { WithStylesProps } from 'react-jss'; import { noop } from 'lodash'; import { observer } from 'mobx-react'; import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; import Icon from '../icon'; import { IFormField } from '../typings/generic'; import Error from '../error'; import Label from '../label'; import Wrapper from '../wrapper'; import { scorePasswordFunc } from './scorePassword'; import styles from './styles'; const messages = defineMessages({ passwordToggle: { id: 'settings.app.form.passwordToggle', defaultMessage: 'Password toggle', }, }); interface IData { [index: string]: string; } interface IProps extends InputHTMLAttributes, IFormField, WithStylesProps, WrappedComponentProps { focus?: boolean; prefix?: string; suffix?: string; scorePassword?: boolean; showPasswordToggle?: boolean; data?: IData; inputClassName?: string; onEnterKey?: () => {}; } interface IState { showPassword: boolean; passwordScore: number; } @observer class Input extends Component { private inputElement: RefObject = createRef(); constructor(props: IProps) { super(props); this.state = { passwordScore: 0, showPassword: false, }; } componentDidMount(): void { const { focus = false, data = {} } = this.props; if (this.inputElement && this.inputElement.current) { if (focus) { this.inputElement.current.focus(); } for (const key of Object.keys(data)) { this.inputElement.current.dataset[key] = data[key]; } } } onChange(e: React.ChangeEvent): void { const { scorePassword, onChange = noop } = this.props; onChange(e); if (scorePassword) { this.setState({ passwordScore: scorePasswordFunc(e.target.value), }); } } onInputKeyPress(e: KeyboardEvent): void { if (e.key === 'Enter') { const { onEnterKey = noop } = this.props; onEnterKey(); } } render(): ReactElement { const { classes, className, error, id, inputClassName, label, prefix, suffix, value, name, placeholder, spellCheck, min, max, step, required, noMargin, onBlur = noop, onFocus = noop, scorePassword = false, showLabel = true, showPasswordToggle = false, type = 'text', disabled = false, readOnly, intl, } = this.props; const { showPassword, passwordScore } = this.state; const inputType = type === 'password' && showPassword ? 'text' : type; return ( {label && showLabel && ( ); } } export default injectIntl(withStyles(styles, { injectTheme: true })(Input));