New: 149+ components, Page Builder, and more
AI App Building Blocks for the Web
Clean, modern building blocks. Copy and paste into your apps. Works with all React frameworks. Open Source. Free forever.
Clean, modern building blocks. Copy and paste into your apps. Works with all React frameworks. Open Source. Free forever.
"use client"
import { Button } from "@/components/ui/button"
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card"
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"
function SignupForm({ ...props }: React.ComponentProps<typeof Card>) {
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
const formData = new FormData(e.currentTarget)
// TODO: Add your authentication logic here
console.log("Form submitted:", Object.fromEntries(formData))
// Example: await signIn(formData)
}
return (
<Card {...props}>
<CardHeader>
<CardTitle>Create an account</CardTitle>
<CardDescription>
Enter your information below to create your account
</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit}>
<FieldGroup>
<Field>
<FieldLabel htmlFor="name">Full Name</FieldLabel>
<Input
id="name"
name="name"
type="text"
placeholder="John Doe"
required
/>
</Field>
<Field>
<FieldLabel htmlFor="email">Email</FieldLabel>
<Input
id="email"
name="email"
type="email"
placeholder="m@example.com"
required
/>
<FieldDescription>
We'll use this to contact you. We will not share your email
with anyone else.
</FieldDescription>
</Field>
<Field>
<FieldLabel htmlFor="password">Password</FieldLabel>
<Input id="password" name="password" type="password" required />
<FieldDescription>
Must be at least 8 characters long.
</FieldDescription>
</Field>
<Field>
<FieldLabel htmlFor="confirm-password">
Confirm Password
</FieldLabel>
<Input
id="confirm-password"
name="confirm-password"
type="password"
required
/>
<FieldDescription>Please confirm your password.</FieldDescription>
</Field>
<FieldGroup>
<Field>
<Button type="submit">Create Account</Button>
<Button variant="outline" type="button">
Sign up with Google
</Button>
<FieldDescription className="px-6 text-center">
Already have an account? <a href="#">Sign in</a>
</FieldDescription>
</Field>
</FieldGroup>
</FieldGroup>
</form>
</CardContent>
</Card>
)
}
export function Page() {
return (
<div className="flex min-h-svh w-full items-center justify-center p-6 md:p-10">
<div className="w-full max-w-sm">
<SignupForm />
</div>
</div>
)
}


"use client"
import { GalleryVerticalEnd } from "lucide-react"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
FieldSeparator,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"
function SignupForm({
className,
...props
}: React.ComponentPropsWithoutRef<"form">) {
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
const formData = new FormData(e.currentTarget)
// TODO: Add your authentication logic here
console.log("Form submitted:", Object.fromEntries(formData))
// Example: await signIn(formData)
}
return (
<form
className={cn("flex flex-col gap-6", className)}
{...props}
onSubmit={handleSubmit}
>
<FieldGroup>
<div className="flex flex-col items-center gap-1 text-center">
<h1 className="text-2xl font-bold">Create your account</h1>
<p className="text-muted-foreground text-sm text-balance">
Fill in the form below to create your account
</p>
</div>
<Field>
<FieldLabel htmlFor="name">Full Name</FieldLabel>
<Input
id="name"
name="name"
type="text"
placeholder="John Doe"
required
/>
</Field>
<Field>
<FieldLabel htmlFor="email">Email</FieldLabel>
<Input
id="email"
name="email"
type="email"
placeholder="m@example.com"
required
/>
<FieldDescription>
We'll use this to contact you. We will not share your email
with anyone else.
</FieldDescription>
</Field>
<Field>
<FieldLabel htmlFor="password">Password</FieldLabel>
<Input id="password" name="password" type="password" required />
<FieldDescription>
Must be at least 8 characters long.
</FieldDescription>
</Field>
<Field>
<FieldLabel htmlFor="confirm-password">Confirm Password</FieldLabel>
<Input
id="confirm-password"
name="confirm-password"
type="password"
required
/>
<FieldDescription>Please confirm your password.</FieldDescription>
</Field>
<Field>
<Button type="submit">Create Account</Button>
</Field>
<FieldSeparator>Or continue with</FieldSeparator>
<Field>
<Button variant="outline" type="button">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"
fill="currentColor"
/>
</svg>
Sign up with GitHub
</Button>
<FieldDescription className="px-6 text-center">
Already have an account? <a href="#">Sign in</a>
</FieldDescription>
</Field>
</FieldGroup>
</form>
)
}
export function SignupPage() {
return (
<div className="grid min-h-svh lg:grid-cols-2">
<div className="flex flex-col gap-4 p-6 md:p-10">
<div className="flex justify-center gap-2 md:justify-start">
<a href="#" className="flex items-center gap-2 font-medium">
<div className="bg-primary text-primary-foreground flex size-6 items-center justify-center rounded-md">
<GalleryVerticalEnd className="size-4" />
</div>
Acme Inc.
</a>
</div>
<div className="flex flex-1 items-center justify-center">
<div className="w-full max-w-xs">
<SignupForm />
</div>
</div>
</div>
<div className="bg-muted relative hidden lg:block">
<img
src="/placeholder.svg"
alt="Image"
className="absolute inset-0 h-full w-full object-cover dark:brightness-[0.2] dark:grayscale"
/>
</div>
</div>
)
}


