Centered Card Sign-in
A centred login card with email, a toggleable password field and a submit button.
3 फ्रेमवर्कशुरुआती
A login card in its error state, with a role="alert" banner and an aria-invalid password field.
<!--
The error state, done properly. The alert is role="alert" so it is announced
the moment it appears; the password field carries aria-invalid="true" and
aria-describedby pointing at the message, so a screen reader ties the two
together. Colour is a redundant cue, never the only one - the text says what is
wrong.
-->
<form class="mx-auto w-full max-w-sm space-y-4 rounded-2xl border border-gray-200 bg-white p-6 shadow-sm sm:p-8 dark:border-gray-800 dark:bg-gray-950" action="#" method="post">
<h1 class="text-xl font-bold tracking-tight text-gray-900 dark:text-gray-100">Sign in</h1>
<div role="alert" class="flex items-start gap-2 rounded-lg border border-red-200 bg-red-50 px-3.5 py-2.5 text-sm text-red-700 dark:border-red-900/60 dark:bg-red-950/40 dark:text-red-300">
<span aria-hidden="true" class="mt-px font-bold">!</span>
<span>That email and password don't match. Try again.</span>
</div>
<div>
<label for="err-email" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Email</label>
<input id="err-email" name="email" type="email" autocomplete="email" required placeholder="you@company.com" class="mt-1.5 w-full rounded-lg border border-gray-300 bg-white px-3.5 py-2.5 text-sm text-gray-900 placeholder:text-gray-500 focus-visible:border-transparent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100 dark:placeholder:text-gray-400 dark:focus-visible:ring-blue-400" />
</div>
<div>
<label for="err-password" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Password</label>
<input id="err-password" name="password" type="password" autocomplete="current-password" required aria-invalid="true" aria-describedby="err-password-msg" placeholder="••••••••" class="mt-1.5 w-full rounded-lg border border-red-400 bg-white px-3.5 py-2.5 text-sm text-gray-900 placeholder:text-gray-500 focus-visible:border-transparent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-500 dark:border-red-500 dark:bg-gray-900 dark:text-gray-100 dark:placeholder:text-gray-400 dark:focus-visible:ring-red-400" />
<p id="err-password-msg" class="mt-1.5 text-xs text-red-600 dark:text-red-400">Check your password and try again.</p>
</div>
<button type="submit" class="w-full rounded-lg bg-blue-600 px-5 py-2.5 text-sm font-semibold text-white transition-colors hover:bg-blue-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2 focus-visible:ring-offset-white motion-reduce:transition-none dark:focus-visible:ring-blue-400 dark:focus-visible:ring-offset-gray-950">Sign in</button>
</form>| Prop | टाइप | डिफ़ॉल्ट | विवरण |
|---|---|---|---|
error | string | - | Error |
onSubmit | (data: { email: string; password: string }) => void | - | सबमिट होने पर फ़ॉर्म के मानों के साथ कॉल होता है। |
className | string | - | रूट एलिमेंट पर मर्ज होने वाली अतिरिक्त क्लासेज़। |
The banner is `role="alert"` so it is announced when it appears, and the password field carries `aria-invalid` plus `aria-describedby` pointing at the message - colour is a redundant cue, never the only one. Pass `error` to toggle the state; omit it for the clean form.