Login Form
Email and password, with somewhere for SSO buttons and an error. The error is announced, not just coloured — a failed sign-in that only turns red is invisible to a screen reader.
src/components/ui/login-form.tsxAbout
From the component's own source, where it was written.
Email and password sign-in, with providers.
The error is deliberately generic and lives above the form, not on a field. "No account with that email" tells an attacker which addresses are registered; a single "those details do not match" on the form as a whole leaks nothing and is what every audited implementation does.
Field names and autocomplete tokens are the real ones — username and current-password — because password managers key off them, and a login form they cannot fill is one people work around by choosing weaker passwords.
Install
npx astralyx-ui add login-form
Usage
import { LoginForm } from '@/components/ui/login-form'
<LoginForm onSubmit={signIn} onForgot={reset} error={error} />Composer
Change the props and the source below follows.
<LoginForm onSubmit={signIn} onForgot={reset} error={error} />Examples
With SSO providers and a failure
<LoginForm
error="Those credentials did not match an account."
providers={<><Button variant="secondary">GitHub</Button><Button variant="secondary">Google</Button></>}
onForgot={() => navigate('/reset')}
/>Submitting
<LoginForm loading submitLabel="Signing in…" />
API
Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.
LoginForm
Email and password sign-in, with providers.
Extends Omit<ComponentProps<'form'>, 'onSubmit' | 'title'>.
| Prop | Type | Default | Description |
|---|---|---|---|
| onSubmit | (credentials: { email: string; password: string }) => void | — | Called on submit with the two values. The form never navigates on its own. |
| onForgot | () => void | — | — |
| providers | ReactNode | — | Slot for SSO or OAuth buttons, placed above the fields — where people who use them actually look. |
| error | ReactNode | — | Rendered in a live region above the fields and referenced by aria-describedby, so it is read on failure rather than merely seen. |
| loading | boolean | false | Disables the submit button and shows a spinner. The fields stay enabled, so a slow request does not eat a correction. |
| title | ReactNode | 'Sign in' | — |
| description | ReactNode | — | — |
| footer | ReactNode | — | — |
| emailLabel | ReactNode | 'Email' | — |
| passwordLabel | ReactNode | 'Password' | — |
| forgotLabel | ReactNode | 'Forgot password?' | — |
| submitLabel | ReactNode | 'Sign in' | — |
| dividerLabel | ReactNode | 'or' | Separates the provider buttons from the fields. |
| titleAs | 'h1' | 'h2' | 'h3' | 'p' | 'h2' | Element for the title. |
Behaviour
| Topic | Detail | Description |
|---|---|---|
| autocomplete | set | username and current-password, which is what lets a password manager fill both in one gesture. |