"use client"
import { GalleryVerticalEnd } from "lucide-react"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card"
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"
export function SignupPage() {
return (
<div className="bg-muted flex min-h-svh flex-col items-center justify-center gap-6 p-6 md:p-10">
<div className="flex w-full max-w-sm flex-col gap-6">
<a href="#" className="flex items-center gap-2 self-center font-medium">
<div className="bg-primary text-primary-foreground flex size-6 items-center justify-center rounded-md">
<GalleryVerticalEnd className="size-4" />
</div>
Acme Inc.
</a>
<SignupForm />
</div>
</div>
)
}
export function SignupForm({
className,
...props
}: React.ComponentPropsWithoutRef<"div">) {
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
const formData = new FormData(e.currentTarget)
// TODO: Add your authentication logic here
console.log("Form submitted:", Object.fromEntries(formData))
// Example: await signIn(formData)
}
return (
<div className={cn("flex flex-col gap-6", className)} {...props}>
<Card>
<CardHeader className="text-center">
<CardTitle className="text-xl">Create your account</CardTitle>
<CardDescription>
Enter your email below to create your account
</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit}>
<FieldGroup>
<Field>
<FieldLabel htmlFor="name">Full Name</FieldLabel>
<Input
id="name"
name="name"
type="text"
placeholder="John Doe"
required
/>
</Field>
<Field>
<FieldLabel htmlFor="email">Email</FieldLabel>
<Input
id="email"
name="email"
type="email"
placeholder="m@example.com"
required
/>
</Field>
<Field>
<Field className="grid grid-cols-2 gap-4">
<Field>
<FieldLabel htmlFor="password">Password</FieldLabel>
<Input
id="password"
name="password"
type="password"
required
/>
</Field>
<Field>
<FieldLabel htmlFor="confirm-password">
Confirm Password
</FieldLabel>
<Input
id="confirm-password"
name="confirm-password"
type="password"
required
/>
</Field>
</Field>
<FieldDescription>
Must be at least 8 characters long.
</FieldDescription>
</Field>
<Field>
<Button type="submit">Create Account</Button>
<FieldDescription className="text-center">
Already have an account? <a href="#">Sign in</a>
</FieldDescription>
</Field>
</FieldGroup>
</form>
</CardContent>
</Card>
<FieldDescription className="px-6 text-center">
By clicking continue, you agree to our <a href="#">Terms of Service</a>{" "}
and <a href="#">Privacy Policy</a>.
</FieldDescription>
</div>
)
}


