# Prompt Input Allows a user to send a message with file attachments to a large language model. It includes a textarea, file upload capabilities, a submit button, and a dropdown for selecting the model. The `PromptInput` component allows a user to send a message with file attachments to a large language model. It includes a textarea, file upload capabilities, a submit button, and a dropdown for selecting the model. See `scripts/prompt-input.tsx` for this example. ## Installation ```bash npx ai-elements@latest add prompt-input ``` ## Usage with AI SDK Build a fully functional chat app using `PromptInput`, [`Conversation`](/components/conversation) with a model picker: Add the following component to your frontend: ```tsx title="app/page.tsx" "use client"; import { Attachment, AttachmentPreview, AttachmentRemove, Attachments, } from "@/components/ai-elements/attachments"; import { PromptInput, PromptInputActionAddAttachments, PromptInputActionAddScreenshot, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuTrigger, PromptInputBody, PromptInputButton, PromptInputHeader, type PromptInputMessage, PromptInputSelect, PromptInputSelectContent, PromptInputSelectItem, PromptInputSelectTrigger, PromptInputSelectValue, PromptInputSubmit, PromptInputTextarea, PromptInputFooter, PromptInputTools, usePromptInputAttachments, } from "@/components/ai-elements/prompt-input"; import { GlobeIcon } from "lucide-react"; import { useState } from "react"; import { useChat } from "@ai-sdk/react"; import { Conversation, ConversationContent, ConversationScrollButton, } from "@/components/ai-elements/conversation"; import { Message, MessageContent, MessageResponse, } from "@/components/ai-elements/message"; const PromptInputAttachmentsDisplay = () => { const attachments = usePromptInputAttachments(); if (attachments.files.length === 0) { return null; } return ( {attachments.files.map((attachment) => ( attachments.remove(attachment.id)} > ))} ); }; const models = [ { id: "gpt-4o", name: "GPT-4o" }, { id: "claude-opus-4-20250514", name: "Claude 4 Opus" }, ]; const InputDemo = () => { const [text, setText] = useState(""); const [model, setModel] = useState(models[0].id); const [useWebSearch, setUseWebSearch] = useState(false); const { messages, status, sendMessage } = useChat(); const handleSubmit = (message: PromptInputMessage) => { const hasText = Boolean(message.text); const hasAttachments = Boolean(message.files?.length); if (!(hasText || hasAttachments)) { return; } sendMessage( { text: message.text || "Sent with attachments", files: message.files, }, { body: { model: model, webSearch: useWebSearch, }, } ); setText(""); }; return (
{messages.map((message) => ( {message.parts.map((part, i) => { switch (part.type) { case "text": return ( {part.text} ); default: return null; } })} ))} setText(e.target.value)} value={text} /> setUseWebSearch(!useWebSearch)} tooltip={{ content: "Search the web", shortcut: "⌘K" }} variant={useWebSearch ? "default" : "ghost"} > Search { setModel(value); }} value={model} > {models.map((model) => ( {model.name} ))}
); }; export default InputDemo; ``` Add the following route to your backend: ```ts title="app/api/chat/route.ts" import { streamText, UIMessage, convertToModelMessages } from "ai"; // Allow streaming responses up to 30 seconds export const maxDuration = 30; export async function POST(req: Request) { const { model, messages, webSearch, }: { messages: UIMessage[]; model: string; webSearch?: boolean; } = await req.json(); const result = streamText({ model: webSearch ? "perplexity/sonar" : model, messages: await convertToModelMessages(messages), }); return result.toUIMessageStreamResponse(); } ``` ## Features - Auto-resizing textarea that adjusts height based on content - File attachment support with drag-and-drop - Built-in screenshot capture action - Image preview for image attachments - Configurable file constraints (max files, max size, accepted types) - Automatic submit button icons based on status - Support for keyboard shortcuts (Enter to submit, Shift+Enter for new line) - Customizable min/max height for the textarea - Flexible toolbar with support for custom actions and tools - Built-in model selection dropdown - Built-in native speech recognition button (Web Speech API) - Optional provider for lifted state management - Form automatically resets on submit - Responsive design with mobile-friendly controls - Clean, modern styling with customizable themes - Form-based submission handling - Hidden file input sync for native form posts - Global document drop support (opt-in) ## Examples ### Cursor style See `scripts/prompt-input-cursor.tsx` for this example. ### Button tooltips Buttons can display tooltips with optional keyboard shortcut hints. Hover over the buttons below to see the tooltips. See `scripts/prompt-input-tooltip.tsx` for this example. ## Props ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `onSubmit` | `(message: PromptInputMessage, event: FormEvent) => void` | - | Handler called when the form is submitted with message text and files. | | `accept` | `string` | - | File types to accept (e.g., | | `multiple` | `boolean` | - | Whether to allow multiple file selection. | | `globalDrop` | `boolean` | - | When true, accepts file drops anywhere on the document. | | `syncHiddenInput` | `boolean` | - | Render a hidden input with given name for native form posts. | | `maxFiles` | `number` | - | Maximum number of files allowed. | | `maxFileSize` | `number` | - | Maximum file size in bytes. | | `onError` | `(err: { code: ` | - | Handler for file validation errors. | | `...props` | `React.HTMLAttributes` | - | Any other props are spread to the root form element. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the underlying Textarea component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.HTMLAttributes` | - | Any other props are spread to the toolbar div. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.HTMLAttributes` | - | Any other props are spread to the tools div. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `tooltip` | `string | { content: ReactNode; shortcut?: string; side?: ` | - | Optional tooltip to display on hover. Can be a string or an object with content, shortcut, and side properties. | | `...props` | `React.ComponentProps` | - | Any other props are spread to the underlying shadcn/ui Button component. | #### Tooltip Examples ```tsx // Simple string tooltip // Tooltip with keyboard shortcut hint // Tooltip with custom position ``` ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `status` | `ChatStatus` | - | Current chat status to determine button icon (submitted, streaming, error). | | `...props` | `React.ComponentProps` | - | Any other props are spread to the underlying shadcn/ui Button component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the underlying Select component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the underlying SelectTrigger component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the underlying SelectContent component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the underlying SelectItem component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the underlying SelectValue component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.HTMLAttributes` | - | Any other props are spread to the body div. | ### Attachments Attachment components have been moved to a separate module. See the [Attachment](/components/attachment) component documentation for details on ``, ``, ``, ``, and ``. ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the underlying DropdownMenu component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the underlying Button component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the underlying DropdownMenuContent component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the underlying DropdownMenuItem component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `label` | `string` | - | Label for the menu item. | | `...props` | `React.ComponentProps` | - | Any other props are spread to the underlying DropdownMenuItem component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `label` | `string` | - | Label for the menu item. | | `...props` | `React.ComponentProps` | - | Any other props are spread to the underlying DropdownMenuItem component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `initialInput` | `string` | - | Initial text input value. | | `children` | `React.ReactNode` | - | Child components that will have access to the provider context. | Optional global provider that lifts PromptInput state outside of PromptInput. When used, it allows you to access and control the input state from anywhere within the provider tree. If not used, PromptInput stays fully self-managed. ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `Omit, ` | - | Any other props (except align) are spread to the InputGroupAddon component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `openDelay` | `number` | `0` | Delay in milliseconds before opening. | | `closeDelay` | `number` | `0` | Delay in milliseconds before closing. | | `...props` | `React.ComponentProps` | - | Any other props are spread to the HoverCard component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the HoverCardTrigger component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `align` | `unknown` | - | Alignment of the hover card content. | | `...props` | `React.ComponentProps` | - | Any other props are spread to the HoverCardContent component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.HTMLAttributes` | - | Any other props are spread to the div element. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.HTMLAttributes` | - | Any other props are spread to the div element. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.HTMLAttributes` | - | Any other props are spread to the h3 element. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.HTMLAttributes` | - | Any other props are spread to the div element. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.HTMLAttributes` | - | Any other props are spread to the div element. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the Command component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the CommandInput component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the CommandList component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the CommandEmpty component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the CommandGroup component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the CommandItem component. | ### `` | Prop | Type | Default | Description | |------|------|---------|-------------| | `...props` | `React.ComponentProps` | - | Any other props are spread to the CommandSeparator component. | ## Hooks ### `usePromptInputAttachments` Access and manage file attachments within a PromptInput context. ```tsx const attachments = usePromptInputAttachments(); // Available methods: attachments.files; // Array of current attachments attachments.add(files); // Add new files attachments.remove(id); // Remove an attachment by ID attachments.clear(); // Clear all attachments attachments.openFileDialog(); // Open file selection dialog ``` ### `usePromptInputController` Access the full PromptInput controller from a PromptInputProvider. Only available when using the provider. ```tsx const controller = usePromptInputController(); // Available methods: controller.textInput.value; // Current text input value controller.textInput.setInput(value); // Set text input value controller.textInput.clear(); // Clear text input controller.attachments; // Same as usePromptInputAttachments ``` ### `useProviderAttachments` Access attachments context from a PromptInputProvider. Only available when using the provider. ```tsx const attachments = useProviderAttachments(); // Same interface as usePromptInputAttachments ``` ### `usePromptInputReferencedSources` Access referenced sources context within a PromptInput. ```tsx const sources = usePromptInputReferencedSources(); // Available methods: sources.sources; // Array of current referenced sources sources.add(sources); // Add new source(s) sources.remove(id); // Remove a source by ID sources.clear(); // Clear all sources ```