UNPKG

react-otp-custom

Version:

Customizable React OTP input component

63 lines (62 loc) 2.62 kB
(function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode(".otp-container{display:flex;gap:8px}.otp-input{width:40px;height:40px;font-size:20px;text-align:center;border:1px solid #ccc;border-radius:4px}.otp-square{border-radius:4px}.otp-circle{border-radius:50%}.otp-light:focus{border-color:#000;outline:none}.otp-dark{background-color:#000!important;color:#fff!important;border:1px solid white}.otp-dark:focus{border:2px solid whitesmoke;outline:none}")),document.head.appendChild(e)}}catch(o){console.error("vite-plugin-css-injected-by-js",o)}})(); import { jsx as m } from "react/jsx-runtime"; import { useState as O, useRef as v, useEffect as D } from "react"; import p from "prop-types"; const b = ({ length: u = 6, onChange: h, isNumeric: f = !0, theme: y = "light", shape: g = "square", fontSize: l = 24 }) => { const [s, i] = O(Array(u).fill("")), c = v([]); D(() => { h(s.join("")); }, [s, h]); const w = (n, t) => { var a; const e = n.target.value; if (f && !/^\d*$/.test(e)) return; const o = [...s], r = e.slice(-1); o[t] = r, i(o), r && s[t] === "" && t < u - 1 && ((a = c.current[t + 1]) == null || a.focus()); }, $ = (n, t) => { var e, o, r; if (n.key === "Backspace") { const a = [...s]; s[t] ? (a[t] = "", i(a)) : t > 0 && ((e = c.current[t - 1]) == null || e.focus()); } else n.key === "ArrowLeft" && t > 0 ? (o = c.current[t - 1]) == null || o.focus() : n.key === "ArrowRight" && t < u - 1 && ((r = c.current[t + 1]) == null || r.focus()); }; return /* @__PURE__ */ m("div", { className: "otp-container", onPaste: (n) => { var o; n.preventDefault(); const t = n.clipboardData.getData("text").slice(0, u).split(""), e = [...s]; t.forEach((r, a) => { f && !/^[0-9]$/.test(r) || (e[a] = r); }), i(e), (o = c.current[t.length - 1]) == null || o.focus(); }, children: s.map((n, t) => /* @__PURE__ */ m( "input", { ref: (e) => c.current[t] = e, type: "text", inputMode: f ? "numeric" : "text", autoFocus: t === 0, maxLength: 2, value: n, onChange: (e) => w(e, t), onKeyDown: (e) => $(e, t), className: `otp-input otp-${y} otp-${g}`, style: { fontSize: `${l}px`, width: `${l * 2}px`, height: `${l * 2}px` } }, t )) }); }; b.propTypes = { length: p.number, onChange: p.func.isRequired, isNumeric: p.bool, theme: p.string, shape: p.oneOf(["square", "circle"]), fontSize: p.number }; export { b as OtpInput, b as default };