react-native-modern-elements
Version:
A modern, customizable UI component library for React Native
76 lines (75 loc) • 2.9 kB
JavaScript
import React, { memo, useRef, useState } from "react";
import { StyleSheet, TextInput, View } from "react-native";
const OTPInput = ({ length, setVerifyOtp }) => {
const [otp, setOTP] = useState(Array(length).fill(null));
const inputsRef = useRef([]);
const handleChange = (index, value) => {
var _a, _b;
if (/^\d$/.test(value) || value === "") {
const newOTP = [...otp];
newOTP[index] = value === "" ? null : Number(value); // ✅ Convert to number
setOTP(newOTP);
// ✅ Send OTP array with numbers to parent
setVerifyOtp(newOTP.filter((num) => num !== null));
if (value !== "" && index < length - 1) {
(_a = inputsRef.current[index + 1]) === null || _a === void 0 ? void 0 : _a.focus();
}
else if (value === "" && index > 0) {
(_b = inputsRef.current[index - 1]) === null || _b === void 0 ? void 0 : _b.focus();
}
}
};
const handleKeyDown = (index, e) => {
var _a;
if (e.nativeEvent.key === "Backspace") {
if (!otp[index] && index > 0) {
// ✅ Move focus AND clear previous input
const newOTP = [...otp];
newOTP[index - 1] = null;
setOTP(newOTP);
setVerifyOtp(newOTP.filter((num) => num !== null));
(_a = inputsRef.current[index - 1]) === null || _a === void 0 ? void 0 : _a.focus();
}
}
};
return (React.createElement(View, { style: styles.container },
React.createElement(View, { style: styles.inputContainer }, otp.map((value, index) => (React.createElement(TextInput, { key: index, ref: (el) => {
if (el)
inputsRef.current[index] = el;
}, style: [styles.input, value !== null && styles.inputFilled], keyboardType: "number-pad", maxLength: 1, value: value !== null ? String(value) : "", onKeyPress: (e) => handleKeyDown(index, e), onChangeText: (text) => handleChange(index, text), autoFocus: index === 0 }))))));
};
const styles = StyleSheet.create({
container: {
alignItems: "center",
justifyContent: "center",
padding: 20,
},
title: {
fontSize: 24,
fontWeight: "bold",
color: "#007AFF",
marginBottom: 20,
},
inputContainer: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
},
input: {
fontSize: 24,
fontWeight: "bold",
borderWidth: 1,
borderColor: "gray",
width: 57,
height: 57,
textAlign: "center",
marginRight: 10,
borderRadius: 10,
color: "#FB5C12",
},
inputFilled: {
borderColor: "#FB5C12",
backgroundColor: "#FB5C121A",
},
});
export default memo(OTPInput);