// @flow strict import * as React from 'react'; import {classify} from '../../utils/classify'; import type {IconType} from '../Icon'; import {Icon} from '../Icon'; import {BodySmall, FormLabelSmall} from '../Text'; import css from './Input.module.css'; type ClassNames = $ReadOnly<{ box?: string, iconLeft?: string, iconRight?: string, }>; export const INPUT_TYPES = Object.freeze({ text: 'text', number: 'number', password: 'password', email: 'email', tel: 'tel', url: 'url', date: 'date', 'datetime-local': 'datetime-local', time: 'time', week: 'week', month: 'month', color: 'color', search: 'search', }); export type InputType = $Values; export type InputProps = { value?: string, onChange?: ( evt: SyntheticInputEvent, isEnter?: boolean, ) => mixed, classNames?: ClassNames, onFocus?: (e: SyntheticInputEvent) => mixed, onBlur?: (e: SyntheticInputEvent) => mixed, onKeyDown?: (e: SyntheticKeyboardEvent) => mixed, onPaste?: (e: ClipboardEvent) => mixed, onIconRightClick?: ?(SyntheticEvent) => mixed, onContainerClick?: ?(SyntheticEvent) => mixed, name?: string, disabled?: boolean, placeholder?: string, locked?: boolean, error?: boolean, errorText?: string, label?: string | React.Node, helperText?: string | React.Node, type?: InputType, size?: 'medium' | 'small', iconLeftName?: string, iconLeftType?: IconType, iconRightName?: string, iconRightType?: IconType, required?: boolean, readOnly?: boolean, boxRef?: (?HTMLElement) => mixed, minLength?: string, maxLength?: string, pattern?: string, min?: string, max?: string, /** The step attribute is a number that specifies the granularity that the value must adhere to, or the special value any. * Only values which are equal to the basis for stepping (min if specified, value otherwise, and an * appropriate default value if neither of those is provided) are valid. */ step?: string, ... }; const Input_ = (props: InputProps, ref): React.Node => { const { value, type, onChange, onFocus, onBlur, onIconRightClick, onContainerClick, name, disabled, placeholder, error, locked, errorText, label, helperText, classNames, size = 'medium', iconLeftName = '', iconLeftType = 'regular', iconRightName = '', iconRightType = 'regular', required, readOnly, boxRef, ...inputProps } = props; const [showPassword, setShowPassword] = React.useState(false); const controlledInputFilled = value !== ''; const handleRightIconClick = (e: SyntheticEvent) => { if (locked || disabled) { return; } if (type === 'password') { setShowPassword(!showPassword); } onIconRightClick && onIconRightClick(e); }; return (
{Boolean(label) && (
{label ?? ''}   {required && {'*'}}
)}
{iconLeftName && ( )} {type === 'color' && (
{value ? value : placeholder}
)}
{(Boolean(helperText) || error) && (
{error && errorText ? errorText : helperText ?? ''}
)}
); }; const RightInputIcon = ({ isEmail, isPassword, showPassword, isLocked, isDisabled, iconRightName, iconRightType, ...rightIconProps }: { isEmail?: boolean, isPassword?: boolean, showPassword?: boolean, isLocked?: boolean, isDisabled?: boolean, onClick?: ?(SyntheticEvent) => mixed, iconRightName?: string, iconRightType?: IconType, className?: string, }): React.Node => { if (isLocked) { return ( ); } if (isEmail) { return ( ); } if (isPassword) { return ( ); } if (iconRightName) { return ( ); } return <>; }; export const Input = (React.forwardRef( Input_, ): React$AbstractComponent);