"use client"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
FieldSeparator,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"
export function SignupPage() {
return (
<div className="bg-muted flex min-h-svh flex-col items-center justify-center p-6 md:p-10">
<div className="w-full max-w-sm md:max-w-4xl">
<SignupForm />
</div>
</div>
)
}
export function SignupForm({
className,
...props
}: React.ComponentPropsWithoutRef<"div">) {
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
const formData = new FormData(e.currentTarget)
// TODO: Add your authentication logic here
console.log("Form submitted:", Object.fromEntries(formData))
// Example: await signIn(formData)
}
return (
<div className={cn("flex flex-col gap-6", className)} {...props}>
<Card className="overflow-hidden p-0">
<CardContent className="grid p-0 md:grid-cols-2">
<form className="p-6 md:p-8" onSubmit={handleSubmit}>
<FieldGroup>
<div className="flex flex-col items-center gap-2 text-center">
<h1 className="text-2xl font-bold">Create your account</h1>
<p className="text-muted-foreground text-sm text-balance">
Enter your email below to create your account
</p>
</div>
<Field>
<FieldLabel htmlFor="email">Email</FieldLabel>
<Input
id="email"
name="email"
type="email"
placeholder="m@example.com"
required
/>
<FieldDescription>
We'll use this to contact you. We will not share your
email with anyone else.
</FieldDescription>
</Field>
<Field>
<Field className="grid grid-cols-2 gap-4">
<Field>
<FieldLabel htmlFor="password">Password</FieldLabel>
<Input
id="password"
name="password"
type="password"
required
/>
</Field>
<Field>
<FieldLabel htmlFor="confirm-password">
Confirm Password
</FieldLabel>
<Input
id="confirm-password"
name="confirm-password"
type="password"
required
/>
</Field>
</Field>
<FieldDescription>
Must be at least 8 characters long.
</FieldDescription>
</Field>
<Field>
<Button type="submit">Create Account</Button>
</Field>
<FieldSeparator className="*:data-[slot=field-separator-content]:bg-card">
Or continue with
</FieldSeparator>
<Field className="grid grid-cols-3 gap-4">
<Button variant="outline" type="button">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
d="M12.152 6.896c-.948 0-2.415-1.078-3.96-1.04-2.04.027-3.91 1.183-4.961 3.014-2.117 3.675-.546 9.103 1.519 12.09 1.013 1.454 2.208 3.09 3.792 3.039 1.52-.065 2.09-.987 3.935-.987 1.831 0 2.35.987 3.96.948 1.637-.026 2.676-1.48 3.676-2.948 1.156-1.688 1.636-3.325 1.662-3.415-.039-.013-3.182-1.221-3.22-4.857-.026-3.04 2.48-4.494 2.597-4.559-1.429-2.09-3.623-2.324-4.39-2.376-2-.156-3.675 1.09-4.61 1.09zM15.53 3.83c.843-1.012 1.4-2.427 1.245-3.83-1.207.052-2.662.805-3.532 1.818-.78.896-1.454 2.338-1.273 3.714 1.338.104 2.715-.688 3.559-1.701"
fill="currentColor"
/>
</svg>
<span className="sr-only">Sign up with Apple</span>
</Button>
<Button variant="outline" type="button">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
d="M12.48 10.92v3.28h7.84c-.24 1.84-.853 3.187-1.787 4.133-1.147 1.147-2.933 2.4-6.053 2.4-4.827 0-8.6-3.893-8.6-8.72s3.773-8.72 8.6-8.72c2.6 0 4.507 1.027 5.907 2.347l2.307-2.307C18.747 1.44 16.133 0 12.48 0 5.867 0 .307 5.387.307 12s5.56 12 12.173 12c3.573 0 6.267-1.173 8.373-3.36 2.16-2.16 2.84-5.213 2.84-7.667 0-.76-.053-1.467-.173-2.053H12.48z"
fill="currentColor"
/>
</svg>
<span className="sr-only">Sign up with Google</span>
</Button>
<Button variant="outline" type="button">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
d="M6.915 4.03c-1.968 0-3.683 1.28-4.871 3.113C.704 9.208 0 11.883 0 14.449c0 .706.07 1.369.21 1.973a6.624 6.624 0 0 0 .265.86 5.297 5.297 0 0 0 .371.761c.696 1.159 1.818 1.927 3.593 1.927 1.497 0 2.633-.671 3.965-2.444.76-1.012 1.144-1.626 2.663-4.32l.756-1.339.186-.325c.061.1.121.196.183.3l2.152 3.595c.724 1.21 1.665 2.556 2.47 3.314 1.046.987 1.992 1.22 3.06 1.22 1.075 0 1.876-.355 2.455-.843a3.743 3.743 0 0 0 .81-.973c.542-.939.861-2.127.861-3.745 0-2.72-.681-5.357-2.084-7.45-1.282-1.912-2.957-2.93-4.716-2.93-1.047 0-2.088.467-3.053 1.308-.652.57-1.257 1.29-1.82 2.05-.69-.875-1.335-1.547-1.958-2.056-1.182-.966-2.315-1.303-3.454-1.303zm10.16 2.053c1.147 0 2.188.758 2.992 1.999 1.132 1.748 1.647 4.195 1.647 6.4 0 1.548-.368 2.9-1.839 2.9-.58 0-1.027-.23-1.664-1.004-.496-.601-1.343-1.878-2.832-4.358l-.617-1.028a44.908 44.908 0 0 0-1.255-1.98c.07-.109.141-.224.211-.327 1.12-1.667 2.118-2.602 3.358-2.602zm-10.201.553c1.265 0 2.058.791 2.675 1.446.307.327.737.871 1.234 1.579l-1.02 1.566c-.757 1.163-1.882 3.017-2.837 4.338-1.191 1.649-1.81 1.817-2.486 1.817-.524 0-1.038-.237-1.383-.794-.263-.426-.464-1.13-.464-2.046 0-2.221.63-4.535 1.66-6.088.454-.687.964-1.226 1.533-1.533a2.264 2.264 0 0 1 1.088-.285z"
fill="currentColor"
/>
</svg>
<span className="sr-only">Sign up with Meta</span>
</Button>
</Field>
<FieldDescription className="text-center">
Already have an account? <a href="#">Sign in</a>
</FieldDescription>
</FieldGroup>
</form>
<div className="bg-muted relative hidden md:block">
<img
src="/placeholder.svg"
alt="Image"
className="absolute inset-0 h-full w-full object-cover dark:brightness-[0.2] dark:grayscale"
/>
</div>
</CardContent>
</Card>
<FieldDescription className="px-6 text-center">
By clicking continue, you agree to our <a href="#">Terms of Service</a>{" "}
and <a href="#">Privacy Policy</a>.
</FieldDescription>
</div>
)
}


