import { useEffect, useRef, useState } from 'react'; import { useField } from '@unform/core'; import { useTheme } from '../../../hooks/theme'; import { InputContainer, Label, Error } from '../styles'; import { Container } from './styles'; interface Props { name: string; label?: string; amount?: number; } type PinInputProps = JSX.IntrinsicElements['input'] & Props; export function PinInput({ name, label, disabled, onBlur, onChange, amount = 4, ...rest }: PinInputProps): JSX.Element { const { colorScheme } = useTheme(); const inputRefs = useRef([]); const { fieldName, defaultValue, registerField, error } = useField(name); const [isFocused, setIsFocused] = useState(false); const [isFilled, setIsFilled] = useState(defaultValue); function handleBlur( event?: React.FocusEvent, ): void { setIsFocused(false); if (onBlur && event) { onBlur(event); } } function handleChange( event?: React.ChangeEvent | null, data?: string, ): void { const value = data ?? event?.target.value; setIsFilled(value); if (onChange && event) { onChange(event); } } useEffect(() => { if (disabled) { handleBlur(); } }, [disabled]); useEffect(() => { registerField({ name: fieldName, getValue: () => { let value = ''; if (inputRefs.current.length) { inputRefs.current.forEach((ref) => { value = `${value}${ref.value}`; }); } return value; }, setValue: (_, value: string) => { if (inputRefs.current.length) { inputRefs.current.forEach((ref, index) => { if (value[index]) { ref.value = value[index]; } }); } }, clearValue: () => { if (inputRefs.current.length) { inputRefs.current.forEach((ref) => { ref.value = ''; }); } setIsFilled(''); }, }); }, [fieldName, registerField]); return ( {label && ( )} {new Array(amount).fill('').map((_, index) => ( { inputRefs.current[index] = ref as HTMLInputElement; }} type="text" maxLength={1} onKeyDown={(event) => { if (event.key === 'Backspace' && inputRefs.current[index - 1]) { const { value } = inputRefs.current[index]; if (!value) { inputRefs.current[index - 1].focus(); } } }} onBlur={handleBlur} onChange={(event) => { handleChange(event); const { value } = event.target; const valueWithoutDigit = value.replaceAll(/\D/g, ''); inputRefs.current[index].value = valueWithoutDigit; if (!!valueWithoutDigit && inputRefs.current[index + 1]) { inputRefs.current[index + 1].focus(); } }} disabled={disabled} {...rest} /> ))} {error && {error}} ); }