UNPKG

@kadoui/react

Version:

Kadoui primitive components for React

56 lines (55 loc) 2.32 kB
"use client"; import { jsx as _jsx } from "react/jsx-runtime"; import { use } from "react"; import { OtpContext } from "./OtpContext"; export function OtpInputs({ name, length, onLastChange, ...props }) { const { inputs, getInputsValue } = use(OtpContext); const handlePaste = (ev, startIndex) => { ev.preventDefault(); const pastedData = ev.clipboardData.getData("text").replace(/\s/g, ""); // Remove whitespace if (!pastedData) return; for (let i = 0; i < pastedData.length; i++) { const inputIndex = startIndex + i; if (inputIndex >= length) break; // Don't exceed OTP length const input = inputs?.current[inputIndex]; const indexedPastedData = pastedData[i]; if (input && indexedPastedData) { input.value = indexedPastedData; } } const nextIndex = Math.min(startIndex + pastedData.length, length - 1); inputs?.current[nextIndex]?.focus(); const otpValue = getInputsValue(); if (otpValue.length === length) { onLastChange?.(otpValue); } }; const handleInputChange = (value, index) => { if (value) { const currentInput = inputs?.current[index]; const currentValue = currentInput?.value[currentInput.value.length - 1]; if (currentValue) { currentInput.value = currentValue; } const nextInput = inputs?.current[index + 1]; if (nextInput) { nextInput.value = ""; nextInput.focus(); return; } onLastChange?.(getInputsValue()); } }; const handleBackspace = (e, index) => { if (e.key === "Backspace" && !e.currentTarget.value && index > 0) { inputs?.current[index - 1]?.focus(); } }; return Array.from({ length }).map((_, index) => (_jsx("input", { autoComplete: "off", name: `${name || "otp"}-${index}`, onPaste: ev => handlePaste(ev, index), onKeyDown: ev => handleBackspace(ev, index), onChange: ev => handleInputChange(ev.target.value, index), ref: el => { if (inputs) { inputs.current[index] = el; } }, ...props }, index))); }