react-native-otp-box-input
Version:
A customizable and lightweight OTP input component for React Native apps with full TypeScript support and clean UI.
115 lines • 3.62 kB
JavaScript
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
import React, { useState, useRef } from 'react';
import { View, TextInput, StyleSheet } from 'react-native';
const OtpInputBox = ({
length,
style,
onChangeOtp,
inputStyle,
activeInputStyle,
keyboardType = 'numeric',
placeholder,
placeholders,
renderInput,
inputProps = {},
onInputFocus,
onInputBlur,
...props
}) => {
const [otp, setOtp] = useState(Array(length).fill(''));
const [focusedIndex, setFocusedIndex] = useState(null);
const inputRefs = useRef([]);
const handleChange = (value, index) => {
const updatedOtp = [...otp];
if (value === '') {
updatedOtp[index] = '';
setOtp(updatedOtp);
onChangeOtp(updatedOtp.join(''));
if (index > 0) {
var _inputRefs$current;
(_inputRefs$current = inputRefs.current[index - 1]) === null || _inputRefs$current === void 0 || _inputRefs$current.focus();
}
return;
}
if (/^\d$/.test(value)) {
updatedOtp[index] = value;
setOtp(updatedOtp);
onChangeOtp(updatedOtp.join(''));
if (index < length - 1) {
var _inputRefs$current2;
(_inputRefs$current2 = inputRefs.current[index + 1]) === null || _inputRefs$current2 === void 0 || _inputRefs$current2.focus();
}
}
};
const handleFocus = index => {
setFocusedIndex(index);
if (onInputFocus) onInputFocus(index);
};
const handleBlur = index => {
setFocusedIndex(prev => prev === index ? null : prev);
if (onInputBlur) onInputBlur(index);
};
return /*#__PURE__*/React.createElement(View, {
style: [styles.container, style]
}, otp.map((digit, index) => {
const isFocused = focusedIndex === index;
const mergedStyle = [styles.input, inputStyle, isFocused && activeInputStyle];
const inputPlaceholder = (placeholders === null || placeholders === void 0 ? void 0 : placeholders[index]) ?? placeholder;
const refCallback = ref => {
if (ref) inputRefs.current[index] = ref;
};
const inputNodeProps = {
value: digit,
ref: refCallback,
style: mergedStyle,
keyboardType,
maxLength: 1,
selectTextOnFocus: true,
autoFocus: (props === null || props === void 0 ? void 0 : props.autoFocus) && index === 0,
onChangeText: value => handleChange(value, index),
onFocus: () => handleFocus(index),
onBlur: () => handleBlur(index),
placeholder: inputPlaceholder,
...inputProps,
...props
};
if (renderInput) {
return renderInput({
value: digit,
index,
isFocused,
onChangeText: value => handleChange(value, index),
onFocus: () => handleFocus(index),
onBlur: () => handleBlur(index),
ref: refCallback,
style: mergedStyle,
inputProps: {
...inputProps,
...props
}
});
}
return /*#__PURE__*/React.createElement(TextInput, _extends({
key: index
}, inputNodeProps));
}));
};
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
justifyContent: 'space-between'
},
input: {
width: 40,
height: 40,
borderWidth: 1,
borderRadius: 8,
borderColor: '#ccc',
textAlign: 'center',
fontSize: 20,
margin: 5,
backgroundColor: '#fff'
}
});
export default OtpInputBox;
//# sourceMappingURL=index.js.map