Prompt Input
PromptInput is a complete prompt composer for AI assistants: auto-grows, attaches via button / drag and drop / pasted images, validates files inline, and Send turns into Stop while the model responds.
Import
Install from npm, copy the source into your project with @yugen-ui/cli or the shadcn CLI, or import directly when working in this repo.
// npm install yugen-uiimport { PromptInput, validateFiles, formatFileSize } from "yugen-ui";Variants
Each tile is a standalone example: hover to copy, or press Code to see the source.
Text only, with key hint
Disabled
Usage
- Set accept / maxSize to the server's limits so errors show early.
- Put the model and tool pickers in toolbar, close to the Send button.
- Allow stopping (onStop) when answers are long.
- Don't clear the content when sending fails. Return false from onSubmit.
- Don't send when Enter is only confirming text in an input method.
- Don't hide why a file was rejected.
Props
| Prop · Type | Default | Description |
|---|---|---|
| onSubmit({ text, files }) => void | boolean | Default: — | Sends; returning false keeps the content. |
| value / defaultValue / onValueChangestring | Default: — | Text (controlled / uncontrolled). |
| files / defaultFiles / onFilesChangeFile[] | Default: — | Attached files. |
| accept / maxFiles / maxSizestring / number / number (byte) | Default: — | File checks; onFilesRejected receives the reasons. |
| streaming / onStopboolean / () => void | Default: — | Blocks sending; Stop button. |
| toolbarReactNode | Default: — | Slot after the attach button. |
| allowAttachmentsboolean | Default: true | Attach button, drag and drop, pasting files. |
| maxRows / showHint / disablednumber / boolean / boolean | Default: 8 / false / false | Maximum rows before scrolling, key hint, disabled. |
| placeholder / label / sendLabel / stopLabelstring | Default: — | Visible text and accessible labels. |
Messages
Text built into the component: labels, aria-labels, screen reader announcements.
English by default. Change it with the messages prop of YugenProvider, by the namespace below; messagesVi has the Vietnamese set. See Interface language.
messages.promptInput
| Key · Type | Default (English) | messagesVi |
|---|---|---|
| placeholderstring | Default (English)"Ask anything…" | messagesVi"Hỏi bất cứ điều gì…" |
| labelstring Nhãn truy cập cho ô soạn. | Default (English)"Enter a prompt" | messagesVi"Nhập yêu cầu" |
| sendstring Tên nút gửi / dừng. | Default (English)"Send" | messagesVi"Gửi" |
| stopstring | Default (English)"Stop responding" | messagesVi"Dừng phản hồi" |
| attachstring Tên nút đính kèm. | Default (English)"Attach files" | messagesVi"Đính kèm tệp" |
| attachmentsstring Tên danh sách tệp đã đính kèm. | Default (English)"Attachments" | messagesVi"Tệp đính kèm" |
| remove(fileName: string) => string Tên nút gỡ một tệp. | Default (English)(fileName) => `Remove ${fileName}` | messagesVi(fileName) => `Gỡ ${fileName}` |
| hintstring Gợi ý phím (showHint). | Default (English)"Enter to send · Shift+Enter for a new line" | messagesVi"Enter để gửi · Shift+Enter xuống dòng" |
| dropzonestring Lớp phủ khi kéo tệp vào. | Default (English)"Drop files to attach" | messagesVi"Thả tệp để đính kèm" |
| attachedOne(fileName: string) => string Đọc qua live region sau khi đính kèm / gỡ tệp. | Default (English)(fileName) => `Attached ${fileName}` | messagesVi(fileName) => `Đã đính kèm ${fileName}` |
| attachedMany(count: number) => string | Default (English)(count) => (count === 1 ? "Attached 1 file" : `Attached ${count} files`) | messagesVi(count) => `Đã đính kèm ${count} tệp` |
| removed(fileName: string) => string | Default (English)(fileName) => `Removed ${fileName}` | messagesVi(fileName) => `Đã gỡ ${fileName}` |
| duplicate(fileName: string) => string Lỗi kiểm tra tệp (validateFiles). | Default (English)(fileName) => `“${fileName}” is already attached.` | messagesVi(fileName) => `“${fileName}” đã được đính kèm.` |
| invalidType(fileName: string) => string | Default (English)(fileName) => `“${fileName}” isn't an allowed file type.` | messagesVi(fileName) => `“${fileName}” không đúng định dạng cho phép.` |
| tooLarge(fileName: string, maxSize: string) => string | Default (English)(fileName, maxSize) => `“${fileName}” is larger than ${maxSize}.` | messagesVi(fileName, maxSize) => `“${fileName}” vượt quá ${maxSize}.` |
| tooMany(maxFiles: number) => string | Default (English)(maxFiles) => (maxFiles === 1 ? "You can attach only 1 file." : `You can attach up to ${maxFiles} files.`) | messagesVi(maxFiles) => `Chỉ đính kèm tối đa ${maxFiles} tệp.` |