Sign up form
BlockAn account-creation form with a password strength hint and terms.
pnpm dlx shadcn@latest add https://caliperui.site/r/sign-up-form.jsonWhen to use #
Use it for
- New users create an account.
- You want live checks before they submit.
Skip it when
- Existing users are signing in; use the sign-in form.
Installation #
terminal
pnpm dlx shadcn@latest add https://caliperui.site/r/sign-up-form.json
Adds its 12 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above.
example.tsx
import { Building2, Fingerprint } from "lucide-react" import { useState } from "react" import { SignUpForm } from "@/components/ui/sign-up-form" const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); const providers = [ { id: "passkey", label: "a passkey", icon: <Fingerprint aria-hidden="true" />, onClick: () => undefined }, { id: "sso", label: "SSO", icon: <Building2 aria-hidden="true" />, onClick: () => undefined }, ]; export function SignUpFormDemo() { const [, setView] = useState<"in" | "up">("in"); const [, setDone] = useState<string | null>(null); return ( <SignUpForm description="Free for small teams. No card needed." providers={providers} signIn={{ onClick: () => setView("in") }} onSubmit={async ({ email }) => { await wait(1000); if (email === "taken@example.com") return { fields: { email: "An account with this email already exists." } }; setDone("Check your inbox"); }} /> ); }
API reference #
SignUpForm
component
PropTypeDefaultDescription
titlestring"Create your account"
descriptionstring—
onSubmit *(values: { name: string; email: string; password: string; }) => SignUpResult | Promise<SignUpResult>—
providersreadonly AuthProvider[]—
signIn{ href?: string | undefined; onClick?: (() => void) | undefined; }—
termsHrefstring—
privacyHrefstring—
minimumRulesnumber3How many password rules must be met before the form can be sent.
classNamestring—
Accessibility #
It exposes alert semantics, with aria-label, aria-invalid and aria-describedby kept in step with state. Changes that matter are announced through a live region.
No custom key handling; Tab and the native activation keys do the work.
Motion #
It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.