PromptBar
Animated prompt composer with compact and expanded layouts, rounded and pill shapes, and controls that render only when wired.
Use PromptBar as a controlled composer. Application code owns uploads, attachment opening, dictation, transcription, and execution. Use stable IDs for context and commands. The bar switches between compact and expanded layouts by itself. Do not force a layout from the outside. Set `submitOnEnter` deliberately. Keep stop available while work is busy. Do not execute work when context, command, attachment, or policy selection changes.
Interactive example
Loading interactive example
PromptBar
PromptBar is a controlled prompt composer that switches between compact and expanded layouts.
Purpose
Use PromptBar when prompt controls must share one keyboard, layout, and motion contract. Use Textarea for ordinary multiline input.
Control boundary
PromptBar uses compact mode for one line without tokens. It switches to expanded mode when text needs multiple lines or a token exists. PromptBar always measures wrapping at the compact input width, even after it expands. It measures again when the container width changes.
The shape prop accepts rounded or pill. A pill changes to the panel radius in expanded mode.
Add context and submit or stop always render. Attach, policy, measurement, and dictation controls render only when the consumer supplies their data or callbacks.
The policy control uses a menu-style select trigger. It shows each policy label, optional description, disabled state, and selected state. Typeahead works while the trigger is closed. Keyboard navigation keeps the highlighted policy visible in long lists.
Application code owns uploads, audio capture, transcription, persistence, and execution. PromptBar reports callbacks and renders the supplied state.
Use onOpenAttachment only with a localized openAttachment label. The controlled transcribing state also requires its visible status label.
Keep context as stable IDs in selectedContextIds. Keep attachments as separate records. A command inserts its consumer-owned insertText.
Changing context, a command, or an execution policy must not start work. Keep stop available during busy when the operation can stop safely.
Keyboard and input
The textarea keeps focus while the anchored suggestion panel is open. Arrow keys move through enabled suggestions without changing their stable IDs. Enter or Tab selects the active enabled suggestion. Tab closes the panel without selection when no enabled suggestion is active. Escape closes the panel.
submitOnEnter defaults to true. Enter submits, while Shift+Enter inserts a line break. Set submitOnEnter={false} when Enter must always insert a line break. IME composition does not select a suggestion or submit a prompt.
Supply the complete localized labels object. Give each context item, command, attachment, and execution policy a stable ID.
Changing the controlled value outside PromptBar closes the suggestion panel. The next input or selection recomputes the inline trigger. Setting busy or disabled closes the suggestion and policy panels. These states also block suggestion and policy changes.
Tokens and style hooks
PromptBar uses card, control, floating, and selected layers. Height, cluster, and radius changes use --bd-motion-base.
The rounded shape uses --bd-r-card. The compact pill uses token-derived control geometry and changes to --bd-r-panel when expanded. The policy trigger uses --bd-r-btn. Reduced motion disables layout and panel animation.
API
| Member | Type | Kind | Required | Default |
|---|---|---|---|---|
attachments | readonly PromptBarAttachment[] | prop | No | [] |
busy | boolean | prop | No | false |
commands | readonly PromptBarCommand[] | prop | No | [] |
contextItems | readonly PromptBarContextItem[] | prop | No | [] |
disabled | boolean | prop | No | false |
executionPolicies | readonly PromptBarExecutionPolicy[] | prop | No | [] |
labels | PromptBarLabels | (PromptBarLabels & { openAttachment: (attachment: PromptBarAttachment) => string; }) | PromptBarLabels & { transcribing: string; } | prop | Yes | |
listening | boolean | binding | No | false |
maxRows | number | prop | No | 6 |
measurement | PromptBarMeasurement | prop | No | undefined |
onAddAttachment | () => void | callback | No | undefined |
onListeningChange | (listening: boolean) => void | callback | No | undefined |
onOpenAttachment | ((attachment: PromptBarAttachment) => void) | undefined | callback | No | undefined |
onPolicyChange | (policy: PromptBarExecutionPolicy) => void | callback | No | undefined |
onRemoveAttachment | (attachment: PromptBarAttachment) => void | callback | No | undefined |
onRemoveContext | (item: PromptBarContextItem) => void | callback | No | undefined |
onSelectCommand | (command: PromptBarCommand) => void | callback | No | undefined |
onSelectContext | (item: PromptBarContextItem) => void | callback | No | undefined |
onStop | () => void | callback | No | undefined |
onSubmit | (detail: PromptBarSubmitDetail) => void | callback | No | undefined |
selectedContextIds | string[] | binding | No | [] |
selectedPolicyId | string | binding | No | '' |
shape | 'rounded' | 'pill' | prop | No | 'rounded' |
submitOnEnter | boolean | prop | No | true |
transcribing | boolean | false | undefined | prop | No | false |
value | string | binding | No | '' |