Prompt Input
The PromptInput
component allows a user to send a message to a large language model. It includes a textarea, a submit button, and a dropdown for selecting the model.
Installation
npx ai-elements@latest add prompt-input
Usage
import { PromptInput, PromptInputSubmit, PromptInputTextarea, PromptInputToolbar,} from '@/components/ai-elements/prompt-input';
<PromptInput onSubmit={() => {}} className="mt-4 relative"> <PromptInputTextarea onChange={(e) => {}} value={''} /> <PromptInputToolbar> <PromptInputSubmit className="absolute right-1 bottom-1" disabled={false} status={'ready'} /> </PromptInputToolbar></PromptInput>
Usage with AI SDK
Built a fully functional chat app using PromptInput
, Conversation
with a model picker:
Add the following component to your frontend:
app/page.tsx
'use client';
import { PromptInput, PromptInputButton, PromptInputModelSelect, PromptInputModelSelectContent, PromptInputModelSelectItem, PromptInputModelSelectTrigger, PromptInputModelSelectValue, PromptInputSubmit, PromptInputTextarea, PromptInputToolbar, PromptInputTools,} from '@/components/ai-elements/prompt-input';import { GlobeIcon, MicIcon } from 'lucide-react';import { useState } from 'react';import { useChat } from '@ai-sdk/react';import { Conversation, ConversationContent, ConversationScrollButton,} from '../ai-elements/conversation';import { Message, MessageContent } from '../ai-elements/message';import { Response } from '../ai-elements/response';
const models = [ { id: 'gpt-4o', name: 'GPT-4o' }, { id: 'claude-opus-4-20250514', name: 'Claude 4 Opus' },];
const InputDemo = () => { const [text, setText] = useState<string>(''); const [model, setModel] = useState<string>(models[0].id);
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); sendMessage( { text: text }, { body: { model: model, }, }, ); setText(''); };
const { messages, status, sendMessage } = useChat();
return ( <div className="max-w-4xl mx-auto p-6 relative size-full rounded-lg border h-[600px]"> <div className="flex flex-col h-full"> <Conversation> <ConversationContent> {messages.map((message) => ( <Message from={message.role} key={message.id}> <MessageContent> {message.parts.map((part, i) => { switch (part.type) { case 'text': return ( <Response key={`${message.id}-${i}`}> {part.text} </Response> ); default: return null; } })} </MessageContent> </Message> ))} </ConversationContent> <ConversationScrollButton /> </Conversation>
<PromptInput onSubmit={handleSubmit} className="mt-4"> <PromptInputTextarea onChange={(e) => setText(e.target.value)} value={text} /> <PromptInputToolbar> <PromptInputTools> <PromptInputButton> <MicIcon size={16} /> </PromptInputButton> <PromptInputButton> <GlobeIcon size={16} /> <span>Search</span> </PromptInputButton> <PromptInputModelSelect onValueChange={(value) => { setModel(value); }} value={model} > <PromptInputModelSelectTrigger> <PromptInputModelSelectValue /> </PromptInputModelSelectTrigger> <PromptInputModelSelectContent> {models.map((model) => ( <PromptInputModelSelectItem key={model.id} value={model.id}> {model.name} </PromptInputModelSelectItem> ))} </PromptInputModelSelectContent> </PromptInputModelSelect> </PromptInputTools> <PromptInputSubmit disabled={!text} status={status} /> </PromptInputToolbar> </PromptInput> </div> </div> );};
export default InputDemo;
Add the following route to your backend:
app/api/chat/route.ts
import { streamText, UIMessage, convertToModelMessages } from 'ai';
// Allow streaming responses up to 30 secondsexport const maxDuration = 30;
export async function POST(req: Request) { const { model, messages }: { messages: UIMessage[]; model: string } = await req.json();
const result = streamText({ model: model, messages: convertToModelMessages(messages), });
return result.toUIMessageStreamResponse();}
Features
- Auto-resizing textarea that adjusts height based on content
- Automatic submit button icons based on status
- Support for keyboard shortcuts (Cmd/Ctrl + Enter to submit)
- Customizable min/max height for the textarea
- Flexible toolbar with support for custom actions and tools
- Built-in model selection dropdown
- Responsive design with mobile-friendly controls
- Clean, modern styling with customizable themes
- Form-based submission handling
Props
<PromptInput />
[...props]?:
React.HTMLAttributes<HTMLFormElement>
Any other props are spread to the root form element.
<PromptInputTextarea />
[...props]?:
React.ComponentProps<typeof Textarea>
Any other props are spread to the underlying Textarea component.
<PromptInputToolbar />
[...props]?:
React.HTMLAttributes<HTMLDivElement>
Any other props are spread to the toolbar div.
<PromptInputTools />
[...props]?:
React.HTMLAttributes<HTMLDivElement>
Any other props are spread to the tools div.
<PromptInputButton />
[...props]?:
React.ComponentProps<typeof Button>
Any other props are spread to the underlying shadcn/ui Button component.
<PromptInputSubmit />
[...props]?:
React.ComponentProps<typeof Button>
Any other props are spread to the underlying shadcn/ui Button component.
<PromptInputModelSelect />
[...props]?:
React.ComponentProps<typeof Select>
Any other props are spread to the underlying Select component.
<PromptInputModelSelectTrigger />
[...props]?:
React.ComponentProps<typeof SelectTrigger>
Any other props are spread to the underlying SelectTrigger component.
<PromptInputModelSelectContent />
[...props]?:
React.ComponentProps<typeof SelectContent>
Any other props are spread to the underlying SelectContent component.
<PromptInputModelSelectItem />
[...props]?:
React.ComponentProps<typeof SelectItem>
Any other props are spread to the underlying SelectItem component.
<PromptInputModelSelectValue />
[...props]?:
React.ComponentProps<typeof SelectValue>
Any other props are spread to the underlying SelectValue component.