Message composer
The raised input card — multiline field, send and stop, and slots for host actions.
FlowComposer is the raised input card: a multiline field that grows with
the draft, a send button that becomes stop while the model is
generating, and slots for host actions on the design’s rail. onSend is
required — a composer needs somewhere to send to. The card sits on
surfaceBright behind a gradient hairline that firms on hover and focus,
standing at the design’s 116px with an empty draft — which also drains the
send disc to the disabled ink.
Composed
Section titled “Composed”The composer’s slots take other flow_ui components directly — here the
“+” menu in leadingActions and the model selector in trailingActions:
FlowComposer( placeholder: 'Message flow_ui…', isStreaming: generating, onSend: (text) => startGeneration(text), onStop: cancelGeneration, leadingActions: [ FlowMenu( icon: Icons.add, tooltip: 'Add to chat', entries: [ FlowMenuOption( id: 'photos', icon: Icons.image_outlined, label: 'Photos'), FlowMenuOption( id: 'files', icon: Icons.upload_file_outlined, label: 'Files'), ], onSelected: (id) => pickAttachment(id), ), ], trailingActions: [ FlowModelSelector( models: [ FlowModelOption(id: 'sonnet', label: 'Sonnet 5'), FlowModelOption(id: 'opus', label: 'Opus 5'), ], selectedId: modelId, onSelected: (id) => setModel(id), efforts: [ FlowEffortOption(id: 'medium', label: 'Medium'), FlowEffortOption(id: 'high', label: 'High'), ], selectedEffortId: effortId, onEffortSelected: (id) => setEffort(id), ), ],)Send and stop
Section titled “Send and stop”isStreaming drives the send button: false shows send, true swaps it
for stop and routes taps to onStop. Flip it from your generation state
and the composer stays honest about what a tap will do.
Typing
Section titled “Typing”On hardware keyboards Enter sends and Shift+Enter inserts a
newline — submitOnEnter: false opts out; mobile soft keyboards keep
their newline key and send from the button. The field grows with the draft
to maxLines (6) and scrolls beyond it, and clearOnSend empties it
after a successful send. onSend receives the trimmed text and never
fires empty.
Attachments
Section titled “Attachments”The composer renders a pending-attachments row above the field — pass
attachments: and onRemoveAttachment:. The Attachments
page shows the full flow, from the “+” menu to the sent message.
Key API
Section titled “Key API”onSend— required; receives the trimmed draft, never empty text.isStreaming+onStop— the send/stop swap.enabled,submitOnEnter,clearOnSend,maxLines— field behavior; all default on, with a 6-line growth cap.leadingActions/trailingActions— widget slots on the input rail; any widget works, the flow_ui menus just fit the design out of the box.attachments,onRemoveAttachment,removeAttachmentTooltip— the pending row.onAttachmentTapreplaces the built-in full-screen preview;previewCloseTooltiplabels the preview’s close button.controller,focusNode,placeholder— the field itself; pass your ownTextEditingControllerto prefill or clear the draft.padding,borderRadius— the card’s metric overrides (the design’s 24px corner by default).