UNPKG

react-native-otp-fields

Version:

A customizable React Native OTP input component with smooth focus handling, digit-only validation, and easy integration for verification codes, PINs, or passcodes.

73 lines (72 loc) 2.81 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = OtpInput; const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const react_native_1 = require("react-native"); ; function OtpInput({ length = 6, onOtpComplete, inputStyle, containerStyle, }) { const [otp, setOtp] = (0, react_1.useState)(Array(length).fill('')); const inputsRef = (0, react_1.useRef)([]); const handleChangeText = (text, index) => { var _a; const newOtp = [...otp]; const char = text.slice(-1); const digitRegex = /^\d$/; if (digitRegex.test(char)) { newOtp[index] = char; setOtp(newOtp); if (index < length - 1) { (_a = inputsRef.current[index + 1]) === null || _a === void 0 ? void 0 : _a.focus(); } if (newOtp.every(d => d !== '')) { onOtpComplete === null || onOtpComplete === void 0 ? void 0 : onOtpComplete(newOtp.join('')); } } else if (text === '') { newOtp[index] = ''; setOtp(newOtp); } }; const handleKeyPress = ({ nativeEvent }, index) => { if (nativeEvent.key === 'Backspace') { setOtp((prevOtp) => { var _a, _b; const newOtp = [...prevOtp]; if (newOtp[index] === '') { if (index > 0) { newOtp[index - 1] = ''; (_a = inputsRef.current[index - 1]) === null || _a === void 0 ? void 0 : _a.focus(); } } else { newOtp[index] = ''; (_b = inputsRef.current[index]) === null || _b === void 0 ? void 0 : _b.focus(); } return newOtp; }); } }; return ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: [styles.container, containerStyle], children: Array.from({ length }).map((_, i) => ((0, jsx_runtime_1.jsx)(react_native_1.TextInput, { // @ts-ignore ref: ref => (inputsRef.current[i] = ref), value: otp[i], onChangeText: text => handleChangeText(text, i), onKeyPress: e => handleKeyPress(e, i), keyboardType: "number-pad", maxLength: 1, style: [styles.input, inputStyle], returnKeyType: "done", autoFocus: i === 0 }, i))) })); } ; const styles = react_native_1.StyleSheet.create({ container: { flexDirection: 'row', gap: 12, justifyContent: 'center', padding: 20, }, input: { width: 48, height: 58, borderWidth: 1, borderColor: '#ccc', borderRadius: 8, textAlign: 'center', fontSize: 20, backgroundColor: '#fff', }, });