A routed contact form where the topic switch reshapes the fields and the reply time. Inline validation, a message progress ring and a paper plane success state with a ticket number.
Pick a topic and we will route you to the right person.
npx shadcn@latest add https://hyperblur.dev/r/form-contact.jsonWorks in any React project set up with the shadcn CLI. The file lands in components/hyperblur/form-contact.tsx.
import { FormContact } from "@/components/hyperblur/form-contact"
<FormContact onSubmit={(values) => fetch("/api/contact", { method: "POST", body: JSON.stringify(values) })} />| Prop | Type | Default | Description |
|---|---|---|---|
| title | string | "Talk to our team" | Heading of the card. |
| subtitle | string | "Pick a topic and we will route you to the right person." | Line under the heading. |
| topics | FormContactTopic[] | Sales, Support, Press | Topics with id, label, reply time text and an optional extra field ({ name, label, placeholder, required }). |
| defaultTopic | string | first topic | Topic id selected on mount. |
| minMessage | number | 20 | Minimum message length; the ring fills toward it. |
| maxMessage | number | 600 | Maximum message length. |
| submitLabel | string | "Send message" | Text of the submit button. |
| accent | string | "#2f7bff" | Accent color for focus rings, selected states and the primary button. |
| delay | number | 1100 | Minimum time in milliseconds the loading state stays visible, so the transition never flickers. |
| onSubmit | (values: FormContactValues) => void | Promise<void> | Called with topic, name, email, message and extra. Throw or reject to show the error banner. |