Components
Auth panel
A sign-in and sign-up card made of liquid glass: a mode switch that stretches like a drop, Continue with Google, a password eye that watches you, a strength tube that fills as you type, and a button that melts into a spinner, then a check — with confetti.
Paste it into ChatGPT, Claude, Cursor or v0.
Usage
import { AuthPanel } from '@vizzele/react';
<AuthPanel
brand={<Logo />}
providers={['google']}
onProvider={(id) => signIn(id)}
onSubmit={async ({ mode, email, password, name }) => {
const res = await fetch(`/api/${mode}`, {
method: 'POST',
body: JSON.stringify({ email, password, name }),
});
// Throw to show the message and shake the card.
if (!res.ok) throw new Error('Wrong email or password');
}}
onForgot={() => router.push('/forgot')}
footer={<>By continuing you agree to our <a href="/terms">Terms</a>.</>}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
onSubmit | ({ mode, email, password, name? }) => void | Promise | — | Resolve for the success state (check + confetti); reject with an Error to show its message. |
providers | ('google' | 'github' | { id, label, icon })[] | ['google'] | Social buttons. Pass [] to hide them. |
onProvider | (id) => void | Promise | — | Return a promise to spin the provider icon until it settles. |
mode / defaultMode / onModeChange | 'sign-in' | 'sign-up' | 'sign-in' | Controlled or not. |
brand | ReactNode | — | Your logo above the title. |
title | { signIn?, signUp? } | — | Headings for each mode. |
nameField | boolean | true | Ask for a name on sign-up. |
minLength | number | 8 | Minimum password length on sign-up. |
onForgot | () => void | — | Shows "Forgot password?" on sign-in. |
celebrate | boolean | true | Confetti on success. |
footer | ReactNode | — | Small print under the form. |
Accessibility
- A real form labelled by its heading; Enter submits, the browser can autofill email and password (autocomplete is set per mode).
- Invalid fields get aria-invalid and a message tied with aria-describedby, and focus moves to the first one.
- Progress, errors and success are read out from one role="status" line; the busy button has aria-busy.
- The mode switch is two toggle buttons with aria-pressed. The hidden name field is disabled, so it is out of the tab order.
- With reduced motion the aura, rim and confetti stay still; the spinner keeps turning because it carries meaning.