import React, { useState, useEffect } from 'react'; import { CopyButton } from '../CopyButton'; import { Icon } from '../Icon'; import { iconTypes } from '../Icon/collection'; import InputStyles from './Input.styles'; import type { InputProps } from './types'; const { CopyContainerStyled, DivStyled, DivWrapperStyled, InputStyled, LabelStyled, StrongStyled, VisibilityIcon, } = InputStyles; const Input: React.FC = ({ autoComplete = true, autoFocus = false, disabled = false, description, errorMessage = 'Sorry this is not valid', hasCopyButton = false, id, ref, inputHidden = false, label, name, onChange, onBlur, placeholder = '', prefixIcon, size = 'regular', state = disabled ? 'disabled' : undefined, style, type = 'text', validation, value = '', width = '320px', labelBgColor, iconPosition = 'front', customInput, ...props }: InputProps) => { const [currentValue, setCurrentValue] = useState(value); const [currentState, setCurrentState] = useState(state); const [mainType, setMainType] = useState(type); const [isInputHidden, setIsInputHidden] = useState(inputHidden); const [invalidMessage, setInvalidMessage] = useState(errorMessage); useEffect(() => setIsInputHidden(type === 'password'), [inputHidden]); useEffect(() => setCurrentState(state), [state]); useEffect(() => setMainType(type), [type]); useEffect(() => setCurrentValue(value), [value]); useEffect(() => setInvalidMessage(errorMessage), [errorMessage]); const valueChanged = (event: React.ChangeEvent) => { setCurrentValue(event.target.value); onChange && onChange(event); }; const canToggleHideInput = (): boolean => { return mainType === 'password'; }; const toggleHideInput = (): void => { if (currentState === 'disabled') return; setIsInputHidden(!isInputHidden); }; const hasValidation = () => Boolean( validation?.required || validation?.numberMax || validation?.numberMin || validation?.characterMaxLength || validation?.characterMinLength || validation?.regExp, ); const validate = (event: React.FocusEvent) => { onBlur && onBlur(event); if (!hasValidation()) return; // check for HTML validation if (!event?.target.checkValidity()) { setInvalidMessage(event?.target.validationMessage || errorMessage); setCurrentState('error'); return; } // check for the value passes the custom RegExp if (validation?.regExp) { const re = new RegExp(validation?.regExp); if (!re.test(event?.target.value)) { setInvalidMessage( validation?.regExpInvalidMessage || errorMessage, ); setCurrentState('error'); return; } } // finally if all pass but the Input is in error state if (currentState === 'error') { setCurrentState('confirmed'); setTimeout(() => setCurrentState('initial'), 3000); } }; return ( 0 ? 'filled' : 'empty' }`} data-testid="test-div" style={{ ...style, width }} size={size} > {prefixIcon && iconPosition == 'front' && ( )} {customInput && customInput} ) => validate(event) } onChange={(event: React.ChangeEvent) => valueChanged(event) } pattern={validation?.regExp} placeholder={placeholder} required={validation?.required} type={ mainType !== 'password' ? type : isInputHidden ? 'password' : 'text' } value={currentValue} {...props} /> {label && ( {label} {validation?.required && '*'} )} {currentState === 'error' && ( {invalidMessage} )} {description && !(currentState === 'error') && ( {description} )} {canToggleHideInput() && ( toggleHideInput()} type="button" > {isInputHidden ? ( ) : ( )} )} {prefixIcon && iconPosition == 'end' && ( )} {hasCopyButton && ( )} ); }; export default Input;