Back to Component Explorer

Minimal Sign In

signin

Ultra-clean single column authentication interface with focus state glows.

#signin#login#minimal#auth
Live Interactive Preview

Welcome Back

Sign in to access your dashboard

Forgot password?

Component Source Code

Select language in the dropdown
MinimalLogin.tsx
1'use client';
2
3import React, { useState } from 'react';
4import { Eye, EyeOff, Lock, Mail, ArrowRight } from 'lucide-react';
5
6export default function MinimalLogin() {
7 const [email, setEmail] = useState('');
8 const [password, setPassword] = useState('');
9 const [showPassword, setShowPassword] = useState(false);
10 const [rememberMe, setRememberMe] = useState(false);
11 const [error, setError] = useState('');
12 const [loading, setLoading] = useState(false);
13
14 const handleSubmit = (e: React.FormEvent) => {
15 e.preventDefault();
16 if (!email.includes('@')) {
17 setError('Please enter a valid email address.');
18 return;
19 }
20 setError('');
21 setLoading(true);
22 setTimeout(() => {
23 setLoading(false);
24 alert('Simulated Login Success!');
25 }, 1200);
26 };
27
28 return (
29 <div className="w-full max-w-md rounded-2xl border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900 p-6 sm:p-8 shadow-xl transition-colors">
30 <div className="text-center mb-6 sm:mb-8">
31 <h2 className="text-2xl font-bold tracking-tight text-slate-900 dark:text-slate-100">Welcome Back</h2>
32 <p className="mt-1 text-xs sm:text-sm text-slate-500 dark:text-slate-400">Sign in to access your dashboard</p>
33 </div>
34
35 <form onSubmit={handleSubmit} className="space-y-4">
36 {error && (
37 <div className="rounded-lg bg-rose-500/10 border border-rose-500/20 p-3 text-xs text-rose-600 dark:text-rose-400">
38 {error}
39 </div>
40 )}
41
42 <div>
43 <label className="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Email</label>
44 <div className="relative">
45 <Mail className="absolute left-3 top-2.5 h-4 w-4 text-slate-400" />
46 <input
47 type="email"
48 value={email}
49 onChange={(e) => setEmail(e.target.value)}
50 placeholder="alex@example.com"
51 required
52 className="w-full rounded-xl border border-slate-200 dark:border-slate-800 bg-slate-50 dark:bg-slate-800/60 py-2 pl-9 pr-3 text-sm text-slate-900 dark:text-slate-100 placeholder:text-slate-400 outline-none transition focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20"
53 />
54 </div>
55 </div>
56
57 <div>
58 <label className="block text-xs font-semibold text-slate-700 dark:text-slate-300 mb-1">Password</label>
59 <div className="relative">
60 <Lock className="absolute left-3 top-2.5 h-4 w-4 text-slate-400" />
61 <input
62 type={showPassword ? 'text' : 'password'}
63 value={password}
64 onChange={(e) => setPassword(e.target.value)}
65 placeholder="••••••••"
66 required
67 className="w-full rounded-xl border border-slate-200 dark:border-slate-800 bg-slate-50 dark:bg-slate-800/60 py-2 pl-9 pr-10 text-sm text-slate-900 dark:text-slate-100 placeholder:text-slate-400 outline-none transition focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20"
68 />
69 <button
70 type="button"
71 onClick={() => setShowPassword(!showPassword)}
72 className="absolute right-3 top-2.5 text-slate-400 hover:text-slate-600 dark:hover:text-slate-200"
73 >
74 {showPassword ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
75 </button>
76 </div>
77 </div>
78
79 <div className="flex flex-wrap items-center justify-between gap-2 text-xs">
80 <label className="flex items-center gap-2 cursor-pointer text-slate-600 dark:text-slate-400">
81 <input
82 type="checkbox"
83 checked={rememberMe}
84 onChange={(e) => setRememberMe(e.target.checked)}
85 className="rounded border-slate-300 dark:border-slate-700 text-blue-600 focus:ring-blue-500"
86 />
87 Remember me
88 </label>
89 <a href="#" className="font-semibold text-blue-600 dark:text-blue-400 hover:underline">
90 Forgot password?
91 </a>
92 </div>
93
94 <button
95 type="submit"
96 disabled={loading}
97 className="mt-2 flex w-full items-center justify-center gap-2 rounded-xl bg-slate-900 dark:bg-slate-100 py-2.5 text-sm font-semibold text-white dark:text-slate-900 shadow transition hover:opacity-90 active:scale-98 disabled:opacity-50"
98 >
99 {loading ? 'Authenticating...' : 'Sign In'}
100 {!loading && <ArrowRight className="h-4 w-4" />}
101 </button>
102 </form>
103 </div>
104 );
105}

Installation & Integration Guide

Step 1: Tailwind CSS v4 Setup
Tailwind Docs

If you do not have Tailwind installed yet, run this installation command:

Terminal
npm install tailwindcss @tailwindcss/postcss postcss

Then add the Tailwind directive to your main stylesheet (globals.css):

@import "tailwindcss";

Step 2: Install Icon Dependencies

npm install lucide-react react-icons

Step 3: Add Component File

Create a new file in your project at src/components/signin/MinimalLogin.tsx and paste the copied code from the source viewer above.

Step 4: Usage Example

ExamplePage.tsx
1import MinimalSignIn from '@/components/signin/MinimalLogin';
2
3export default function ExamplePage() {
4 return (
5 <main className="p-8 flex items-center justify-center min-h-screen">
6 <MinimalSignIn />
7 </main>
8 );
9}