Component Library
Browse and explore components
Form Examples
A showcase of form components displayed in a clean, structured layout.
Registration Form
Component Code
Copy Code
"use client";
import React from "react";
import { useForm, useFieldArray } from "react-hook-form";
import * as z from "zod";
import { cn } from "@/lib/utils";
import { zodResolver } from "@hookform/resolvers/zod";
import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Checkbox } from "@/components/ui/checkbox";
import { Switch } from "@/components/ui/switch";
import { Icon } from "@iconify/react";
function RegistrationFormCode() {
const formSchema = z.object({
fullName: z.string({ error: "Full Name is required." }).min(1, "Full Name is required."),
email: z.string({ error: "Email is required." }).email("Invalid email address."),
age: z.number({ error: "Age is required." })
.int("Age must be an integer.")
.min(18, "You must be at least 18 years old."),
address: z.object({
street: z.string({ error: "Street address is required." }).min(1, "Street address is required."),
city: z.string({ error: "City is required." }).min(1, "City is required."),
zipCode: z.string({ error: "ZIP Code is required." })
.regex(/^\d{5}$/, "ZIP Code must be 5 digits."),
}),
phoneNumbers: z.array(
z.string({ error: "Phone number is required." }).min(1, "Phone number cannot be empty.")
).min(1, "At least one phone number is required."),
employmentType: z.enum(["Full-time", "Part-time", "Contract"], {
error: "Please select an employment type.",
}),
skills: z.array(z.string()).min(1, "Please select at least one skill."),
openToRemote: z.boolean().default(false),
});
const defaultValues = {
fullName: "",
email: "",
age: 0,
address: {
street: "",
city: "",
zipCode: "",
},
phoneNumbers: [""],
employmentType: "Full-time",
skills: [],
openToRemote: false,
};
const form = useForm<any>({
resolver: zodResolver(formSchema),
defaultValues: defaultValues,
});
const { fields, append, remove } = useFieldArray({
control: form.control,
name: "phoneNumbers",
});
const onSubmit = (data: any) => {
alert(JSON.stringify(data, null, 2));
};
const skillsOptions = ["React", "Node.js", "TypeScript", "AWS", "Docker", "Kubernetes", "SQL", "NoSQL"];
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit as any)} className="max-w-full space-y-8">
<div className="grid grid-cols-12 gap-4">
<div className="lg:col-span-6 col-span-12">
<FormField
control={form.control}
name="fullName"
render={({ field }: any) => (
<FormItem>
<FormLabel>Full Name</FormLabel>
<FormControl>
<Input placeholder="John Doe" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<div className="lg:col-span-6 cols-span-12">
<FormField
control={form.control}
name="email"
render={({ field }: any) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input placeholder="john.doe@example.com" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<div className="lg:col-span-6 col-span-12">
<FormField
control={form.control}
name="age"
render={({ field }: any) => (
<FormItem>
<FormLabel>Age</FormLabel>
<FormControl>
<Input
type="number"
placeholder="30"
{...field}
value={field.value === undefined || field.value === null ? "" : String(field.value)}
onChange={(event: any) => field.onChange(event.target.value === "" ? undefined : +event.target.value)}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<div className="lg:col-span-6 col-span-12">
<FormField
control={form.control}
name={`phoneNumber`}
render={({ field }: any) => (
<FormItem className="flex-grow">
<FormLabel>
Phone Number
</FormLabel>
<FormControl>
<Input placeholder="555-123-4567" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
</div>
<div>
<h3 className="mb-4 text-lg font-medium">Address</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="md:col-span-2 col-span-1">
<FormField
control={form.control}
name="address.street"
render={({ field }: any) => (
<FormItem>
<FormLabel>Street Address</FormLabel>
<FormControl>
<Input placeholder="123 Main St" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<FormField
control={form.control}
name="address.city"
render={({ field }: any) => (
<FormItem>
<FormLabel>City</FormLabel>
<FormControl>
<Input placeholder="Anytown" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="address.zipCode"
render={({ field }: any) => (
<FormItem>
<FormLabel>ZIP Code</FormLabel>
<FormControl>
<Input placeholder="12345" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
</div>
<div>
<h3 className="mb-4 text-lg font-medium">Job Preferences</h3>
<FormField
control={form.control}
name="employmentType"
render={({ field }: any) => (
<FormItem>
<FormLabel>Employment Type</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Select an employment type" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value="Full-time">Full-time</SelectItem>
<SelectItem value="Part-time">Part-time</SelectItem>
<SelectItem value="Contract">Contract</SelectItem>
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="skills"
render={() => (
<FormItem className="mt-4">
<FormLabel>Skills</FormLabel>
<div className="grid grid-cols-2 gap-2">
{skillsOptions.map((skill: string) => (
<FormField
key={skill}
control={form.control}
name="skills"
render={({ field }: any) => (
<FormItem className="flex flex-row items-start space-x-3 space-y-0">
<FormControl>
<Checkbox
checked={field.value?.includes(skill)}
onCheckedChange={(checked: boolean) => {
return checked
? field.onChange([...field.value, skill])
: field.onChange(
field.value?.filter(
(value: any) => value !== skill
)
);
}}
/>
</FormControl>
<FormLabel className="font-normal">
{skill}
</FormLabel>
</FormItem>
)}
/>
))}
</div>
<FormMessage />
{form.formState.errors.skills && (
<p className="text-sm font-medium text-destructive mt-2">{form.formState.errors.skills.message as any}</p>
)}
</FormItem>
)}
/>
<FormField
control={form.control}
name="openToRemote"
render={({ field }: any) => (
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-4 mt-6">
<FormLabel className="text-base">
Open to Remote Work
</FormLabel>
<FormControl>
<Switch
checked={field.value}
onCheckedChange={field.onChange}
className="m-0"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<Button type="submit">Submit Application</Button>
</form>
</Form>
);
}
export default RegistrationFormCode;
StudentEnrollment Form
Component Code
Copy Code
"use client";
import React from "react";
import { useForm, useFieldArray } from "react-hook-form";
import * as z from "zod";
import { cn } from "@/lib/utils";
import { zodResolver } from "@hookform/resolvers/zod";
import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Checkbox } from "@/components/ui/checkbox";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Calendar } from "@/components/ui/calendar";
import { format } from "date-fns";
import { Icon } from "@iconify/react";
function StudentEnrollmentFormCode() {
const formSchema = z.object({
name: z.string({ error: "Name is required." }).min(2, "Name must be at least 2 characters."),
email: z.string({ error: "Email is required." }).email("Invalid email address."),
dateOfBirth: z.date({ error: "Date of birth is required." })
.max(new Date(), "Date of birth cannot be in the future.")
.refine((date) => {
const today = new Date();
const eighteenYearsAgo = new Date(today.getFullYear() - 18, today.getMonth(), today.getDate());
return date <= eighteenYearsAgo;
}, "Student must be at least 18 years old."),
parentGuardian: z.object({
parentName: z.string({ error: "Parent/Guardian name is required." }).min(2, "Name must be at least 2 characters."),
parentPhone: z.string({ error: "Parent/Guardian phone is required." })
.regex(/^\+?[0-9]{7,15}$/, "Invalid phone number format. E.g., +1234567890"),
}),
subjects: z.array(
z.object({
name: z.string({ error: "Subject name is required." }).min(1, "Subject name cannot be empty.")
})
).min(1, { message: "At least one subject is required." }),
gradeLevel: z.enum(["Kindergarten", "1st Grade", "2nd Grade", "3rd Grade", "4th Grade", "5th Grade", "6th Grade", "7th Grade", "8th Grade", "9th Grade", "10th Grade", "11th Grade", "12th Grade"], {
error: "Please select a grade level.",
}),
agreeToTerms: z.boolean({ error: "You must agree to the terms." }).refine(val => val === true, "You must agree to the terms."),
});
const defaultValues = {
name: "",
email: "",
dateOfBirth: new Date(new Date().setFullYear(new Date().getFullYear() - 18)), // Default to 18 years ago
parentGuardian: {
parentName: "",
parentPhone: "",
},
subjects: [{ name: "" }],
gradeLevel: "1st Grade" as "1st Grade", // Initialize with a valid enum member
agreeToTerms: false,
};
const form = useForm<any>({
resolver: zodResolver(formSchema),
defaultValues,
});
const { fields, append, remove } = useFieldArray({
control: form.control,
name: "subjects",
});
const onSubmit = (data: any) => {
alert(JSON.stringify(data, null, 2));
};
const gradeLevels = [
"Kindergarten", "1st Grade", "2nd Grade", "3rd Grade", "4th Grade", "5th Grade",
"6th Grade", "7th Grade", "8th Grade", "9th Grade", "10th Grade", "11th Grade", "12th Grade"
];
return (
<div className="w-full">
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
<div className="grid md:grid-cols-2 grid-cols-1 gap-4">
{/* Student Name */}
<FormField
control={form.control}
name="name"
render={({ field }: any) => (
<FormItem>
<FormLabel>Student Name</FormLabel>
<FormControl>
<Input placeholder="John Doe" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
{/* Student Email */}
<FormField
control={form.control}
name="email"
render={({ field }: any) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input type="email" placeholder="john.doe@example.com" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
{/* Date of Birth */}
<FormField
control={form.control}
name="dateOfBirth"
render={({ field }: any) => (
<FormItem className="flex flex-col">
<FormLabel>Date of Birth</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>
<Button
variant={"outline"}
className={cn(
"w-full pl-3 text-left font-normal",
!field.value && "text-muted-foreground"
)}
>
{field.value ? (
format(field.value, "PPP")
) : (
<span>Pick a date</span>
)}
<Icon icon="lucide:calendar" className="ml-auto h-4 w-4 opacity-50" />
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="start">
<Calendar
mode="single"
selected={field.value}
onSelect={field.onChange}
disabled={(date) =>
date > new Date() || date < new Date("1900-01-01")
}
captionLayout="dropdown"
fromYear={1900}
toYear={new Date().getFullYear()}
initialFocus
/>
</PopoverContent>
</Popover>
<FormMessage />
</FormItem>
)}
/>
{/* Parent/Guardian Details */}
<fieldset className="space-y-4 border p-4 rounded-md">
<legend className="text-lg font-semibold px-2">Parent/Guardian Details</legend>
<FormField
control={form.control}
name="parentGuardian.parentName"
render={({ field }: any) => (
<FormItem>
<FormLabel>Parent/Guardian Name</FormLabel>
<FormControl>
<Input placeholder="Jane Doe" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="parentGuardian.parentPhone"
render={({ field }: any) => (
<FormItem>
<FormLabel>Parent/Guardian Phone</FormLabel>
<FormControl>
<Input type="tel" placeholder="+1234567890" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</fieldset>
{/* Dynamic Subjects */}
<fieldset className="space-y-4 border p-4 rounded-md">
<legend className="text-lg font-semibold px-2">Subjects</legend>
{fields.map((item: any, index: number) => (
<FormField
control={form.control}
key={item.id}
name={`subjects.${index}.name`}
render={({ field }: any) => (
<FormItem>
<FormLabel>Subject {index + 1}</FormLabel>
<div className="flex items-center space-x-2">
<FormControl>
<Input placeholder="Mathematics" {...field} />
</FormControl>
<Button
type="button"
variant="outline"
size="sm"
onClick={() => append({ name: "" })}
>
<Icon icon="lucide:plus" className="h-4 w-4" />
</Button>
<Button
type="button"
variant="outline"
size="sm"
onClick={() => remove(index)}
disabled={fields.length === 1}
>
<Icon icon="lucide:trash-2" className="h-4 w-4" />
</Button>
</div>
<FormMessage />
</FormItem>
)}
/>
))}
{form.formState.errors.subjects && typeof (form.formState.errors.subjects as any).message === 'string' && (
<p className="text-sm font-medium text-destructive mt-2">{(form.formState.errors.subjects as any).message}</p>
)}
</fieldset>
{/* Grade Level Select */}
<FormField
control={form.control}
name="gradeLevel"
render={({ field }: any) => (
<FormItem>
<FormLabel>Grade Level</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Select a grade level" />
</SelectTrigger>
</FormControl>
<SelectContent>
{gradeLevels.map((grade) => (
<SelectItem key={grade} value={grade}>
{grade}
</SelectItem>
))}
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
{/* Agree to Terms Checkbox */}
<FormField
control={form.control}
name="agreeToTerms"
render={({ field }: any) => (
<FormItem className="flex flex-row items-start gap-3 space-y-0 rounded-md border p-3">
<FormControl>
<Checkbox
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl>
<FormLabel className="mb-0">
I agree to the terms and conditions
</FormLabel>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit" className="w-full">Submit Enrollment</Button>
</form>
</Form>
</div>
);
}
export default StudentEnrollmentFormCode;