Form widget
A form the agent asks the user to fill in. Validates on blur and on submit with messages that say how to fix the value, hands values back through a callback, then becomes a read-only summary.
On this page
Validation on blur and submit with messages that say how to fix the value, then a summary of what was sent.
Installation
Usage
import { FormWidget } from "@/components/ui/chatcn/form-widget"
<FormWidget
title="Details for the staging database"
fields={[
{ name: "project", label: "Project name", required: true, pattern: "[a-z0-9-]{3,40}" },
{ name: "owner", label: "Owner email", type: "email", required: true },
]}
submitLabel="Create project"
onSubmit={(values) => addToolResult({ toolCallId, output: values })}
onCancel={() => addToolResult({ toolCallId, output: { skipped: true } })}
/>Throw or reject from onSubmit to show the error and keep the form editable. Restore a sent form from history with status="submitted" and values.
Examples
Streaming, sent and dismissed
Rows reserved while fields stream, then the read-only summaries.
Fields
| Type | Validation |
|---|---|
text, tel, textarea | required, minLength, maxLength, pattern with patternMessage |
email | Address shape. "Enter an email address like ada@example.com." |
url | A full address with a protocol |
number | min, max, step. Sent as a number |
date | Native date input |
select, radio | options with value, label, description? |
checkbox | A boolean. Required means it must be checked |
Props
| Prop | Type | Notes |
|---|---|---|
fields | FormField[] | width: "half" pairs two fields on one row |
submitLabel, cancelLabel | string | Specific verbs. Default Send to agent and Not now |
onSubmit | (values) => void | Promise<void> | Only called with valid values |
onCancel | () => void | Shows the cancel button |
status, values | Controlled status for restored forms | |
streaming, expectedFields | Rows reserved and submit held while fields stream | |
error, disabled |
Keyboard
| Key | Action |
|---|---|
Tab | Move through fields and buttons |
Enter | Submit from a single-line field. Ignored while an IME composition is open |
Arrow keys | Choose within a radio group |
Space | Toggle a checkbox |
Accessibility
- Errors appear after a field is left or submit is attempted, never while typing. Each is tied to its control with
aria-describedbyandaria-invalid, and the first invalid field takes focus on submit. - Optional fields say so in the label instead of starring the required ones.
Motion
- Focus rings and checkbox fills change over 150 ms. The submit spinner sits on top of the label so the button keeps its width.