Form
FormForm wrapper with field validation and error display.
Preview
Usage
example.jsx
import { Form, FormField, FormLabel, FormDescription, FormMessage } from "@/components/ui/form";
export default function Example() {
return <Form />;
}Source Code
Copy this file into components/ui/form.jsx in your project.
form.jsx
"use client";
import { forwardRef, createContext, useContext } from "react";
import { cn } from "@/lib/utils";
const FormContext = createContext({});
const Form = forwardRef(({ className, children, onSubmit, ...props }, ref) => {
return (
<form ref={ref} onSubmit={onSubmit} className={cn("space-y-6", className)} {...props}>
{children}
</form>
);
});
Form.displayName = "Form";
const FormField = forwardRef(({ className, children, ...props }, ref) => {
return (
<div ref={ref} className={cn("space-y-2", className)} {...props}>
{children}
</div>
);
});
FormField.displayName = "FormField";
const FormLabel = forwardRef(({ className, required, children, ...props }, ref) => {
return (
<label ref={ref} className={cn("text-sm font-medium leading-none", className)} {...props}>
{children}
{required && <span className="text-destructive ml-1">*</span>}
</label>
);
});
FormLabel.displayName = "FormLabel";
const FormDescription = forwardRef(({ className, ...props }, ref) => (
<p ref={ref} className={cn("text-xs text-muted-foreground", className)} {...props} />
));
FormDescription.displayName = "FormDescription";
const FormMessage = forwardRef(({ className, children, ...props }, ref) => {
if (!children) return null;
return (
<p ref={ref} className={cn("text-xs text-destructive", className)} {...props}>
{children}
</p>
);
});
FormMessage.displayName = "FormMessage";
export { Form, FormField, FormLabel, FormDescription, FormMessage };
Quick Install
Make sure you have the cn() utility set up. It requires clsx and tailwind-merge.
npm install clsx tailwind-merge