@penaprieto/design-system
Version:
Multi-brand React design system with design tokens from Figma
63 lines (62 loc) • 2.91 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.OTPInput = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
require("./OTPInput.css");
const OTPInput = ({ length = 6, value = '', onChange, onComplete, disabled = false, error = false, className = '', }) => {
const [otp, setOtp] = (0, react_1.useState)(value.split(''));
const inputRefs = (0, react_1.useRef)([]);
const handleChange = (index, val) => {
var _a;
if (disabled)
return;
const newVal = val.replace(/[^0-9]/g, '');
if (newVal.length > 1)
return;
const newOtp = [...otp];
newOtp[index] = newVal;
setOtp(newOtp);
const otpString = newOtp.join('');
onChange === null || onChange === void 0 ? void 0 : onChange(otpString);
if (newVal && index < length - 1) {
(_a = inputRefs.current[index + 1]) === null || _a === void 0 ? void 0 : _a.focus();
}
if (otpString.length === length) {
onComplete === null || onComplete === void 0 ? void 0 : onComplete(otpString);
}
};
const handleKeyDown = (index, e) => {
var _a;
if (e.key === 'Backspace' && !otp[index] && index > 0) {
(_a = inputRefs.current[index - 1]) === null || _a === void 0 ? void 0 : _a.focus();
}
};
const handlePaste = (e) => {
var _a, _b;
e.preventDefault();
const pastedData = e.clipboardData.getData('text').replace(/[^0-9]/g, '').slice(0, length);
const newOtp = pastedData.split('');
setOtp(newOtp);
onChange === null || onChange === void 0 ? void 0 : onChange(pastedData);
if (pastedData.length === length) {
onComplete === null || onComplete === void 0 ? void 0 : onComplete(pastedData);
(_a = inputRefs.current[length - 1]) === null || _a === void 0 ? void 0 : _a.focus();
}
else if (pastedData.length > 0) {
(_b = inputRefs.current[Math.min(pastedData.length, length - 1)]) === null || _b === void 0 ? void 0 : _b.focus();
}
};
const rootClassName = [
'ds-otp-input',
error && 'ds-otp-input--error',
disabled && 'ds-otp-input--disabled',
className,
]
.filter(Boolean)
.join(' ');
return ((0, jsx_runtime_1.jsx)("div", { className: rootClassName, children: Array.from({ length }).map((_, index) => ((0, jsx_runtime_1.jsx)("input", { ref: (el) => {
inputRefs.current[index] = el;
}, type: "text", inputMode: "numeric", maxLength: 1, value: otp[index] || '', onChange: (e) => handleChange(index, e.target.value), onKeyDown: (e) => handleKeyDown(index, e), onPaste: handlePaste, disabled: disabled, className: "ds-otp-input__field" }, index))) }));
};
exports.OTPInput = OTPInput;