UNPKG

payloadcms_otp_plugin

Version:

A comprehensive One-Time Password (OTP) authentication plugin for Payload CMS that enables secure passwordless authentication via SMS and email

87 lines (86 loc) 3.21 kB
'use client'; import { jsx as _jsx } from "react/jsx-runtime"; import React, { useState, useRef } from 'react'; import './otp-view.scss'; const OTPInput = ({ length = 6, disabled = false, onComplete, onChange, className = '', value = '', onReset })=>{ const [otp, setOtp] = useState(()=>{ const initialOtp = value.split('').slice(0, length); while(initialOtp.length < length){ initialOtp.push(''); } return initialOtp; }); const inputRefs = useRef([]); // Note: We don't update the array when length changes dynamically // to avoid state management issues. The parent component should // handle ensuring the correct length is passed from the start. // Reset OTP when onReset is called React.useEffect(()=>{ if (onReset) { const resetOtp = Array(length).fill(''); setOtp(resetOtp); // Use setTimeout to ensure DOM is updated before focusing setTimeout(()=>{ inputRefs.current[0]?.focus(); }, 0); } }, [ onReset, length ]); // Handle input change const handleInputChange = (index, inputValue)=>{ if (disabled) return; if (inputValue.length > 1) return; // Only allow numeric input if (inputValue && !/^\d$/.test(inputValue)) return; const newOtp = [ ...otp ]; newOtp[index] = inputValue; setOtp(newOtp); const otpString = newOtp.join(''); // Call onChange callback onChange?.(otpString); // Call onComplete if all digits are filled if (otpString.length === length && !otpString.includes('')) { onComplete?.(otpString); } // Auto-focus next input if (inputValue && index < length - 1) { inputRefs.current[index + 1]?.focus(); } }; // Handle key down for backspace const handleKeyDown = (index, e)=>{ if (disabled) return; if (e.key === 'Backspace' && !otp[index] && index > 0) { inputRefs.current[index - 1]?.focus(); } }; return /*#__PURE__*/ _jsx("div", { className: `otp-input ${className}`, children: /*#__PURE__*/ _jsx("div", { className: "otp-input__container", children: otp.map((digit, index)=>/*#__PURE__*/ _jsx("input", { ref: (el)=>{ if (el) { inputRefs.current[index] = el; } }, type: "text", inputMode: "numeric", pattern: "\\d*", maxLength: 1, value: digit, onChange: (e)=>handleInputChange(index, e.target.value), onKeyDown: (e)=>handleKeyDown(index, e), className: `otp-input__field ${disabled ? 'otp-input__field--disabled' : ''}`, disabled: disabled, "aria-label": `Digit ${index + 1} of ${length}` }, index)) }) }); }; export default OTPInput; //# sourceMappingURL=otp-input.js.map