Learn and Teach Coding

Login Form UI

A clean, accessible login form component for React with email, password, and social sign-in.

ReactBeginnerformsuiauthentication

Live preview

Welcome back

Sign in to your account to continue

Don't have an account? Sign up

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 2

Build a login form component in React, then layer on hand-rolled input validation with useState.

Related examples

Beginner

React Login Form Validation

Build a login form with validation using React Hook Form and Zod.

View example
Beginner

Fetch Users from API

Fetch and display a list of users from a REST API with loading and error states.

View example