@frank-auth/react
Version:
Flexible and customizable React UI components for Frank Authentication
310 lines (309 loc) • 9.16 kB
JavaScript
'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