Back to components
Form

Login Form

A complete sign-in form composed from Card, Field, Input, Separator, and Button.

Page preview
Source
This is the component source that shadcn installs into a consuming project.
registry/default/login-form/login-form.tsx
import { ArrowRightIcon } from "lucide-react"

import { Button } from "@/components/ui/button"
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import {
  Field,
  FieldDescription,
  FieldGroup,
  FieldLabel,
  FieldSeparator,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"

type LoginFormCopy = {
  title: string
  description: string
  emailLabel: string
  emailPlaceholder: string
  passwordLabel: string
  passwordPlaceholder: string
  helperText: string
  submitLabel: string
  footerText: string
  separator: string
}

type LoginFormProps = {
  copy?: LoginFormCopy
}

const defaultCopy: LoginFormCopy = {
  title: "Sign in",
  description: "Use your workspace email to continue.",
  emailLabel: "Email",
  emailPlaceholder: "name@example.com",
  passwordLabel: "Password",
  passwordPlaceholder: "Enter your password",
  helperText: "Keep this form as source code and adapt it per project.",
  submitLabel: "Continue",
  footerText: "New team? Request access from your administrator.",
  separator: "or",
}

export function LoginForm({ copy = defaultCopy }: LoginFormProps) {
  return (
    <Card className="w-full max-w-sm">
      <CardHeader>
        <CardTitle>{copy.title}</CardTitle>
        <CardDescription>{copy.description}</CardDescription>
      </CardHeader>
      <CardContent>
        <form className="flex flex-col gap-5">
          <FieldGroup>
            <Field>
              <FieldLabel htmlFor="email">{copy.emailLabel}</FieldLabel>
              <Input
                id="email"
                type="email"
                placeholder={copy.emailPlaceholder}
                autoComplete="email"
                required
              />
            </Field>
            <Field>
              <FieldLabel htmlFor="password">{copy.passwordLabel}</FieldLabel>
              <Input
                id="password"
                type="password"
                placeholder={copy.passwordPlaceholder}
                autoComplete="current-password"
                required
              />
              <FieldDescription>
                {copy.helperText}
              </FieldDescription>
            </Field>
            <Button type="submit" className="w-full">
              {copy.submitLabel}
              <ArrowRightIcon data-icon="inline-end" />
            </Button>
            <FieldSeparator>{copy.separator}</FieldSeparator>
          </FieldGroup>
        </form>
      </CardContent>
      <CardFooter className="justify-center">
        <p className="text-sm text-muted-foreground">
          {copy.footerText}
        </p>
      </CardFooter>
    </Card>
  )
}