Skip to content
Generative UIForm widgetMenu

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.

Validation on blur and submit with messages that say how to fix the value, then a summary of what was sent.

Installation

$ pnpm dlx shadcn@latest add https://chatcn.dev/r/form-widget.json

Usage

tsx
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

TypeValidation
text, tel, textarearequired, minLength, maxLength, pattern with patternMessage
emailAddress shape. "Enter an email address like ada@example.com."
urlA full address with a protocol
numbermin, max, step. Sent as a number
dateNative date input
select, radiooptions with value, label, description?
checkboxA boolean. Required means it must be checked

Props

PropTypeNotes
fieldsFormField[]width: "half" pairs two fields on one row
submitLabel, cancelLabelstringSpecific verbs. Default Send to agent and Not now
onSubmit(values) => void | Promise<void>Only called with valid values
onCancel() => voidShows the cancel button
status, valuesControlled status for restored forms
streaming, expectedFieldsRows reserved and submit held while fields stream
error, disabled

Keyboard

KeyAction
TabMove through fields and buttons
EnterSubmit from a single-line field. Ignored while an IME composition is open
Arrow keysChoose within a radio group
SpaceToggle 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-describedby and aria-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.