import { ChangeEvent, useState } from 'react'; import classNames from 'classnames'; import styled from 'styled-components'; import { Noop } from '../../types/Util'; import { useHTMLDirection } from '../../util/i18n'; import { SessionIconButton } from '../icon'; type Props = { label?: string; error?: string; type?: string; value?: string; placeholder: string; maxLength?: number; enableShowHide?: boolean; onValueChanged?: (value: string) => any; onEnterPressed?: any; autoFocus?: boolean; ref?: any; inputDataTestId?: string; }; const StyledInputWithLabelContainer = styled.label` height: 46.5px; width: 280px; font-family: var(--font-default); color: var(--text-primary-color); padding: 2px 0 2px 0; transition: opacity var(--default-duration); opacity: 1; position: relative; label { line-height: 14px; opacity: 0; color: var(--text-primary-color); font-size: 10px; line-height: 11px; position: absolute; top: 0px; } &.filled { opacity: 1; } &.error { color: var(--danger-color); } input { border: none; outline: 0; height: 14px; width: 280px; background: transparent; color: var(--input-text-color); font-family: var(--font-default); font-size: 12px; line-height: 14px; position: absolute; top: 50%; transform: translateY(-50%); &::placeholder { color: var(--input-text-placeholder-color); } } `; const LabelItem = (props: { inputValue: string; label?: string }) => { return ( <StyledInputWithLabelContainer htmlFor="session-input-floating-label" className={classNames(props.inputValue !== '' ? 'filled' : '')} > {props.label} </StyledInputWithLabelContainer> ); }; const ErrorItem = (props: { error: string | undefined }) => { return ( <StyledInputWithLabelContainer htmlFor="session-input-floating-label" className={classNames('filled error')} > {props.error} </StyledInputWithLabelContainer> ); }; const ShowHideButton = (props: { toggleForceShow: Noop }) => { const htmlDirection = useHTMLDirection(); const position = htmlDirection === 'ltr' ? { right: '0px' } : { left: '0px' }; return ( <SessionIconButton iconType="eye" iconSize="medium" onClick={props.toggleForceShow} style={{ position: 'absolute', top: '50%', transform: 'translateY(-50%)', ...position }} /> ); }; export const SessionInput2 = (props: Props) => { const { autoFocus, placeholder, type, value, maxLength, enableShowHide, error, label, onValueChanged, inputDataTestId, } = props; const [inputValue, setInputValue] = useState(''); const [forceShow, setForceShow] = useState(false); const correctType = forceShow ? 'text' : type; const updateInputValue = (e: ChangeEvent<HTMLInputElement>) => { e.preventDefault(); const val = e.target.value; setInputValue(val); if (onValueChanged) { onValueChanged(val); } }; return ( <StyledInputWithLabelContainer> {error ? ( <ErrorItem error={props.error} /> ) : ( <LabelItem inputValue={inputValue} label={label} /> )} <input id="session-input-floating-label" type={correctType} placeholder={placeholder} value={value} maxLength={maxLength} autoFocus={autoFocus} data-testid={inputDataTestId} onChange={updateInputValue} style={{ paddingInlineEnd: enableShowHide ? '30px' : undefined }} // just in case onChange isn't triggered onBlur={updateInputValue} onKeyDown={event => { if (event.key === 'Enter' && props.onEnterPressed) { props.onEnterPressed(); } }} /> {enableShowHide && ( <ShowHideButton toggleForceShow={() => { setForceShow(!forceShow); }} /> )} </StyledInputWithLabelContainer> ); };