// @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, wrapper?: string, }>; export const EXPONENT_CHARACTER_LIST = ['E', 'e']; 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 InputOnChangeParamsType = { evt: SyntheticInputEvent, isEnter?: boolean, }; 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, autoComplete?: string, /* Note(Nishant): Restricts typing `e` and `E` in the number input when set to true. We have baked this condition in the keydown handler itself so this would restrict and not show these exponent characters when typed **/ disallowExponents?: boolean, /** 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, hideNumberSpinner?: boolean, hidePasswordToggleIcon?: boolean, ... }; 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, onKeyDown, disallowExponents, hideNumberSpinner, hidePasswordToggleIcon, ...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); }; const handleKeyDown = (e: SyntheticKeyboardEvent) => { if (type === INPUT_TYPES.number && disallowExponents) { if (EXPONENT_CHARACTER_LIST.includes(e.key)) { e.preventDefault(); } } onKeyDown?.(e); }; return (
{Boolean(label) && (
{label ?? ''}   {required && {'*'}}
)}
{iconLeftName && ( )} {type === 'color' && (
{value ? value : placeholder}
)}
{(Boolean(helperText) || error) && (
{error && errorText ? ( {errorText} ) : typeof helperText === 'string' ? ( {helperText} ) : ( helperText )}
)}
); }; const RightInputIcon = ({ isEmail, isPassword, showPassword, showPasswordToggleIcon, isLocked, isDisabled, iconRightName, iconRightType, ...rightIconProps }: { isEmail?: boolean, isPassword?: boolean, showPassword?: boolean, showPasswordToggleIcon?: boolean, isLocked?: boolean, isDisabled?: boolean, onClick?: ?(SyntheticEvent) => mixed, iconRightName?: string, iconRightType?: IconType, className?: string, }): React.Node => { if (isLocked) { return ( ); } if (isEmail) { return ( ); } if (isPassword && showPasswordToggleIcon) { return ( ); } if (iconRightName) { return ( ); } return <>; }; export const Input = (React.forwardRef( Input_, ): React$AbstractComponent);