Contact Form
A family of ready get-in-touch blocks on one recipe: ContactForm, LeadForm for sales, and SupportForm for help-desk requests. Each wires its controls through Field, owns its state and confirms on submit.
Lead capture#
LeadForm is the richer sales / collaboration block: a name and social row, a company-size Select, a country-aware PhoneInput, and a message. Drop it beside a hero to capture qualified leads.
Support request#
SupportForm is tuned for an inbound support queue: a name and email row, a support-topic Select, an optional order / reference field so an agent can pull the account up fast, and a message.
Installation#
Usage#
usage.tsxTSX
"use client"
import { ContactForm, type ContactFormData } from "@/components/ui/contact-form"
export function Example() {
async function send(data: ContactFormData) {
await fetch("/api/contact", { method: "POST", body: JSON.stringify(data) })
}
return <ContactForm onSubmit={send} />
}API reference#
ContactForm / LeadForm / SupportForm
Each composes Field, Input, Select, and Textarea (LeadForm adds PhoneInput). Each forwards all <div> props.
onSubmit: called with the block's data object on a valid submit ({ name, email, subject, message }for ContactForm,{ firstName, linkedin, email, companySize, phone, message }for LeadForm,{ name, email, topic, reference, message }for SupportForm). Return a promise to drive the loading spinner.variant:card(default, standalone bordered block) orbare(drops the chrome to embed in a page shell).density:compact(16px padding, 32px fields, default) orcomfortable(24px padding, 36px fields). The fields take the default control size for that density rather than the 40px a bareFormimposes, so the card stays proportional.title,description,action: override the default copy.defaultCountry(LeadForm only): initial ISO2 for the phone field.