mirror of
https://github.com/shadcn-ui/taxonomy
synced 2026-05-24 01:38:28 +00:00
Add form UI component
This commit is contained in:
parent
651f984e52
commit
13cced3f76
4 changed files with 113 additions and 26 deletions
58
components/ui/form.tsx
Normal file
58
components/ui/form.tsx
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as FormPrimitive from "@radix-ui/react-form"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const Form = FormPrimitive.Root
|
||||
|
||||
const FormField = FormPrimitive.Field
|
||||
|
||||
const FormControl = FormPrimitive.Control
|
||||
|
||||
const FormLabel = ({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: FormPrimitive.FormLabelProps) => (
|
||||
<FormPrimitive.Label
|
||||
className={cn(
|
||||
className,
|
||||
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</FormPrimitive.Label>
|
||||
)
|
||||
FormLabel.displayName = FormPrimitive.Label.displayName
|
||||
|
||||
const ErrorMessage = ({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: FormPrimitive.FormMessageProps) => (
|
||||
<FormPrimitive.Message
|
||||
className={cn(className, "text-xs leading-3 text-red-500")}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</FormPrimitive.Message>
|
||||
)
|
||||
ErrorMessage.displayName = FormPrimitive.Message.displayName
|
||||
|
||||
const FormSubmit = ({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: FormPrimitive.FormSubmitProps) => (
|
||||
<FormPrimitive.Submit asChild>
|
||||
<button className={cn(className)} {...props}>
|
||||
{children}
|
||||
</button>
|
||||
</FormPrimitive.Submit>
|
||||
)
|
||||
FormSubmit.displayName = FormPrimitive.Submit.displayName
|
||||
|
||||
export { Form, FormField, FormLabel, FormControl, ErrorMessage, FormSubmit }
|
||||
|
|
@ -10,6 +10,14 @@ import * as z from "zod"
|
|||
import { cn } from "@/lib/utils"
|
||||
import { userAuthSchema } from "@/lib/validations/auth"
|
||||
import { buttonVariants } from "@/components/ui/button"
|
||||
import {
|
||||
ErrorMessage,
|
||||
Form,
|
||||
FormControl,
|
||||
FormField,
|
||||
FormLabel,
|
||||
FormSubmit,
|
||||
} from "@/components/ui/form"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Label } from "@/components/ui/label"
|
||||
import { toast } from "@/components/ui/use-toast"
|
||||
|
|
@ -58,42 +66,42 @@ export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
|
|||
|
||||
return (
|
||||
<div className={cn("grid gap-6", className)} {...props}>
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<Form onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="grid gap-2">
|
||||
<div className="grid gap-1">
|
||||
<Label className="sr-only" htmlFor="email">
|
||||
Email
|
||||
</Label>
|
||||
<Input
|
||||
id="email"
|
||||
placeholder="name@example.com"
|
||||
type="email"
|
||||
autoCapitalize="none"
|
||||
autoComplete="email"
|
||||
autoCorrect="off"
|
||||
disabled={isLoading || isGitHubLoading}
|
||||
{...register("email")}
|
||||
/>
|
||||
{errors?.email && (
|
||||
<p className="px-1 text-xs text-red-600">
|
||||
{errors.email.message}
|
||||
</p>
|
||||
)}
|
||||
<FormField name="email">
|
||||
<FormLabel htmlFor="firstName">Email</FormLabel>
|
||||
<FormControl asChild>
|
||||
<Input
|
||||
id="email"
|
||||
placeholder="name@example.com"
|
||||
type="email"
|
||||
autoCapitalize="none"
|
||||
autoComplete="email"
|
||||
autoCorrect="off"
|
||||
disabled={isLoading || isGitHubLoading}
|
||||
{...register("email")}
|
||||
/>
|
||||
</FormControl>
|
||||
{errors?.email && (
|
||||
<ErrorMessage>{errors?.email.message}</ErrorMessage>
|
||||
)}
|
||||
</FormField>
|
||||
</div>
|
||||
<button className={cn(buttonVariants())} disabled={isLoading}>
|
||||
<FormSubmit className={cn(buttonVariants())} disabled={isLoading}>
|
||||
{isLoading && (
|
||||
<Icons.spinner className="mr-2 h-4 w-4 animate-spin" />
|
||||
<Icons.spinner className="w-4 h-4 mr-2 animate-spin" />
|
||||
)}
|
||||
Sign In with Email
|
||||
</button>
|
||||
</FormSubmit>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 flex items-center">
|
||||
<span className="w-full border-t" />
|
||||
</div>
|
||||
<div className="relative flex justify-center text-xs uppercase">
|
||||
<span className="bg-background px-2 text-muted-foreground">
|
||||
<span className="px-2 bg-background text-muted-foreground">
|
||||
Or continue with
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -108,9 +116,9 @@ export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
|
|||
disabled={isLoading || isGitHubLoading}
|
||||
>
|
||||
{isGitHubLoading ? (
|
||||
<Icons.spinner className="mr-2 h-4 w-4 animate-spin" />
|
||||
<Icons.spinner className="w-4 h-4 mr-2 animate-spin" />
|
||||
) : (
|
||||
<Icons.gitHub className="mr-2 h-4 w-4" />
|
||||
<Icons.gitHub className="w-4 h-4 mr-2" />
|
||||
)}{" "}
|
||||
Github
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
"@radix-ui/react-context-menu": "^2.1.3",
|
||||
"@radix-ui/react-dialog": "^1.0.3",
|
||||
"@radix-ui/react-dropdown-menu": "^2.0.4",
|
||||
"@radix-ui/react-form": "^0.0.2",
|
||||
"@radix-ui/react-hover-card": "^1.0.5",
|
||||
"@radix-ui/react-label": "^2.0.1",
|
||||
"@radix-ui/react-menubar": "^1.0.2",
|
||||
|
|
|
|||
|
|
@ -67,6 +67,9 @@ dependencies:
|
|||
'@radix-ui/react-dropdown-menu':
|
||||
specifier: ^2.0.4
|
||||
version: 2.0.4(@types/react@18.0.15)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-form':
|
||||
specifier: ^0.0.2
|
||||
version: 0.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-hover-card':
|
||||
specifier: ^1.0.5
|
||||
version: 1.0.5(@types/react@18.0.15)(react-dom@18.2.0)(react@18.2.0)
|
||||
|
|
@ -2048,6 +2051,23 @@ packages:
|
|||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-form@0.0.2(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-+WQU4Gs4MqjYsHwh5d19Ka4CMcWeXd7WPuWYCYGtNbDRMHFG2TtgM9PlEK4Yrk7wG1f5/da6Bgtteky2ggDXUg==}
|
||||
peerDependencies:
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
dependencies:
|
||||
'@babel/runtime': 7.21.0
|
||||
'@radix-ui/primitive': 1.0.0
|
||||
'@radix-ui/react-compose-refs': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/react-context': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/react-id': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/react-label': 2.0.1(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-hover-card@1.0.5(@types/react@18.0.15)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-jXRuZEkxSWdHZbVyL0J46cm7pQjmOMpwJEFKY+VqAJnV+FxS+zIZExI1OCeIiDwCBzUy6If1FfouOsfqBxr86g==}
|
||||
peerDependencies:
|
||||
|
|
|
|||
Loading…
Reference in a new issue