import React, { useRef, useState } from 'react'; import { TextInput, NativeSyntheticEvent, TextInputKeyPressEventData, } from 'react-native'; import { Box } from '../Box'; import { Normalize } from '../../utils/normalize'; import styles from './styles'; export type TextInputProps = React.ComponentPropsWithRef & { defaultValue: string; numInputs: number; inputCellLength?: number; handleTextChange: Function; keyboardType?: string; error?: boolean; }; const getOTPTextChucks = ( numInputs: number, inputCellLength: number, text: string ) => { let otpText = text.match(new RegExp('.{1,' + inputCellLength + '}', 'g')) || []; otpText = otpText.slice(0, numInputs) as RegExpMatchArray; return otpText; }; export const TextFieldDigit = React.forwardRef( ( { defaultValue = '', numInputs = 4, inputCellLength = 1, handleTextChange = () => {}, keyboardType = 'numeric', error = false, ...textInputProps }, ref ) => { const [focusedInput, setFocusedInput] = useState(0); const [otpText, setOtpText] = useState( getOTPTextChucks(numInputs, inputCellLength, defaultValue) ); const inputCodeRef = useRef([]); const basicValidation = (text: string) => { const validText = /^[0-9a-zA-Z]+$/; return text.match(validText); }; const onKeyPress = ( event: NativeSyntheticEvent, index: number ) => { const key = event.nativeEvent.key; if (key === 'Backspace') { const indexOnBackspace = index > 0 ? index - 1 : 0; return inputCodeRef.current[indexOnBackspace].focus(); } const currentIndex = index < numInputs - 1 ? index + 1 : numInputs - 1; return inputCodeRef.current[currentIndex].focus(); }; const onTextChange = (text: string, i: number) => { if (text && !basicValidation(text)) { return; } const typedCode = text.slice(-1); const currentCodes = [...otpText] as RegExpMatchArray; currentCodes[i] = typedCode; setOtpText(currentCodes); handleTextChange(otpText.join('')); }; const onInputFocus = (i: number) => { const prevIndex: number = i - 1; if (prevIndex > -1 && !otpText[prevIndex] && !otpText.join('')) { inputCodeRef.current[prevIndex].focus(); return; } setFocusedInput(i); }; const getBorderColor = (i: number) => { if (error) return 'chiperBrandRed'; if (focusedInput === i) return 'yankeesBlue'; return 'gray25'; }; const TextInputs = []; for (let i = 0; i < numInputs; i += 1) { TextInputs.push( element && inputCodeRef.current.push(element)} key={i} autoCorrect={false} keyboardType={keyboardType} autoFocus={i === 0} value={otpText[i] || ''} style={styles.textInput} maxLength={inputCellLength} selectTextOnFocus={true} onFocus={() => onInputFocus(i)} onChangeText={(text) => onTextChange(text, i)} multiline={false} onKeyPress={(e) => onKeyPress(e, i)} {...textInputProps} /> ); } return ( {TextInputs} ); } );