Login Form UI
A clean, accessible login form component for React with email, password, and social sign-in.
Live preview
Welcome back
Sign in to your account to continue
Code walkthrough
This is the presentational layer of a login screen: a card with labelled inputs, a primary action, a forgot-password link, and a success state. It is fully keyboard accessible and works in light and dark mode. Below we build it up piece by piece — hit View full code above to see everything at once.
1. Component state
We track the two field values and whether the form has been submitted. Keeping the inputs in state makes them controlled — React is the single source of truth for what each field contains.
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [submitted, setSubmitted] = useState(false);2. Handling submit
On submit we call e.preventDefault() to stop the browser's full-page reload, then
flip submitted to true. In a real app this is where you'd call your auth API.
function onSubmit(e: React.FormEvent) {
e.preventDefault();
setSubmitted(true);
}Because the inputs are controlled, email and password are already available
here — no need to read them off the DOM.
3. The card and header
The outer card constrains width, adds a border and shadow, and adapts to dark mode. The header stacks an icon, a title, and a subtitle.
<div className="w-full max-w-sm rounded-2xl border border-slate-200 bg-white p-6 shadow-sm dark:border-slate-700 dark:bg-slate-900">
<div className="mb-6 text-center">
<h3 className="text-lg font-bold text-slate-900 dark:text-white">
Welcome back
</h3>
<p className="mt-1 text-sm text-slate-500 dark:text-slate-400">
Sign in to your account to continue
</p>
</div>
{/* ...fields... */}
</div>4. Accessible fields
Each input is tied to its <label> via matching htmlFor / id, so clicking the
label focuses the field and screen readers announce it correctly. type="email" and
required give us free browser validation.
<label htmlFor="lf-email" className="mb-1.5 block text-sm font-medium">
Email
</label>
<input
id="lf-email"
type="email"
required
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="you@example.com"
/>5. The success state
When submitted is true we swap the form for a confirmation message. The
role="status" attribute makes assistive tech announce it the moment it appears.
{submitted ? (
<p role="status" className="rounded-lg bg-emerald-50 px-4 py-3 text-center text-sm font-medium text-emerald-700">
Signed in as {email || "you"} 🎉
</p>
) : (
<form onSubmit={onSubmit} className="space-y-4">
{/* fields + submit button */}
</form>
)}That's the whole component. Use View full code above for the complete, copy-ready source.
Compare: Login Form in another stack
The same login screen built two ways. Compare the React component with the plain HTML + JavaScript version to see exactly what the framework does for you.
Login Form with React
Step 1 of 2Build a login form component in React, then layer on hand-rolled input validation with useState.
Related examples
React Login Form Validation
Build a login form with validation using React Hook Form and Zod.
View exampleFetch Users from API
Fetch and display a list of users from a REST API with loading and error states.
View example