Multi-Step Auth Card
Animation-first enterprise auth flow: email discovery, first-time and returning user paths, password create/login, and OTP verification with spring transitions between steps.
UniqueUI CLI
npx uniqueui add multi-step-auth-card
shadcn CLI
npx shadcn@latest add https://uniqueui.com/r/multi-step-auth-card.json -y
shadcn path expects @/lib/utils (run shadcn init first). Same source file is installed to components/ui/.
Preview
Usage
"use client";
import { MultiStepAuthCard } from "@/components/ui/multi-step-auth-card";
export default function Example() {
return (
<div className="flex min-h-[400px] items-center justify-center p-8">
<MultiStepAuthCard
strings={{
email: { titleSignIn: "Log in", continue: "Continue" },
}}
otpResendCooldownSeconds={45}
onSubmitEmail={async (email) => {
const res = await fetch("/api/auth/lookup", {
method: "POST",
body: JSON.stringify({ email }),
}).then((r) => r.json());
return { exists: res.exists, registered: res.registered };
}}
/>
</div>
);
}Props
| Prop | Type | Description |
|---|---|---|
className | string | Additional Tailwind classes for the outer card container. |
initialState | AuthState | Starting step: "email" | "unregistered" | "first-time" | "create-password" | "password-login" | "otp". |
onStateChange | (state: AuthState) => void | Called whenever the active auth step changes. |
onSubmitEmail | (email: string) => Promise<{ exists: boolean; registered: boolean }> | If provided, drives routing after email submit; otherwise demo heuristics apply (e.g. email containing "new" or "err"). |
onSubmitPassword | (password: string) => Promise<boolean | void> | Called on password login submit. Return false to stay on this step and show an error; any other return (including void) advances to OTP on success. |
onCreatePassword | (password: string) => Promise<boolean | void> | Called when saving a new password. Return false to stay on this step and show an error; otherwise advance to OTP. |
onSubmitOTP | (otp: string) => Promise<boolean | void> | Called when the user submits a six-digit code. Return false to show an invalid-code message without leaving the step. |
onResendOTP | () => Promise<boolean | void> | Optional resend handler. Return false to keep the current timer and code; on throw or false, resend count is not incremented. |
strings | MultiStepAuthStringsPartial | Deep-partial overrides for all UI copy; defaults are exported as MULTI_STEP_AUTH_DEFAULT_STRINGS for reference and i18n. |
otpResendCooldownSeconds | number | Countdown length before the resend action is available again. |
otpMaxResends | number | Maximum resend taps before the UI locks resend. |
demoEmailDelayMs | number | Artificial delay after email submit when onSubmitEmail is omitted (demo mode). |
demoPasswordDelayMs | number | Artificial delay after password/OTP demo submits when the matching handler is omitted. |
requireTermsConsent | boolean | When true, the initial email step shows a terms/privacy checkbox and blocks submit until it is checked. Set false to hide it. |
termsUrl | string | URL for the 'Terms of Service' consent link. |
privacyUrl | string | URL for the 'Privacy Policy' consent link. |