Canonical contact form component supporting both public contact flows and internal ticket creation. Accepts configurable field visibility, custom submit handlers, file attachments, and bot-protection signals, making a single form reusable across multiple surfaces without forking. ## Key Components | Export | Type | Description | |---|---|---| | `ContactForm` | Component | Main form component with all contact/ticket functionality | | `ContactFormProps` | Interface | Full prop surface for customization and embedding | | `ContactFormHideableField` | Type | Union of field keys that can be suppressed from rendering | **Internal hooks used:** - `useContactSubmission` — built-in `/api/contact` submit flow (toast + redirect) - `useHumanitySignals` — honeypot + timing bot-protection signals - `useChatAttachments` — file staging using the same primitives as the chat composer ## Usage Example ```typescript // Basic contact page usage // Ticket creation surface — hides name/email, adds Subject field, // uses a custom submit handler } attachmentsEnabled submitLabel="Open ticket" onCustomSubmit={async (data, attachments) => { await actions.submitTicket({ ...data, subject, attachments }) }} /> ``` ## Notes - `defaultValues` is **required** when hiding `name`, `email`, or `helpCategory` — Zod still validates hidden fields; missing values cause a silent submit block (a `console.warn` logs the offending fields in DevTools). - `onCustomSubmit` bypasses the built-in toast/redirect chain entirely; the caller owns all success/error UX. - `attachmentsEnabled` must be `true` to render the file picker; otherwise `attachments` passed to `onCustomSubmit` is always `[]`. **Source:** [`contact-form.tsx`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/contact-form.tsx)