caliper uidocs

Sign up form

Block

An account-creation form with a password strength hint and terms.

Installs components/ui/sign-up-form.tsxDepends on @radix-ui/react-slot, lucide-reactMotion none in component source
pnpm dlx shadcn@latest add https://caliperui.site/r/sign-up-form.json

Create your account

Free for small teams. No card needed.

No password yet

  • At least 12 characters, not met
  • Uppercase and lowercase letters, not met
  • A number, not met
  • A symbol, not met

Already have an account? Sign in

When 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.