Form Field
A composite form layout wrapper that connects labels, input fields, helper text, and validation error messages.
formField.tsx
Core implementation of the FormField component.
ReactTailwindFormsUI Layout
"use client";
import * as React from "react";
import { cn } from "@/lib/utils";
import { Label } from "@/components/ui/label/label";
export interface FormFieldProps extends React.HTMLAttributes<HTMLDivElement> {
label?: React.ReactNode;
isRequired?: boolean;
description?: React.ReactNode;
errorMessage?: React.ReactNode;
isInvalid?: boolean;
htmlFor?: string;
}
export function FormField({
className,
children,
label,
isRequired = false,
description,
errorMessage,
isInvalid = false,
htmlFor,
...props
}: FormFieldProps) {
const generatedId = React.useId();
const fieldId = htmlFor || generatedId;
return (
<div className={cn("w-full flex flex-col gap-1.5", className)} {...props}>
{label && (
<Label htmlFor={fieldId} isRequired={isRequired}>
{label}
</Label>
)}
<div className="w-full">
{React.isValidElement(children)
? React.cloneElement(children as React.ReactElement<{ id?: string; isInvalid?: boolean }>, {
id: fieldId,
isInvalid: isInvalid || Boolean(errorMessage),
})
: children}
</div>
{isInvalid && errorMessage ? (
<p className="text-xs text-danger font-medium">{errorMessage}</p>
) : description ? (
<p className="text-xs text-muted-foreground">{description}</p>
) : null}
</div>
);
}Basic Usage
Form field with label, description and error states.
We will send a confirmation email here.
Username is already taken
API Reference
Props — FormField
Properties to configure the FormField component.
| Prop | Type | Default | Description |
|---|---|---|---|
| label | ReactNode | — | Label title text. |
| errorMessage | ReactNode | — | Error message shown when invalid. |