Authentication
ProThe sign-in and sign-up pair, shipped as two ready blocks: social providers, an email and password core, and the cross-link to its sibling. Sign-up adds a name field and a live password-strength meter.
Installation#
Usage#
The preview is yours to explore. Its code comes with a Pro license, paid once and used in every project.
Have a license? Unlock it here
Sign up#
SignUpForm adds a full-name field and a password-strength meter, and gates the submit on the terms checkbox.
Provider-first#
ProviderForm drops the password core for a stack of full-width Continue with… buttons: the password-less OAuth pattern. Add showEmail for a magic-link fallback below the providers.
Single provider · consent gate
Pass one provider with emphasizeFirst for a single dominant button, and requireTerms to gate it behind a consent checkbox. A social rail links out to the community: the OAuth-only screen used by game servers and Discord-native products.
Localization#
Every word the three blocks print reads from one labels dictionary, so a translation is written once and handed to all of them. Pass only the keys you change; the rest keep their English defaults. In the two provider phrases, {provider} is replaced with the provider's name wherever your language puts it. The consent sentences carry links whose words move in a translation, so they are whole nodes instead: termsLabel on SignUpForm and ProviderForm. providers picks the social row on LoginForm and SignUpForm too, and the row takes one track per provider.
Full-page screens#
Composed into complete pages, these blocks become the Authentication section family: seven finished sign-in and sign-up screens (split and centered, plus the community Discord screens), each with a full-screen, resizable device-frame preview. For a split screen, drop variant="bare" on the form and place it in a SplitLayout pane so the shell owns the surface; for a centered page, keep the default bordered card on a soft backdrop.
API reference#
LoginForm
The sign-in block: provider row, email, password, "Remember me" and a forgot-password link. Forwards native <div> props (except title and onSubmit) and accepts className, merged last, like the other two blocks.
| Prop | Type | Default | Description |
|---|---|---|---|
| title | React.ReactNode | "Welcome back" | The heading of the block. |
| description | React.ReactNode | "Sign in to your account to continue." | The line under the heading. |
| onSubmit | (data: LoginFormData) => void | Promise<void> | - | Called with { email, password, remember }. Return a promise and the submit button shows a spinner until it settles. |
| onProvider | (provider: "google" | "github" | "apple" | "discord") => void | - | Called with the provider id when a provider button is pressed. |
| showSocial | boolean | true | Shows the provider row and the divider above the email form. |
| providers | ("google" | "github" | "apple" | "discord")[] | ["google", "github", "apple"] | The provider row, left to right. |
| forgotHref | string | "#" | Target of the "Forgot password?" link. |
| signUpHref | string | "#" | Target of the "Sign up" cross-link. |
| variant | "card" | "bare" | "card" | card is the standalone ring-edged block; bare drops the edge, shadow, max-width and padding to sit in a page shell. |
| density | "comfortable" | "compact" | "compact" | Outer gap, title size and card padding (16px or 24px). Falls back to the nearest DensityProvider. |
| labels | Partial<AuthFormLabels> | - | The strings of the block, for a translation. Pass only the keys you change; provider phrases take a {provider} placeholder. |
SignUpForm
The sign-up block: adds a full-name field, a live password-strength meter and a terms checkbox that gates the submit button.
| Prop | Type | Default | Description |
|---|---|---|---|
| title | React.ReactNode | "Create your account" | The heading of the block. |
| description | React.ReactNode | "Start your free trial. No credit card required." | The line under the heading. |
| onSubmit | (data: SignUpFormData) => void | Promise<void> | - | Called with { name, email, password, acceptedTerms }. Return a promise to drive the spinner. |
| onProvider | (provider: "google" | "github" | "apple" | "discord") => void | - | Called with the provider id when a provider button is pressed. |
| showSocial | boolean | true | Shows the provider row and the divider above the email form. |
| providers | ("google" | "github" | "apple" | "discord")[] | ["google", "github", "apple"] | The provider row, left to right. |
| signInHref | string | "#" | Target of the "Sign in" cross-link. |
| termsHref | string | "#" | Target of the Terms link in the consent sentence. |
| privacyHref | string | "#" | Target of the Privacy Policy link in the consent sentence. |
| termsLabel | React.ReactNode | - | Replaces the consent sentence whole, for a translation that moves words around the links. |
| variant | "card" | "bare" | "card" | card is the standalone ring-edged block; bare drops the edge, shadow, max-width and padding to sit in a page shell. |
| density | "comfortable" | "compact" | "compact" | Outer gap, title size and card padding (16px or 24px). Falls back to the nearest DensityProvider. |
| labels | Partial<AuthFormLabels> | - | The strings of the block, for a translation. Pass only the keys you change; provider phrases take a {provider} placeholder. |
ProviderForm
The password-less, provider-first block: a stack of full-width "Continue with" buttons, with an optional magic-link email, footer and social rail.
| Prop | Type | Default | Description |
|---|---|---|---|
| title | React.ReactNode | "Welcome" | The heading of the block. |
| description | React.ReactNode | "Sign in or create your account to continue." | The line under the heading. |
| providers | ("google" | "github" | "apple" | "discord")[] | ["google", "github", "apple"] | The provider buttons, top to bottom. |
| onProvider | (provider: "google" | "github" | "apple" | "discord") => void | - | Called with the provider id when a provider button is pressed. |
| emphasizeFirst | boolean | false | Renders the first provider as the solid primary button, for a single dominant choice. |
| action | "continue" | "sign-in" | "continue" | The verb on each button: "Continue with Google" or "Sign in with Google". |
| requireTerms | boolean | false | Gates every action behind a consent checkbox the user must tick first. |
| termsLabel | React.ReactNode | - | The consent copy: the checkbox label with requireTerms, otherwise a static line under the buttons (null hides it). |
| termsHref | string | "#" | Target of the Terms link in the default consent copy. |
| privacyHref | string | "#" | Target of the Privacy Policy link in the default consent copy. |
| showEmail | boolean | false | Adds a magic-link email field under a divider. |
| emailAction | React.ReactNode | "Continue with email" | The label of the email submit button. |
| onSubmit | (email: string) => void | Promise<void> | - | Called with the email. Return a promise to drive the spinner. |
| footer | React.ReactNode | - | A cross-link line under the actions, e.g. "Don't have an account? Sign up". |
| social | { network: SocialNetwork; href: string; label?: string }[] | - | A community link rail at the very bottom. network is "x", "discord", "youtube", "instagram", "github" or "linkedin". |
| variant | "card" | "bare" | "card" | card is the standalone ring-edged block; bare drops the edge, shadow, max-width and padding to sit in a page shell. |
| density | "comfortable" | "compact" | "compact" | Outer gap, title size and card padding (16px or 24px). Falls back to the nearest DensityProvider. |
| labels | Partial<AuthFormLabels> | - | The strings of the block, for a translation. Pass only the keys you change; provider phrases take a {provider} placeholder. |