InputMessage
Chat-style message composer with an auto-resizing textarea, flexible left/right action slots, and a built-in send button on a Surface-2 substrate.
Installation
Example
Basic
Left Slot Only
Right Slot Only
Send Handler
Disabled
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | — | Controlled textarea value. |
| onValueChange | (value: string) => void | — | Called with the new value on every textarea change. |
| onSend | (value: string, files: File[]) => void | — | Fires on Enter (without Shift) or send-button click. Receives the trimmed value and the currently-attached files. Skipped when the value is empty and no files are attached. |
| placeholder | string | "Ask me anything…" | Placeholder shown when the value is empty. While a file is being dragged over the component (and attachments are enabled), the placeholder swaps to “Drop files here to add to chat”. |
| leftSlot | ReactNode | (ctx) => ReactNode | — | Content rendered in the bottom-left action area. May be a render-fn that receives `{ openFilePicker, files }` — `openFilePicker(acceptOverride?)` opens the native file picker (optionally scoped to a subset of accept types, e.g. `"image/*"`). |
| rightSlot | ReactNode | (ctx) => ReactNode | — | Content rendered in the bottom-right action area, before the built-in send button. Same render-fn shape as `leftSlot`. |
| disabled | boolean | false | Disables the textarea, send button, and drag-and-drop. |
| minRows | number | 1 | Minimum visible rows before the textarea grows. |
| maxRows | number | 8 | Maximum visible rows before the textarea starts to scroll. |
| clickToFocus | boolean | true | When true, clicking anywhere on the surrounding container (outside of buttons / links / inputs) focuses the textarea. |
| sendLabel | string | "Send" | Accessible label for the send button. |
| files | File[] | — | Controlled list of attached files. Pair with `onFilesChange` to enable drag-and-drop and the file-picker slot helper. When omitted, attachment behavior is disabled. |
| onFilesChange | (files: File[]) => void | — | Called when files are added (drag-drop or picker) or removed via the preview tile’s × button. Duplicate drops of the same file (same name + size + lastModified) are silently de-duplicated. |
| accept | string | "image/png,image/jpeg,application/pdf" | Accepted MIME types as a comma-separated string. Used by both the file picker and the drag-and-drop filter. |
| maxFiles | number | — | Maximum number of attached files. Extra files beyond this limit are dropped. |
| filePreviewSize | number | 80 | Side length (in pixels) of each preview tile. Images use object-cover; PDFs render the first page via pdfjs; other types fall back to a centered icon. |
| textareaProps | TextareaHTMLAttributes | — | Extra props forwarded to the underlying textarea (value, onChange, onKeyDown, disabled and placeholder are controlled by the component). |