UNPKG

mui-one-time-password-input

Version:

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

170 lines (169 loc) 5 kB
import e from "react"; import { styled as t } from "@mui/material/styles"; import n from "@mui/material/TextField"; import { jsx as r } from "react/jsx-runtime"; import i from "@mui/material/Box"; //#region src/components/TextFieldBox/TextFieldBox.styled.ts var a = t(n)` input { text-align: center; } `, o = (e) => /* @__PURE__ */ r(a, { ...e }), s = { left: "ArrowLeft", right: "ArrowRight", backspace: "Backspace", home: "Home", end: "End" }; //#endregion //#region src/shared/helpers/array.ts function c(e, t) { return e <= 0 ? [] : Array.from({ length: e }, t); } function l(e, t, n) { return e.map((e, r) => t === r ? n : e); } function u(e) { return e.join(""); } function d(e, t) { return [...e, t]; } function f(e, t, n) { return e.reduce((e, t, r) => { let { characters: i, restArrayMerged: a } = e; if (r < n) return { restArrayMerged: a, characters: d(i, t) }; let [o, ...s] = a; return { restArrayMerged: s, characters: d(i, o || "") }; }, { restArrayMerged: t, characters: [] }).characters; } //#endregion //#region src/shared/helpers/react.ts function p(e) { return (t) => { for (let n of e) typeof n == "function" ? n(t) : n != null && (n.current = t); }; } //#endregion //#region src/shared/helpers/string.ts function m(e) { return e.split(""); } //#endregion //#region src/shared/hooks/useEvent.ts function h(t) { let n = e.useRef(() => { throw Error("Cannot call an event handler while rendering."); }); return e.useInsertionEffect(() => { n.current = t; }), e.useCallback((...e) => n.current?.(...e), []); } //#endregion //#region src/index.tsx var g = () => !0, _ = { display: "flex", gap: "20px", alignItems: "center" }, v = e.forwardRef((t, n) => { let { value: a = "", length: d = 4, autoFocus: v = !1, onChange: y, TextFieldsProps: b, onComplete: x, validateChar: S = g, className: C, onBlur: w, sx: T, ...E } = t, D = e.useRef(a), O = h(x), k = h((e) => { let t = e.slice(0, d); return { isCompleted: t.length === d, finalValue: t }; }); e.useEffect(() => { let { isCompleted: e, finalValue: t } = k(D.current); e && O(t); }, [ d, O, k ]); let A = c(d, (t, n) => ({ character: a[n] || "", inputRef: e.createRef() })), j = (e) => A.findIndex(({ inputRef: t }) => t.current === e), M = () => A.map(({ character: e }) => e), N = (e, t) => u(l(M(), e, t)), P = (e) => { A[e]?.inputRef.current?.focus(); }, F = (e) => { A[e]?.inputRef.current?.select(); }, I = (e) => { e + 1 !== d && (A[e + 1].character ? F(e + 1) : P(e + 1)); }, L = (e, t) => typeof S == "function" ? S(e, t) : !0, R = (e) => { let t = j(e.target); if (t === 0 && e.target.value.length > 1) { let { finalValue: t, isCompleted: n } = k(e.target.value); y?.(t), n && x?.(t), F(t.length - 1); return; } let n = e.target.value[0] || "", r = n; r && !L(r, t) && (r = ""); let i = N(t, r); y?.(i); let { isCompleted: a, finalValue: o } = k(i); a && x?.(o), r === "" ? n === "" && i.length <= t && F(t - 1) : i.length - 1 < t ? F(i.length) : I(t); }, z = (e) => { let t = e.target, n = t.selectionStart, r = t.selectionEnd, i = j(t), a = n === 0 && r === 0; if (t.value === e.key) e.preventDefault(), I(i); else if (s.backspace === e.key) { if (!t.value) e.preventDefault(), F(i - 1); else if (a) { e.preventDefault(); let t = N(i, ""); y?.(t), t.length <= i && F(i - 1); } } else s.left === e.key ? (e.preventDefault(), F(i - 1)) : s.right === e.key ? (e.preventDefault(), F(i + 1)) : s.home === e.key ? (e.preventDefault(), F(0)) : s.end === e.key && (e.preventDefault(), F(A.length - 1)); }, B = (e) => { let t = e.clipboardData.getData("text/plain"), n = e.target, r = A.findIndex(({ character: e, inputRef: t }) => e === "" || t.current === n), i = u(f(M(), m(t), r).map((e, t) => L(e, t) ? e : "")); y?.(i); let { isCompleted: a, finalValue: o } = k(i); a ? (x?.(o), F(d - 1)) : F(i.length); }, V = (e) => { if (!A.some(({ inputRef: t }) => t.current === e.relatedTarget)) { let { isCompleted: e, finalValue: t } = k(a); w?.(t, e); } }; return /* @__PURE__ */ r(i, { sx: [_, ...T ? [T].flat() : []], ref: n, className: `MuiOtpInput-Box ${C || ""}`, ...E, children: A.map(({ character: e, inputRef: t }, n) => { let { onPaste: i, onFocus: a, onKeyDown: s, className: c, onBlur: l, inputRef: u, ...d } = typeof b == "function" ? b(n) || {} : b || {}; return /* @__PURE__ */ r(o, { autoFocus: v ? n === 0 : !1, autoComplete: "one-time-code", value: e, inputRef: p([t, u]), className: `MuiOtpInput-TextField MuiOtpInput-TextField-${n + 1} ${c || ""}`, onPaste: (e) => { e.preventDefault(), B(e), i?.(e); }, onFocus: (e) => { e.preventDefault(), e.target.select(), a?.(e); }, onChange: R, onKeyDown: (e) => { z(e), s?.(e); }, onBlur: (e) => { l?.(e), V(e); }, ...d }, n); }) }); }); //#endregion export { v as MuiOtpInput };