Blocks
Authentification
A collection of authentification components.
Simple Login Form
Open in
Log in
Enter your email below to login to your account
Don't have an account?
'use client'
import { toast } from 'sonner'
import { Button } from '@/components/ui/button'
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { useForm } from '@/registry/ui/form'
export const LoginForm = () => {
const form = useForm({
defaultValues: { email: '', password: '' },
validator: (value) => {
const issues = []
if (!value.email)
issues.push({ path: ['email'], message: 'Email is required' })
if (!value.password)
issues.push({ path: ['password'], message: 'Password is required' })
if (issues.length > 0) return { issues }
return { value }
},
onSubmit: async (values) => {
await new Promise((resolve) => setTimeout(resolve, 1000))
return values
},
onError: (e) => toast.error(e.message),
onSuccess: (data) =>
toast('Login successful', {
description: (
<pre className="bg-background mt-2 w-[calc(100svh-37rem)] overflow-x-auto rounded-md p-4 md:w-[320px]">
<code className="text-foreground">
{JSON.stringify(data, null, 2)}
</code>
</pre>
),
}),
})
return (
<Card className="w-svh max-w-md overflow-hidden">
<CardHeader>
<CardTitle>Log in</CardTitle>
<CardDescription>
Enter your email below to login to your account
</CardDescription>
</CardHeader>
<CardContent>
<form
className="grid gap-4"
onSubmit={(e) => {
e.preventDefault()
e.stopPropagation()
form.handleSubmit()
}}
>
<form.Field
name="email"
render={({ field, meta }) => (
<div id={meta.id} className="grid gap-2">
<form.Label>Email</form.Label>
<form.Control {...field}>
<Input type="email" placeholder="yuki@gmail.com" />
</form.Control>
<form.Message />
</div>
)}
/>
<form.Field
name="password"
render={({ field, meta }) => (
<div id={meta.id} className="grid gap-2">
<div className="flex items-center justify-between">
<form.Label>Password</form.Label>
<a
href="https://youtube.com/watch?v=dQw4w9WgXcQ"
className="text-sm underline-offset-4 hover:underline"
>
Forgot your password?
</a>
</div>
<form.Control {...field}>
<Input type="password" />
</form.Control>
<form.Message />
</div>
)}
/>
<Button disabled={form.state.isPending}>Login</Button>
</form>
</CardContent>
<CardFooter className="flex-col">
<Button variant="outline" className="w-full">
Login with Google
</Button>
<p>
Don't have an account?{' '}
<Button variant="link" className="p-0">
Sign Up
</Button>
</p>
</CardFooter>
</Card>
)
}
npx shadcn@latest add https://yuki-ui.vercel.app/r/login-form.json
npx shadcn@latest add https://yuki-ui.vercel.app/r/login-form.json
pnpm dlx shadcn@latest add https://yuki-ui.vercel.app/r/login-form.json
bunx --bun shadcn@latest add https://yuki-ui.vercel.app/r/login-form.json
Typography
Typography is the art and technique of arranging type to make written language legible, readable, and appealing when displayed.
Internationalization
A lightweight, type-safe internationalization library built from scratch for modern web applications with multi-language support and locale management.