Components / Blocks

SignupForm

An account creation flow with field validation, password strength, and a clear completion state.

Install

npx shadcn@latest add https://irisui.dev/r/signup-form.json
import { SignupForm } from "@/components/iris/blocks/signup-form/signup-form";
Registry item signup-formBrings in foundationRegistry JSON

Preview

SignupForm

An account creation card with single sign-on buttons, inline field validation, a password strength meter and a confirmation step it morphs into after a successful submit.

When to use

  • The sign up page or modal of a product, where name, email and password are all you collect up front.
  • When you want validation that waits until a field is touched, and a clear "account created" state without a page change.
  • Not for returning users: use SignIn (email code) or LoginCentered (passkey first, full page).
  • Not for multi-step onboarding with extra questions; follow the done state with OnboardingChecklist or your own flow.

Usage

import { SignupForm } from "@/components/iris/blocks/signup-form/signup-form";

h(SignupForm, {
  onSubmit: async ({ name, email, password, productUpdates }) => {
    await api.createAccount({ name, email, password, productUpdates }); // throw to show an error
  },
  serverError: null,
  onProvider: (provider) => startOAuth(provider), // "Google" | "Apple" | "GitHub"
});

Props

Prop Type Default Description
onSubmit (details: SignupDetails) => void | Promise<void> none Called once every field is valid with { name, email, password, productUpdates }. Throw or reject to show the error message above the button; resolve to show the done step.
serverError string | null none An error from your API, shown above the submit button.
onProvider (provider: "Google" | "Apple" | "GitHub") => void none Called when a single sign-on button is pressed. The block then simulates the redirect and shows the done step after about 900 ms.

Notes

  • Fields: full name (2+ characters), email (pattern check), password (8+ characters, strength scored 1 to 4 on length, mixed case and digits or symbols). Errors appear on blur once a field has a value, or for every field on submit, and focus moves to the first invalid field.
  • The done step's heading receives focus; status changes are announced through a polite live region. The password feedback line is wired with aria-describedby and becomes role="alert" on error.
  • Motion: steps cross-fade sideways with a small blur and the card height springs between steps. Under reduced motion the steps only fade and the height jumps.
  • Hard-coded content: the provider row always shows Google, Apple and GitHub with their official marks (the four-colour Google "G", Apple and GitHub glyphs); there is no prop to change or hide them. The sample product is MyRoomie: the section's accessible name is "Create a MyRoomie account" and the intro reads "Find a room or a flatmate". The "Terms", "Privacy policy" and "Sign in" links only update the status line, so wire real navigation by wrapping or forking the block.
  • Reads --surface, --line, --ink and the button, input, checkbox and password field tokens. The strength meter fills red, orange, accent and green for scores 1 to 4.