Update OTP Field with Resend OTP

This commit is contained in:
2025-08-21 14:55:21 +05:30
parent 92b05197b3
commit 73b6b55ed4
+13 -10
View File
@@ -49,9 +49,12 @@ const boxBase =
const groupCls = "wr:flex wr:items-center wr:gap-2 wr:select-none"; const groupCls = "wr:flex wr:items-center wr:gap-2 wr:select-none";
const resendLabel = p.resendLabel ?? "Resend code"; const resendLabel = p.resendLabel ?? "Resend code";
const containerId = `otp-${Math.random().toString(36).slice(2)}`;
--- ---
<div <div
id={containerId}
class="wr:flex wr:items-center wr:justify-between wr:flex-col wr:md:flex-row" class="wr:flex wr:items-center wr:justify-between wr:flex-col wr:md:flex-row"
> >
<div class={cn("wr:space-y-1.5", p.class)} data-field={p.name}> <div class={cn("wr:space-y-1.5", p.class)} data-field={p.name}>
@@ -159,6 +162,7 @@ const resendLabel = p.resendLabel ?? "Resend code";
<script <script
is:inline is:inline
define:vars={{ define:vars={{
containerId,
onResend: p.onResend ?? "", onResend: p.onResend ?? "",
showResend: p.resendEnabled ?? false, showResend: p.resendEnabled ?? false,
resendCooldown: p.resendCooldown ?? 0, resendCooldown: p.resendCooldown ?? 0,
@@ -316,16 +320,17 @@ const resendLabel = p.resendLabel ?? "Resend code";
} }
// Resend // Resend
const host = document.getElementById(containerId);
const btnSel = "[data-otp-resend]"; const btnSel = "[data-otp-resend]";
const timerEl = document.querySelector("[data-otp-timer]"); const timerEl = host.querySelector("[data-otp-timer]");
let cooldownTimer = 0; let cooldownTimer = 0;
let remaining = 0; let remaining = 0;
const baseLabel = const baseLabel =
document.querySelector(btnSel)?.textContent?.trim() || "Resend"; host.querySelector(btnSel)?.textContent?.trim() || "Resend";
function setResendState({ disabled, label }) { function setResendState({ disabled, label }) {
const btn = document.querySelector(btnSel); const btn = host.querySelector(btnSel);
if (!btn) return; if (!btn) return;
btn.disabled = !!disabled; btn.disabled = !!disabled;
if (label != null) btn.textContent = label; if (label != null) btn.textContent = label;
@@ -359,9 +364,9 @@ const resendLabel = p.resendLabel ?? "Resend code";
} }
// Delegate click so it works even if button is conditionally rendered // Delegate click so it works even if button is conditionally rendered
document.addEventListener("click", async (e) => { host.addEventListener("click", async (e) => {
const btn = e.target?.closest?.(btnSel); const btn = e.target?.closest?.(btnSel);
if (!btn || !document.contains(btn)) return; if (!btn || !host.contains(btn)) return;
// Do nothing if already cooling down // Do nothing if already cooling down
if (btn.disabled) return; if (btn.disabled) return;
@@ -374,17 +379,15 @@ const resendLabel = p.resendLabel ?? "Resend code";
if (typeof fn === "function") { if (typeof fn === "function") {
// you can pass context if you like // you can pass context if you like
const value = Array.from( const value = Array.from(
document.querySelectorAll("[data-otp-slot]"), host.querySelectorAll("[data-otp-slot]"),
) )
.map((i) => i.value || "") .map((i) => i.value || "")
.join(""); .join("");
const res = await fn({ document, length, value }); const res = await fn({ host, length, value });
if (res === false) ok = false; // let user cancel cooldown if (res === false) ok = false; // let user cancel cooldown
} else { } else {
// fire a custom event as a fallback // fire a custom event as a fallback
document.dispatchEvent( host.dispatchEvent(new CustomEvent("wr:otp-resend"));
new CustomEvent("wr:otp-resend"),
);
} }
} catch { } catch {
ok = false; ok = false;