Check whether this receipt matches the original order.
Preview
Design guidance
Use secondary for a task summary or approval. Keep draft files in the primary editor through attachmentContent. The compact LayerCard shows only its primary region until a secondary panel is supplied. Use secondaryVisible={false} to hide a retained panel. Send stays at the trailing edge with or without a model control.
Vercel AI SDK and TanStack AI hooks own transport and streaming state. See the native SDK examples for wiring Composer, messages, stop, approval, and file delivery.
Accessibility
Composer is a form. Enter submits a valid draft, Shift+Enter inserts a newline, and composing or IME key code 229 never submits. Native naming, focus, disabled, read-only, error, and status attributes pass through to the textarea. Failed sends retain the draft and announce the error.
Installation
Install
Source files
Basic usage
Structures
Examples
Default task
Draft a request, choose a model, optionally add a file, and send it. The local example records the submitted content.
Model and attachment composition
Arrange a caller-owned model selection and ready file beside the submit action.
Prepared request and row sizing
Start with a prepared request and file while keeping the editor at two rows and capping it at four.
Attached task progress
Attach a caller-owned checklist when the request needs a few visible subtasks. The clock reports the actual completed count, and the rows can be collapsed without changing the draft.
Tool approval
Attach a pending decision above the editor. Deny and Allow once resolve the caller-owned approval state.
Save weekly update?docs/weekly-update.md
Attachment-only
Submit a ready file when the text draft is empty.
Sending
Send a request in a conversation. Its acknowledgement completes automatically, while edits to a newer draft stay in the composer.
Stop stream
Show a partial assistant response while it generates. Stop ends the response and keeps the text already received.
Failed send and retry
Keep the failed user message in the conversation, show a separate system notice, and retry from the message footer without sending a newer draft.
Disabled
Preserve the disabled draft while preventing edits and actions.
Long draft
Keep long content inside the autosizing field with internal scrolling at the maximum height.
Field label
Place the caller-owned Field.Label at the top of the primary composer panel. Field.Control connects it to the native textarea.
Describe what you need.
Read-only
Keep an archived draft readable while preventing changes and sending.
Blocked attachment
Keep a failed file visible and prevent sending until the caller removes or replaces it.
API reference
| Prop | Type | Default | Description |
|---|---|---|---|
onSubmitrequired | (submission: ComposerSubmission) => void | Promise<void> | Receives the exact draft and attachment snapshot. | |
onSubmitted | (submission: ComposerSubmission) => void | Runs after successful delivery and the draft reset check. Remove captured files here without clearing a newer draft. | |
value | string | Controls the draft value. | |
defaultValue | string | "" | Seeds an uncontrolled draft. |
onValueChange | (text: string) => void | Receives controlled and uncontrolled draft edits. | |
attachments | readonly AttachmentFile[] | [] | Provides caller-owned attachment identities and upload states. |
secondary | ReactNode | Places caller-owned task or approval content above the primary editor. Draft files stay inside the field; pass null to omit the secondary panel. | |
secondaryVisible | boolean | true | Hides a supplied secondary panel while keeping the draft and primary editor. |
attachmentContent | ReactNode | Customizes the draft-file region inside the field; defaults to ComposerAttachments. Pass null to omit it. | |
initialRows | number | 1 | Sets the first native textarea row after positive-integer normalization. |
maxRows | number | 8 | Caps native textarea growth after normalization; values below initialRows are raised. |
feedbackPlacement | inline | conversation | inline | Keeps transport feedback inline, or lets conversation messages show sending, generation and send failures. Validation feedback stays visible. |
status | ready | submitting | streaming | error | ready | Reports caller-owned runtime state. |
onStop | () => void | Promise<void> | Stops a streaming operation when supplied. | |
onRetry | () => void | Promise<void> | Retries a failed operation when supplied. | |
disabled | boolean | false | Disables the input and actions. |
readOnly | boolean | false | Keeps the draft readable without allowing changes or actions. |
label | string | Message | Names the native ComposerInput unless it supplies its own accessible name. |