Login Form

Sign-in card that pairs with Signup Form — email, password and remember-me with generic SSO/passkey buttons — whose "Forgot password?" flow morphs inside the same card from requesting a code to a check-your-inbox screen with a resend cooldown, then an OTP plus new-password step and a drawn success check, with every async handler driving pending states and shaking the card on rejection.

Preview

Login Form preview width

Install

Add it with the shadcn CLI, or copy the source manually.

$ bunx --bun shadcn add @karaui/login-form
@karaui not found? Add it to components.json
{
  "registries": {
    "@karaui": "https://karaui.kamisama-v0.my.id/r/{name}.json"
  }
}

@karaui is in shadcn's public registry directory, so the latest CLI needs no setup. On an older CLI, merge this into the existing file once and every @karaui/… install resolves.

API Reference

view?
"reset" | "done" | "sign-in" | "forgot" | "sent"

Controlled screen. Omit to let the card manage its own flow.

—
defaultView?
"reset" | "done" | "sign-in" | "forgot" | "sent"
sign-in
onViewChange?
((view: LoginView) => void)
—
defaultValues?
Partial<LoginValues>
—
onSubmit?
((values: LoginValues) => void | Promise<void>)

Called with valid values. Reject (or throw) with a message to show it and shake the card.

—
providers?
LoginSocialProvider[]

Social / SSO buttons. Pass `[]` to hide the row.

[ { id: "sso", label: "SSO", icon: Building2 }, { id: "passkey", label: "Passkey", icon: Fingerprint }, ]
onProviderClick?
((id: string) => void | Promise<void>)
—
onRequestReset?
((email: string) => void | Promise<void>)

Sends the reset code. Reject to show an error on the request screen.

—
onResetPassword?
((values: LoginResetValues) => void | Promise<void>)

Verifies the code and stores the new password. Reject to shake the code.

—
codeLength?
number

Length of the emailed code. Default 6.

6
resendCooldown?
number

Seconds before "Resend code" unlocks again. Default 30.

30
title?
ReactNode
Welcome back
description?
ReactNode
Sign in to continue to your workspace.
footer?
ReactNode
—
className?
string
—

Keep in mind

Some components on this site are inspired by or recreated from existing work across the web. I'm not here to take credit; just to learn, experiment, and sometimes push things a bit further. If something looks familiar and I forgot to mention you, reach out and I'll fix that right away.

Updated