UNPKG

mui-one-time-password-input

Version:

A One-Time Password input designed for the React library MUI

213 lines (212 loc) 5.79 kB
import { jsx as R } from "react/jsx-runtime"; import g from "react"; import { styled as W } from "@mui/material/styles"; import q from "@mui/material/TextField"; import z from "@mui/material/Box"; const G = W(q)` input { text-align: center; } `, J = { TextFieldStyled: G }, Q = (n) => /* @__PURE__ */ R(J.TextFieldStyled, { ...n }), D = { left: "ArrowLeft", right: "ArrowRight", backspace: "Backspace", home: "Home", end: "End" }; function U(n, s) { return n <= 0 ? [] : Array.from({ length: n }, s); } function X(n, s, l) { return n.map((i, F) => s === F ? l : i); } function P(n) { return n.join(""); } function M(n, s) { return [...n, s]; } function Z(n, s, l) { return n.reduce( (i, F, C) => { const { characters: y, restArrayMerged: d } = i; if (C < l) return { restArrayMerged: d, characters: M(y, F) }; const [V, ...E] = d; return { restArrayMerged: E, characters: M(y, V || "") }; }, { restArrayMerged: s, characters: [] } ).characters; } function v(n) { return (s) => { n.forEach((l) => { typeof l == "function" ? l(s) : l != null && (l.current = s); }); }; } function ee(n) { return n.split(""); } function N(n) { const s = g.useRef(() => { throw new Error("Cannot call an event handler while rendering."); }); return g.useInsertionEffect(() => { s.current = n; }), g.useCallback((...l) => s.current?.(...l), []); } const te = () => !0, le = g.forwardRef( (n, s) => { const { value: l = "", length: i = 4, autoFocus: F = !1, onChange: C, TextFieldsProps: y, onComplete: d, validateChar: V = te, className: E, onBlur: b, ...K } = n, j = g.useRef(l), w = N(d), I = N((e) => { const t = e.slice(0, i); return { isCompleted: t.length === i, finalValue: t }; }); g.useEffect(() => { const { isCompleted: e, finalValue: t } = I( j.current ); e && w(t); }, [i, w, I]); const p = U( i, (e, t) => ({ character: l[t] || "", inputRef: g.createRef() }) ), T = (e) => p.findIndex(({ inputRef: t }) => t.current === e), k = () => p.map(({ character: e }) => e), A = (e, t) => { const r = X( k(), e, t ); return P(r); }, $ = (e) => { p[e]?.inputRef.current?.focus(); }, c = (e) => { p[e]?.inputRef.current?.select(); }, O = (e) => { e + 1 !== i && (p[e + 1].character ? c(e + 1) : $(e + 1)); }, S = (e, t) => typeof V != "function" ? !0 : V(e, t), Y = (e) => { const t = T(e.target); if (t === 0 && e.target.value.length > 1) { const { finalValue: m, isCompleted: B } = I( e.target.value ); C?.(m), B && d?.(m), c(m.length - 1); return; } const r = e.target.value[0] || ""; let u = r; u && !S(u, t) && (u = ""); const a = A(t, u); C?.(a); const { isCompleted: h, finalValue: f } = I(a); h && d?.(f), u !== "" ? a.length - 1 < t ? c(a.length) : O(t) : r === "" && a.length <= t && c(t - 1); }, _ = (e) => { const t = e.target, r = t.selectionStart, u = t.selectionEnd, a = T(t), h = r === 0 && u === 0; if (t.value === e.key) e.preventDefault(), O(a); else if (D.backspace === e.key) { if (!t.value) e.preventDefault(), c(a - 1); else if (h) { e.preventDefault(); const f = A(a, ""); C?.(f), f.length <= a && c(a - 1); } } else D.left === e.key ? (e.preventDefault(), c(a - 1)) : D.right === e.key ? (e.preventDefault(), c(a + 1)) : D.home === e.key ? (e.preventDefault(), c(0)) : D.end === e.key && (e.preventDefault(), c(p.length - 1)); }, H = (e) => { const t = e.clipboardData.getData("text/plain"), r = e.target, u = p.findIndex( ({ character: x, inputRef: o }) => x === "" || o.current === r ), a = k(), h = Z( a, ee(t), u ).map((x, o) => S(x, o) ? x : ""), f = P(h); C?.(f); const { isCompleted: m, finalValue: B } = I(f); m ? (d?.(B), c(i - 1)) : c(f.length); }, L = (e) => { if (!p.some(({ inputRef: r }) => r.current === e.relatedTarget)) { const { isCompleted: r, finalValue: u } = I(l); b?.(u, r); } }; return /* @__PURE__ */ R( z, { display: "flex", gap: "20px", alignItems: "center", ref: s, className: `MuiOtpInput-Box ${E || ""}`, ...K, children: p.map(({ character: e, inputRef: t }, r) => { const { onPaste: u, onFocus: a, onKeyDown: h, className: f, onBlur: m, inputRef: B, ...x } = typeof y == "function" ? y(r) || {} : y || {}; return /* @__PURE__ */ R( Q, { autoFocus: F ? r === 0 : !1, autoComplete: "one-time-code", value: e, inputRef: v([t, B]), className: `MuiOtpInput-TextField MuiOtpInput-TextField-${r + 1} ${f || ""}`, onPaste: (o) => { o.preventDefault(), H(o), u?.(o); }, onFocus: (o) => { o.preventDefault(), o.target.select(), a?.(o); }, onChange: Y, onKeyDown: (o) => { _(o), h?.(o); }, onBlur: (o) => { m?.(o), L(o); }, ...x }, r ); }) } ); } ); export { le as MuiOtpInput };