Page Sections

Auth Pages

A sign-in / sign-up page pair with form motion — fields expanding and collapsing, heading and button text morphing, and a submit loading state.

This is a WebberUI Pro component

The install command below needs a licence to run; without one it returns 401.

How to install Pro components →See the plans →

Bring this into your project

Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.

npx webberui@latest add "https://webberui.com/r/auth-pages.en.json?t=<install token>"

New project or installation trouble? Start here →

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

Active edited usageDefault props
<AuthPages/>

The complete example includes the preview layout and data. Install the component first, then paste this file into your project.

Installation

npx webberui@latest add "https://webberui.com/r/auth-pages.en.json?t=<install token>"

Or, once registries are configured in components.json, install it as @webberui/auth-pages.

Usage

import { AuthPages } from "@/components/ui/auth-pages";
import { Apple, Mail } from "lucide-react";

<AuthPages
  defaultMode="login"
  onSubmit={async (mode, values) => {
    await signIn(mode, values);
  }}
  onSocial={(id) => oauth(id)}
  socialProviders={[
    { id: "email", label: "Email", icon: Mail },
    { id: "apple", label: "Apple", icon: Apple },
  ]}
/>;

Controlled mode

When mode is not passed, the component manages the sign-in / sign-up state itself (uncontrolled mode). To keep it in sync with routing or external state, switch to the controlled form:

const [mode, setMode] = React.useState<AuthMode>("login");

<AuthPages mode={mode} onModeChange={setMode} onSubmit={handleSubmit} />;

The split style

variant="split" adds a brand sidebar with a flowing gradient on the left on wide screens, collapsing automatically into a single-column card on narrow ones. Use aside to override the sidebar's content.

<AuthPages variant="split" aside={<MyBrandPanel />} onSubmit={handleSubmit} />;

Props

PropTypeDefaultDescription
mode"login" | "signup"—The current mode in controlled mode; when omitted, the component is uncontrolled
defaultMode"login" | "signup""login"Initial mode in uncontrolled mode
onModeChange(mode) => void—Fires when the mode switches
onSubmit(mode, values) => void | Promise<void>—Submits the form; when it returns a Promise, the loading state is shown
onSocial(providerId) => void—Fires when a social sign-in button is clicked
variant"card" | "split""card"Layout style
brandReactNode—The brand block at the top of the card
socialProvidersAuthSocialProvider[]—The social sign-in list; leave it empty to hide it
asideReactNode—Sidebar content for the split style
classNamestring—Styles for the outer container

The values in onSubmit are AuthSubmitValues: in sign-in mode they contain email, password, and remember; in sign-up mode they contain name, email, password, and confirmPassword instead.

How it works

  • On mount, the card's contents fade in and slide up one after another with a stagger
  • When the mode switches, the name and confirm-password fields spring their height open and closed, and the sign-in-only "remember me / forgot password" row is swapped in step
  • The heading and the submit button's text change with a morph transition, and a spinning loading icon is shown while submitting

Accessibility

  • The form is associated with the heading through aria-labelledby, and every field has a matching <label> and autoComplete
  • The show-password toggle is a real button with an aria-label and aria-pressed
  • Pressing Enter mid-composition does not accidentally submit the form during IME composition in Chinese and other languages (including the Safari keyCode 229 case)
  • When the user has "reduce motion" enabled, the reveal, the field expansion, and the text morph all switch instantly instead, and the sidebar gradient stops flowing