Form Component
API reference for the Form component — auto-render, manual children, and props.
Form Component
This page documents the headless <Form> from @buildnbuzz/form-react. For most apps, prefer the shadcn registry form components (@/components/buzzform/form) shown in Quick Start.
API Reference
Prop
Type
| Prop | Type | Description |
|---|---|---|
form | FieldFormApi | TanStack form instance from useForm |
fields | Field[] | Schema fields to auto-render |
registries | FormRegistries | Unified runtime registries (fields, validators, resolvers, fns) |
registry | FieldRegistry | @deprecated Use registries.fields instead. |
customValidators | ValidationRegistry | @deprecated Use registries.validators instead. |
optionResolvers | OptionResolverRegistry | @deprecated Use registries.resolvers instead. |
renderFallback | (field) => ReactNode | Fallback for unregistered field types |
basePath | string | Parent path for nested fields |
contextData | object | External data for dynamic values |
derivedValidationMode | "submit" | "blur" | "change" | When to run derived validators |
onSubmit | (e) => void | Custom submit handler |
children | ReactNode | Custom content to render |
All standard HTML <form> attributes are also supported.
Auto-Render Pattern
Pass fields to auto-render all fields from your schema:
import { contactSchema } from "@/lib/schemas/contact";
import { useForm, Form } from "@buildnbuzz/form-react";
import { FormFields } from "@/components/buzzform/form";
export function ContactForm() {
const form = useForm({ schema: contactSchema });
// Auto-renders all fields + children
<Form form={form} fields={contactSchema.fields}>
<button type="submit">Send Message</button>
</Form>;
}Manual Children Pattern
Render custom layouts without auto-rendering:
import { contactSchema } from "@/lib/schemas/contact";
import { useForm, Form } from "@buildnbuzz/form-react";
import { FormFields } from "@/components/buzzform/form";
export function ContactForm() {
const form = useForm({ schema: contactSchema });
<Form form={form}>
<div className="grid grid-cols-2 gap-4">
<FormFields fields={contactSchema.fields} />
</div>
<button type="submit">Send Message</button>
</Form>;
}Registry Override
Pass a custom registry for this form only:
import { customRegistry } from "@/components/my-form/registry";
import { contactSchema } from "@/lib/schemas/contact";
import { useForm, Form } from "@buildnbuzz/form-react";
export function ContactForm() {
const form = useForm({ schema: contactSchema });
<Form
form={form}
fields={contactSchema.fields}
registries={{ fields: customRegistry }} // Override global registry
>
<button type="submit">Send Message</button>
</Form>;
}Fallback Renderer
Render a placeholder for unregistered field types:
import { contactSchema } from "@/lib/schemas/contact";
import { useForm, Form } from "@buildnbuzz/form-react";
export function ContactForm() {
const form = useForm({ schema: contactSchema });
<Form
form={form}
fields={contactSchema.fields}
renderFallback={(field) => (
<div className="p-4 bg-muted rounded">
<p>Unknown field type: {field.type}</p>
</div>
)}
>
<button type="submit">Send Message</button>
</Form>;
}Base Path
Render a subsection of a nested schema:
import { userProfileSchema } from "@/lib/schemas/user-profile";
import { useForm, Form } from "@buildnbuzz/form-react";
import { FormFields } from "@/components/buzzform/form";
export function AddressForm() {
const form = useForm({ schema: userProfileSchema });
const addressField = userProfileSchema.fields.find(f => f.type === "group");
// Render only address fields
<Form
form={form}
fields={addressField?.fields}
basePath="/address"
>
<button type="submit">Update Address</button>
</Form>;
}Custom Submit Handler
Add custom logic before form submission:
import { contactSchema } from "@/lib/schemas/contact";
import { useForm, Form } from "@buildnbuzz/form-react";
export function ContactForm() {
const form = useForm({ schema: contactSchema });
<Form
form={form}
fields={contactSchema.fields}
onSubmit={(e) => {
// Custom logic before TanStack submit
console.log("Submitting...");
}}
>
<button type="submit">Send Message</button>
</Form>;
}Derived Validation Mode
Override the validation mode for this render:
import { contactSchema } from "@/lib/schemas/contact";
import { useForm, Form } from "@buildnbuzz/form-react";
export function ContactForm() {
const form = useForm({ schema: contactSchema });
<Form
form={form}
fields={contactSchema.fields}
derivedValidationMode="blur"
>
<button type="submit">Send Message</button>
</Form>;
}Context Data
Pass context data for dynamic values and validators:
import { contactSchema } from "@/lib/schemas/contact";
import { useForm, Form } from "@buildnbuzz/form-react";
export function ContactForm() {
const form = useForm({
schema: contactSchema,
contextData: { maxAttempts: 3 },
});
<Form
form={form}
fields={contactSchema.fields}
contextData={{ maxAttempts: 3 }}
>
<button type="submit">Send Message</button>
</Form>;
}Full Example
"use client";
import { contactSchema } from "@/lib/schemas/contact";
import { useForm, Form } from "@buildnbuzz/form-react";
import { FormFields, FormMessage } from "@/components/buzzform/form";
export function ContactForm() {
const form = useForm({
schema: contactSchema,
onSubmit: ({ value }) => {
console.log(value);
},
});
return (
<Form
form={form}
fields={contactSchema.fields}
contextData={{ maxAttempts: 3 }}
derivedValidationMode="blur"
>
<FormMessage />
<button type="submit">Send Message</button>
</Form>
);
}