AI Elements
Prompt input
The box people type into. A form around an input group: a growing textarea, a footer for tools, and a submit that turns into stop while the answer streams.
packages/design-system/components/ai-elements/prompt-input.tsx
Examples
Anatomy
- 01Form
- 02Input group
- 03Textarea
- 04Footer
- 05Tools, left
- 06Submit, right
Usage
import {
PromptInput, PromptInputFooter, PromptInputSubmit, PromptInputTextarea, PromptInputTools,
} from "@repo/design-system/components/ai-elements/prompt-input";
<PromptInput onSubmit={(message) => sendMessage({ text: message.text })}>
<PromptInputTextarea value={input} onChange={(event) => setInput(event.target.value)} />
<PromptInputFooter>
<PromptInputTools>...</PromptInputTools>
<PromptInputSubmit status={status} onStop={stop} disabled={!input.trim()} />
</PromptInputFooter>
</PromptInput>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| onSubmit* | (message: { text, files }, event) => void | Promise<void> | none | Called on Enter or the submit button. The form clears after it resolves. |
| accept / multiple / maxFiles / maxFileSize | string / boolean / number / number | none | Attachment rules. onError is called with max_files, max_file_size or accept. |
| globalDrop | boolean | false | Accept files dropped anywhere on the page. |
| PromptInputTextarea placeholder | string | "What would you like to know?" | Enter submits, Shift Enter adds a line, and IME composition is respected. |
| PromptInputSubmit status | "ready" | "submitted" | "streaming" | "error" | none | The icon: return, spinner, stop square, or X. |
| PromptInputSubmit onStop | () => void | none | While submitted or streaming, the button stops instead of submitting. |
| className | string | none | Merged last with cn(). Use it for layout (width, margin), not to restyle the component. |
Guidance
Do
- Pass the chat status so people can stop a long answer.
Don't
- Disable the textarea while streaming; let people draft the next message.