Prompt Input
Composer for chat and agent apps. Enter to send, Shift+Enter for a new line, paste or drop files, stop while streaming.
Installation
Usage
import {
PromptInput,
PromptInputSubmit,
PromptInputTextarea,
PromptInputToolbar,
PromptInputTools,
PromptInputAttachButton,
PromptInputAttachments,
} from "@/components/ai/prompt-input"
const { status, sendMessage, stop } = useChat()
<PromptInput status={status} onSubmit={({ text, files }) => sendMessage({ text, files })}>
<PromptInputAttachments />
<PromptInputTextarea />
<PromptInputToolbar>
<PromptInputTools>
<PromptInputAttachButton />
</PromptInputTools>
<PromptInputSubmit onStop={stop} />
</PromptInputToolbar>
</PromptInput>Examples
Dictation
Dictation for the prompt input. Speech is transcribed into the textarea as you talk, so it can be reviewed before sending.
Installed separately, so the base component stays lean:
import { PromptInputMic } from "@/components/ai/prompt-input-mic"
<PromptInputToolbar>
<PromptInputTools />
<PromptInputMic />
<PromptInputSubmit />
</PromptInputToolbar>PromptInputMic
| Prop | Type | Default |
|---|---|---|
langBCP 47 language for recognition, e.g. "it-IT". | string | navigator.language |
useSpeechRecognition
| Prop | Type | Default |
|---|---|---|
returnsWeb Speech API. Chrome, Edge and Safari. Elsewhere supported is false and the mic disables itself. | { supported, listening, transcript, error, start, stop } | – |
Mentions
Type @ in the composer to mention files, tools or agents. Keyboard first; picks show as chips and are reported for sending.
Installed separately, so the base component stays lean:
import { PromptInputMentions } from "@/components/ai/prompt-input-mentions"
<PromptInput onSubmit={({ text }) => send({ text, mentions })}>
<PromptInputMentions items={items} onMentionsChange={setMentions} />
<PromptInputTextarea />
…
</PromptInput>PromptInputMentions
| Prop | Type | Default |
|---|---|---|
itemsWhat can be mentioned. Filtered by the text after @. | { id, label, type: "file" | "folder" | "tool" | "agent", description? }[] | – |
onMentionsChangeCurrent picks. Cleared after submit. | (mentions) => void | – |
Tools menu
Tools like web search or deep research folded into one toolbar menu, so they fit at any width. The trigger shows the active tool, or how many are on.
Installed separately, so the base component stays lean:
import { PromptInputOptionMenu } from "@/components/ai/prompt-input-option-menu"
<PromptInputTools>
<PromptInputAttachButton />
<PromptInputOptionMenu options={tools} value={enabled} onValueChange={setEnabled} />
</PromptInputTools>PromptInputOptionMenu
| Prop | Type | Default |
|---|---|---|
optionsThe tools to offer. | { id, label, icon?, description? }[] | – |
valueEnabled ids. | string[] | – |
onValueChangeSend it with the message. | (ids: string[]) => void | – |
labelTrigger text when none are on, and the menu heading. | string | "Tools" |
Scope
Tell the agent which parts of the product it may work on. A context label and a multi-select of modules in the composer footer; nothing selected means everything.
Installed separately, so the base component stays lean:
import { PromptInputScope } from "@/components/ai/prompt-input-scope"
<PromptInputFrame>
<PromptInput onSubmit={({ text }) => send({ text, scope })}>…</PromptInput>
<PromptInputFooter>
<PromptInputScope
label="Workspace context"
icon={<FolderIcon />}
scopes={modules}
allLabel="All modules"
value={scope}
onValueChange={setScope}
/>
</PromptInputFooter>
</PromptInputFrame>PromptInputScope
| Prop | Type | Default |
|---|---|---|
scopesWhat the agent can be limited to. | { id, label, description? }[] | – |
valueSelected ids. Empty means all; picking every scope also resets to empty. | string[] | – |
onValueChangeSend it with the message. | (ids: string[]) => void | – |
labelContext line on the left, e.g. "Workspace context". | ReactNode | – |
iconIcon before the label. | ReactNode | – |
allLabelShown when nothing is selected. | string | "All" |
menuLabelHeading at the top of the menu. | string | – |
API Reference
PromptInput
| Prop | Type | Default |
|---|---|---|
onSubmitCalled on the send key or the send button. Input clears after. | ({ text, files }) => void | – |
statusMatches AI SDK useChat. Drives the submit button. | "ready" | "submitted" | "streaming" | "error" | "ready" |
valueControlled value. | string | – |
onValueChangeChange handler for controlled use. | (value: string) => void | – |
submitOnEnter sends and Shift+Enter adds a line, or ⌘/Ctrl+Enter sends and Enter adds a line (better for long prompts and code). | "enter" | "mod-enter" | "enter" |
acceptFile types for the picker. | string | – |
PromptInputSubmit
| Prop | Type | Default |
|---|---|---|
onStopCalled when pressed while streaming. | () => void | – |
PromptInputFrame
| Prop | Type | Default |
|---|---|---|
childrenAn optional PromptInputHeader, the PromptInput, and an optional PromptInputFooter. Header and footer animate when added or removed. | ReactNode | – |
PromptInputHeader
| Prop | Type | Default |
|---|---|---|
iconShown before the context text. | ReactNode | – |
PromptInputOption
| Prop | Type | Default |
|---|---|---|
iconShown before the label. | ReactNode | – |
pressedControlled state. Or use defaultPressed. | boolean | – |
onPressedChange | (pressed: boolean) => void | – |