{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "login", "title": "Login Form", "description": "A dark-themed login form with email/password fields, show/hide password toggle, Google OAuth button, forgot password link, and loading state.", "dependencies": [], "registryDependencies": [], "files": [ { "path": "registry/default/login/login.tsx", "content": "\"use client\";\r\n\r\nimport * as React from \"react\";\r\nimport { useState } from \"react\";\r\nimport { cn } from \"@/lib/utils\";\r\n\r\nexport interface LoginFormProps {\r\n onSubmit?: (values: { email: string; password: string }) => void;\r\n onGoogleSignIn?: () => void;\r\n onForgotPassword?: () => void;\r\n onSignUp?: () => void;\r\n className?: string;\r\n}\r\n\r\nexport function LoginForm({\r\n onSubmit,\r\n onGoogleSignIn,\r\n onForgotPassword,\r\n onSignUp,\r\n className,\r\n}: LoginFormProps) {\r\n const [email, setEmail] = useState(\"\");\r\n const [password, setPassword] = useState(\"\");\r\n const [showPassword, setShowPassword] = useState(false);\r\n const [loading, setLoading] = useState(false);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setLoading(true);\r\n await onSubmit?.({ email, password });\r\n setLoading(false);\r\n };\r\n\r\n return (\r\n \r\n {/* Header */}\r\n
\r\n
\r\n \r\n \r\n \r\n
\r\n

Welcome back

\r\n

Sign in to your account to continue

\r\n
\r\n\r\n {/* Google Sign-In */}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n Continue with Google\r\n \r\n\r\n {/* Divider */}\r\n
\r\n
\r\n
\r\n
\r\n
\r\n or continue with email\r\n
\r\n
\r\n\r\n {/* Form */}\r\n
\r\n {/* Email */}\r\n
\r\n \r\n setEmail(e.target.value)}\r\n placeholder=\"you@example.com\"\r\n className=\"w-full rounded-xl border border-white/10 bg-white/5 px-4 py-2.5 text-sm text-white placeholder-neutral-600 outline-none transition-all focus:border-white/25 focus:bg-white/8 focus:ring-0\"\r\n />\r\n
\r\n\r\n {/* Password */}\r\n
\r\n
\r\n \r\n \r\n Forgot password?\r\n \r\n
\r\n
\r\n setPassword(e.target.value)}\r\n placeholder=\"••••••••\"\r\n className=\"w-full rounded-xl border border-white/10 bg-white/5 px-4 py-2.5 pr-10 text-sm text-white placeholder-neutral-600 outline-none transition-all focus:border-white/25 focus:bg-white/8 focus:ring-0\"\r\n />\r\n setShowPassword((v) => !v)}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 text-neutral-600 hover:text-neutral-300 transition-colors\"\r\n tabIndex={-1}\r\n >\r\n {showPassword ? (\r\n \r\n \r\n \r\n ) : (\r\n \r\n \r\n \r\n \r\n )}\r\n \r\n
\r\n
\r\n\r\n {/* Submit */}\r\n \r\n {loading ? (\r\n \r\n \r\n \r\n \r\n \r\n Signing in…\r\n \r\n ) : (\r\n \"Sign in\"\r\n )}\r\n \r\n \r\n\r\n {/* Footer */}\r\n

\r\n Don't have an account?{\" \"}\r\n \r\n Sign up\r\n \r\n

\r\n
\r\n );\r\n}\r\n", "type": "registry:component", "target": "" } ], "type": "registry:block" }