UNPKG

@frank-auth/react

Version:

Flexible and customizable React UI components for Frank Authentication

310 lines (309 loc) 9.16 kB
'use client'; import { jsx as e, jsxs as d } from "react/jsx-runtime"; import "@emotion/styled"; import { Button as A } from "../../ui/button/button.js"; import { Input as B } from "../../ui/input/input.js"; import { Chip as M } from "../../ui/chip/chip.js"; import { Alert as z } from "../../ui/alert/alert.js"; import { Progress as L } from "../../ui/progress/progress.js"; import { useConfig as R } from "../../../hooks/use-config.js"; import { XCircleIcon as I, ClockIcon as p, CheckCircleIcon as $, ExclamationTriangleIcon as K } from "@heroicons/react/24/outline"; import { useEffect as y, useRef as F, useState as U } from "react"; import { withErrorBoundary as w } from "./error-boundary.js"; const W = w(function({ value: c, onChange: a, length: r = 6, disabled: f = !1, placeholder: l = "Enter code", type: N = "text", className: u, autoFocus: v = !0, onComplete: C, size: g = "md", radius: h = "md" }) { const o = F([]), [V, m] = U(0), { components: S } = R(), j = S.Input ?? B; y(() => { o.current = o.current.slice(0, r); }, [r]), y(() => { const s = c.split(""); o.current.forEach((n, t) => { n && (n.value = s[t] || ""); }), c.length === r && C?.(c); }, [c, r, C]), y(() => { v && o.current[0] && !f && o.current[0].focus(); }, [v, f]); const k = (s, n) => { const t = n.replace(/\D/g, "").slice(-1), i = c.split(""); for (i[s] = t; i.length < r; ) i.push(""); const P = i.join("").slice(0, r); if (a(P), t && s < r - 1) { const b = o.current[s + 1]; b && (b.focus(), m(s + 1)); } }, D = (s, n) => { if (n.key === "Backspace") if (!c[s] && s > 0) { const t = o.current[s - 1]; if (t) { t.focus(), m(s - 1); const i = c.split(""); i[s - 1] = "", a(i.join("")); } } else { const t = c.split(""); t[s] = "", a(t.join("")); } else if (n.key === "ArrowLeft" && s > 0) { const t = o.current[s - 1]; t && (t.focus(), m(s - 1)); } else if (n.key === "ArrowRight" && s < r - 1) { const t = o.current[s + 1]; t && (t.focus(), m(s + 1)); } }, E = (s) => { s.preventDefault(); const n = s.clipboardData.getData("text").replace(/\D/g, "").slice(0, r); a(n); const t = Math.min(n.length, r - 1), i = o.current[t]; i && (i.focus(), m(t)); }; return /* @__PURE__ */ e("div", { className: `flex gap-2 justify-center ${u || ""}`, children: Array.from({ length: r }, (s, n) => /* @__PURE__ */ e( j, { ref: (t) => o.current[n] = t, type: N, inputMode: "numeric", pattern: "[0-9]*", maxLength: 1, className: "w-12 h-12", classNames: { input: "text-center text-lg font-mono", inputWrapper: `h-12 ${V === n ? "ring-2 ring-primary" : ""}` }, placeholder: n === 0 ? l : "", disabled: f, onChange: (t) => k(n, t.target.value), onKeyDown: (t) => D(n, t), onPaste: E, onFocus: () => m(n), variant: "bordered", size: g, radius: h }, n )) }); }), X = w(function({ totalTime: c, remainingTime: a, onExpired: r, showProgress: f = !0, format: l = "mm:ss", className: N, radius: u = "sm" }) { y(() => { a === 0 && r?.(); }, [a, r]); const v = (h) => { if (l === "seconds") return `${h}s`; const o = Math.floor(h / 60), V = h % 60; return `${o.toString().padStart(2, "0")}:${V.toString().padStart(2, "0")}`; }, C = c > 0 ? (c - a) / c * 100 : 0, g = a <= 30; return /* @__PURE__ */ d("div", { className: `flex items-center gap-3 ${N || ""}`, children: [ /* @__PURE__ */ e( p, { className: `h-4 w-4 ${g ? "text-warning" : "text-default-500"}` } ), /* @__PURE__ */ d("div", { className: "flex-1", children: [ /* @__PURE__ */ d("div", { className: "flex items-center justify-between mb-1", children: [ /* @__PURE__ */ e("span", { className: "text-sm text-default-500", children: "Code expires in" }), /* @__PURE__ */ e( "span", { className: `text-sm font-mono ${g ? "text-warning" : "text-default-700"}`, children: v(a) } ) ] }), f && /* @__PURE__ */ e( L, { value: C, color: g ? "warning" : "primary", size: "sm", className: "w-full", radius: u } ) ] }) ] }); }), _ = w(function({ error: c, onRetry: a, className: r }) { return /* @__PURE__ */ e( z, { icon: /* @__PURE__ */ e(K, { className: "h-4 w-4" }), color: "danger", variant: "flat", className: r, children: /* @__PURE__ */ d("span", { className: "flex items-center justify-between w-full", children: [ /* @__PURE__ */ e("span", { children: c }), a && /* @__PURE__ */ e( A, { size: "sm", color: "danger", variant: "light", onClick: a, className: "ml-2", children: "Retry" } ) ] }) } ); }), q = w(function({ status: c, method: a = "email", className: r }) { const l = (() => { switch (c) { case "pending": return { color: "default", icon: /* @__PURE__ */ e(p, { className: "h-3 w-3" }), text: "Pending" }; case "sent": return { color: "primary", icon: /* @__PURE__ */ e(p, { className: "h-3 w-3" }), text: `Code sent ${a === "email" ? "via email" : a === "phone" ? "via SMS" : ""}` }; case "verifying": return { color: "primary", icon: /* @__PURE__ */ e(p, { className: "h-3 w-3" }), text: "Verifying..." }; case "verified": return { color: "success", icon: /* @__PURE__ */ e($, { className: "h-3 w-3" }), text: "Verified" }; case "error": return { color: "danger", icon: /* @__PURE__ */ e(I, { className: "h-3 w-3" }), text: "Failed" }; case "expired": return { color: "warning", icon: /* @__PURE__ */ e(I, { className: "h-3 w-3" }), text: "Expired" }; default: return { color: "default", icon: /* @__PURE__ */ e(p, { className: "h-3 w-3" }), text: "Unknown" }; } })(); return /* @__PURE__ */ e( M, { color: l.color, variant: "flat", size: "sm", startContent: l.icon, className: r, children: l.text } ); }), G = w( function({ steps: c, className: a }) { return /* @__PURE__ */ e("div", { className: `space-y-4 ${a || ""}`, children: c.map((r, f) => { const l = f === c.length - 1, u = (() => { switch (r.status) { case "completed": return { color: "success", icon: /* @__PURE__ */ e($, { className: "h-5 w-5" }), bgClass: "bg-success", textClass: "text-success" }; case "active": return { color: "primary", icon: /* @__PURE__ */ e(p, { className: "h-5 w-5" }), bgClass: "bg-primary", textClass: "text-primary" }; case "error": return { color: "danger", icon: /* @__PURE__ */ e(I, { className: "h-5 w-5" }), bgClass: "bg-danger", textClass: "text-danger" }; default: return { color: "default", icon: /* @__PURE__ */ e("div", { className: "h-5 w-5 rounded-full border-2 border-default-300" }), bgClass: "bg-default-200", textClass: "text-default-500" }; } })(); return /* @__PURE__ */ d("div", { className: "flex items-center", children: [ /* @__PURE__ */ d("div", { className: "flex items-center", children: [ /* @__PURE__ */ e( "div", { className: `flex items-center justify-center w-8 h-8 rounded-full ${u.bgClass} text-white`, children: u.icon } ), /* @__PURE__ */ e("div", { className: "ml-4", children: /* @__PURE__ */ e("div", { className: `text-sm font-medium ${u.textClass}`, children: r.label }) }) ] }), !l && /* @__PURE__ */ e("div", { className: "flex-1 ml-4", children: /* @__PURE__ */ e( "div", { className: `h-0.5 ${r.status === "completed" ? "bg-success" : "bg-default-200"}` } ) }) ] }, r.id); }) }); } ), ce = { VerificationInput: W, VerificationTimer: X, VerificationError: _, VerificationBadge: q, VerificationProgress: G }; export { q as Verification, ce as VerificationCommon, _ as VerificationError, W as VerificationInput, G as VerificationProgress, X as VerificationTimer }; //# sourceMappingURL=verification.js.map