# PromptInput A growing message composer with attachments, tools, a model picker and a send button that stops a streaming reply. ```ehtml Example import { PromptInput, PromptInputTools, PromptInputButton, PromptInputSubmit, PromptInputActionMenu, PromptInputActionAddAttachments, PromptInputSelect, } from "@elements/ui/prompt-input"; import { Icon } from "@elements/ui/icon"; send(chat, m)}> Search stop(chat)} /> ``` ## Parts | Part | What it is | |---|---| | `PromptInput` | The form: hidden file input, the box, a header of attachment chips, the textarea, and the footer (default slot). | | `.prompt-input-textarea` | Grows from minRows to maxRows. Enter submits, Shift+Enter breaks a line, paste attaches files, Backspace on empty removes the last chip. | | `.prompt-input-header` | Attachment and source chips, then slot header. | | `PromptInputTools` | A row of tool buttons on the left of the footer. | | `PromptInputButton` | A ghost tool button with an optional tooltip, shortcut hint and toggle. | | `PromptInputSubmit` | Send. Its icon follows status; with onStop it stops a reply in flight. | | `PromptInputActionMenu` | The + menu (a DropdownMenu opening upward). | | `PromptInputActionMenuItem` | A plain item in the + menu. | | `PromptInputActionAddAttachments` | Add photos or files: opens the file dialog. | | `PromptInputActionAddScreenshot` | Take screenshot: captures one frame of a screen the user picks. | | `PromptInputSelect` | A quiet NativeSelect for the model. | | `PromptInputSpeechButton` | Dictation into the textarea with the Web Speech API; disabled where unsupported. | | `PromptInputTabsList / Tab / TabLabel / TabBody / TabItem` | Labelled sections of suggestions, for a hover card or popover. | | `.prompt-input-drop` | The Drop files to attach overlay while dragging files over the box. | ## Attributes ### PromptInput | Attribute | Type | Default | Description | |---|---|---|---| | `value` | `string` (two-way) | `""` | The text. | | `files` | `AttachmentData[]` (two-way) | `[]` | Attached files: { id, filename, mediaType, url (blob), size, file }. | | `sources` | `AttachmentData[]` (two-way) | `[]` | Referenced source documents, shown as chips and sent with the message. | | `placeholder` | `string` | `"What would you like to know?"` | Textarea placeholder. | | `label` | `string` | `"Message"` | The textarea's accessible name. | | `name` | `string` | `"message"` | The textarea's name. | | `minRows` | `number` | `2` | Minimum height in lines. | | `maxRows` | `number` | `8` | The height where it stops growing and scrolls. | | `accept` | `string` | `""` | Accepted files: image/\*, application/pdf, .md. Empty accepts all. | | `multiple` | `boolean` | `false` | The file dialog takes several files. | | `globalDrop` | `boolean` | `false` | Accept file drops anywhere on the page. | | `maxFiles` | `number` | `0` | Most files attached at once; 0 is no limit. | | `maxFileSize` | `number` | `0` | Largest file in bytes; 0 is no limit. | | `submitOnEnter` | `boolean` | `true` | Enter submits; Shift+Enter breaks a line. | | `allowEmpty` | `boolean` | `false` | Submit with no text, files or sources. | | `disabled` | `boolean` | `false` | Disables the textarea and every control in the box. | | `autofocus` | `boolean` | `false` | Focus the textarea when it mounts. | | `onSubmit` | `(message: { text, files, sources }, e: SubmitEvent) => void \| Promise` | `() => {}` | Called on submit, with each file's blob url converted to a data url (the File stays attached). Clears when it returns or resolves; keeps everything when it throws or rejects. | | `onError` | `(err: { code: "max_files" \| "max_file_size" \| "accept", message: string }) => void` | `() => {}` | A file was refused. | | `class` | `string` | `""` | Extra classes on the form. | | `attrs` | `Record` | `{}` | Other attributes for the form. | | `textareaAttrs` | `Record` | `{}` | Attributes for the textarea: maxlength, aria-describedby, autocomplete. | | `onTextareaKeyDown` | `(e: KeyboardEvent) => void` | `() => {}` | Runs before the built-in keys; preventDefault skips Enter to submit. | ### PromptInputActionMenu | Attribute | Type | Default | Description | |---|---|---|---| | `icon` | `IconName` | `"plus"` | The trigger's icon (PromptInputActionMenuTrigger children). | | `label` | `string` | `"Add"` | The + button's and the menu's name. | | `open` | `boolean` (two-way) | `false` | Whether the menu is open. | ### PromptInputSubmit | Attribute | Type | Default | Description | |---|---|---|---| | `status` | `"ready" \| "submitted" \| "streaming" \| "error"` | `"ready"` | The chat status: enter, spinner, stop square or x. | | `onStop` | `(() => void) \| undefined` | `undefined` | Set it and the button stops while submitted or streaming. | | `disabled` | `boolean` | `false` | Not clickable; Enter does not submit either. | | `variant` | `ButtonVariant` | `"primary"` | Button variant. | | `label` | `string` | `""` | Overrides Submit / Stop. | | `size` | `"xs" \| "sm" \| "md" \| "lg"` | `"sm"` | Icon button size. | | `onclick` | `(e: MouseEvent) => void` | `() => {}` | Runs before the submit when not stopping; e.preventDefault() cancels the send. | ### PromptInputButton | Attribute | Type | Default | Description | |---|---|---|---| | `label` | `string` | `""` | Accessible name; required for icon-only buttons without a tooltip. | | `tooltip` | `string` | `""` | Shown on hover and focus. | | `shortcut` | `string` | `""` | A key hint after the tooltip text. | | `tooltipSide` | `"top" \| "right" \| "bottom" \| "left"` | `"top"` | Tooltip side. | | `icon` | `boolean` | `false` | Square, icon only. | | `toggle` | `boolean` | `false` | A toggle button (aria-pressed). | | `pressed` | `boolean` (two-way) | `false` | Whether the toggle is on. | | `variant` | `ButtonVariant` | `"ghost"` | Button variant. | | `onclick` | `(e: MouseEvent) => void` | `() => {}` | Click handler. | ### PromptInputActionAddAttachments | Attribute | Type | Default | Description | |---|---|---|---| | `label` | `string` | `"Add photos or files"` | Item text. | ### PromptInputActionAddScreenshot | Attribute | Type | Default | Description | |---|---|---|---| | `label` | `string` | `"Take screenshot"` | Item text. | | `onSelect` | `(e: Event) => void` | `() => {}` | Runs first; preventDefault skips the capture. | ### PromptInputSelect | Attribute | Type | Default | Description | |---|---|---|---| | `value` | `string` (two-way) | `""` | The chosen option. | | `options` | `NativeSelectOptionData[]` | `[]` | { value, label, group?, disabled? }. | | `label` | `string` | `"Model"` | Accessible name. | ### PromptInputSpeechButton | Attribute | Type | Default | Description | |---|---|---|---| | `lang` | `string` | `""` | Recognition language; defaults to the page's lang. | | `label` | `string` | `"Voice input"` | Accessible name. | ## Slots | Slot | Part | Content | |---|---|---| | `default` | `PromptInput` | The footer: PromptInputTools on the left, PromptInputSubmit on the right. | | `header` | `PromptInput` | Extra content after the attachment chips. | | `default` | `PromptInputButton` | Icon and text. | | `default` | `PromptInputSubmit` | A custom icon in place of the status icon. | | `default` | `PromptInputActionMenu` | Menu items. | ## Keyboard | Keys | Action | |---|---| | `Enter` | Submits. Not during IME composition, not while submit is disabled, and not while a reply is generating. | | `Shift + Enter` | Inserts a line break. | | `Backspace` | In an empty textarea, removes the last attachment. | | `Ctrl / Cmd + V` | Pasting files attaches them. | | `Tab` | Attachment chips and header content, then the textarea, then tools and submit (DOM order). | | `Escape` | Closes an open menu, tooltip or preview. | ## Data attributes | Attribute | Values | On | Description | |---|---|---|---| | `data-dragging` | present | .prompt-input-box | Files are being dragged over it. | | `data-pending` | present | .prompt-input-box | An async onSubmit is running. | | `data-disabled` | present | .prompt-input | | | `data-status` | `"ready" \| "submitted" \| "streaming" \| "error"` | .prompt-input-submit | | | `data-state` | `"on" \| "off"` | .prompt-input-button (toggle) | | | `data-listening` | present | .prompt-input-speech | | ## Accessibility - The textarea is named by label (Message). The file input is hidden from the tab order and named Upload files. - Submit is named Submit, or Stop while a reply is submitted or streaming, and sets aria-busy while submitted. - Attachments are a list of chips; each remove button is named Remove `` and returns focus to the textarea. - Tool buttons carry aria-label and aria-pressed; tooltips describe them. - Disabled uses a disabled fieldset, so every control inside is disabled natively, and the box takes no dropped, pasted or chosen files. - File errors go to onError; the caller decides how to show them (a toast, a field message). ## See also - [Icon](icon): An inline stroke icon from the set the templates draw their own controls with, sized in pixels and colored by the text around it. - [Message](message): One chat message with avatar, author, time, streaming Markdown, attachments, actions and response branches. - [MessageList](message-list): A conversation that stays pinned to the newest message unless the reader scrolls up. - [Attachment](attachment): A file or source as a thumbnail, chip or row, with preview, size, upload progress and remove.