"use client"
import { GalleryVerticalEnd } from "lucide-react"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
FieldSeparator,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"
export function SignupPage() {
return (
<div className="bg-background flex min-h-svh flex-col items-center justify-center gap-6 p-6 md:p-10">
<div className="w-full max-w-sm">
<SignupForm />
</div>
</div>
)
}
export function SignupForm({
className,
...props
}: React.ComponentPropsWithoutRef<"div">) {
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
const formData = new FormData(e.currentTarget)
// TODO: Add your authentication logic here
console.log("Form submitted:", Object.fromEntries(formData))
// Example: await signIn(formData)
}
return (
<div className={cn("flex flex-col gap-6", className)} {...props}>
<form onSubmit={handleSubmit}>
<FieldGroup>
<div className="flex flex-col items-center gap-2 text-center">
<a
href="#"
className="flex flex-col items-center gap-2 font-medium"
>
<div className="flex size-8 items-center justify-center rounded-md">
<GalleryVerticalEnd className="size-6" />
</div>
<span className="sr-only">Acme Inc.</span>
</a>
<h1 className="text-xl font-bold">Welcome to Acme Inc.</h1>
<FieldDescription>
Already have an account? <a href="#">Sign in</a>
</FieldDescription>
</div>
<Field>
<FieldLabel htmlFor="email">Email</FieldLabel>
<Input
id="email"
name="email"
type="email"
placeholder="m@example.com"
required
/>
</Field>
<Field>
<Button type="submit">Create Account</Button>
</Field>
<FieldSeparator>Or</FieldSeparator>
<Field className="grid gap-4 sm:grid-cols-2">
<Button variant="outline" type="button">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
d="M12.152 6.896c-.948 0-2.415-1.078-3.96-1.04-2.04.027-3.91 1.183-4.961 3.014-2.117 3.675-.546 9.103 1.519 12.09 1.013 1.454 2.208 3.09 3.792 3.039 1.52-.065 2.09-.987 3.935-.987 1.831 0 2.35.987 3.96.948 1.637-.026 2.676-1.48 3.676-2.948 1.156-1.688 1.636-3.325 1.662-3.415-.039-.013-3.182-1.221-3.22-4.857-.026-3.04 2.48-4.494 2.597-4.559-1.429-2.09-3.623-2.324-4.39-2.376-2-.156-3.675 1.09-4.61 1.09zM15.53 3.83c.843-1.012 1.4-2.427 1.245-3.83-1.207.052-2.662.805-3.532 1.818-.78.896-1.454 2.338-1.273 3.714 1.338.104 2.715-.688 3.559-1.701"
fill="currentColor"
/>
</svg>
Continue with Apple
</Button>
<Button variant="outline" type="button">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
d="M12.48 10.92v3.28h7.84c-.24 1.84-.853 3.187-1.787 4.133-1.147 1.147-2.933 2.4-6.053 2.4-4.827 0-8.6-3.893-8.6-8.72s3.773-8.72 8.6-8.72c2.6 0 4.507 1.027 5.907 2.347l2.307-2.307C18.747 1.44 16.133 0 12.48 0 5.867 0 .307 5.387.307 12s5.56 12 12.173 12c3.573 0 6.267-1.173 8.373-3.36 2.16-2.16 2.84-5.213 2.84-7.667 0-.76-.053-1.467-.173-2.053H12.48z"
fill="currentColor"
/>
</svg>
Continue with Google
</Button>
</Field>
</FieldGroup>
</form>
<FieldDescription className="px-6 text-center">
By clicking continue, you agree to our <a href="#">Terms of Service</a>{" "}
and <a href="#">Privacy Policy</a>.
</FieldDescription>
</div>
)
}

