---
title: Prompt Input
description: A composable chat input with auto-resizing textarea and action slots
---
import PromptInputDefault from "@/components/nexus-ui/examples/prompt-input/default";
import PromptInputBasic from "@/components/nexus-ui/examples/prompt-input/basic";
import GeminiInput from "@/components/nexus-ui/examples/prompt-input/gemini-input";
import PromptInputMultipleActions from "@/components/nexus-ui/examples/prompt-input/multiple-actions";
import PromptInputWithTooltips from "@/components/nexus-ui/examples/prompt-input/with-tooltips";
A flexible, composable input component for building chat interfaces. Includes an auto-resizing textarea with scroll support and customizable action slots for buttons like send, attach, and more.
## Installation
```bash
npx shadcn@latest add @nexus-ui/prompt-input
```
```bash
pnpm dlx shadcn@latest add @nexus-ui/prompt-input
```
```bash
yarn dlx shadcn@latest add @nexus-ui/prompt-input
```
```bash
bunx shadcn@latest add @nexus-ui/prompt-input
```
Copy and paste the following code into your project.
Update the import paths to match your project setup.
## Usage
```tsx keepBackground
import PromptInput, {
PromptInputTextarea,
PromptInputActions,
PromptInputActionGroup,
PromptInputAction,
} from "@/components/nexus-ui/prompt-input";
```
```tsx keepBackground
{/* Left-aligned actions */}
{/* Right-aligned actions */}
```
## Examples
### Basic
A minimal prompt input with just a textarea and send button.
### With Multiple Actions
Combine multiple action buttons in a single group.
### With Tooltips
Action buttons wrapped in shadcn tooltips for descriptive hover labels.
## Vercel AI SDK Integration
Connect Prompt Input to the [Vercel AI SDK](https://sdk.vercel.ai) for streaming chat interfaces.
Install the AI SDK
```bash
npm install ai @ai-sdk/react @ai-sdk/openai
```
Create your chat API route
```ts title="app/api/chat/route.ts"
import { convertToModelMessages, streamText, UIMessage } from "ai";
import { openai } from "@ai-sdk/openai";
export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json();
const result = streamText({
model: openai("gpt-4o-mini"),
system: "You are a helpful assistant.",
messages: await convertToModelMessages(messages),
});
return result.toUIMessageStreamResponse();
}
```
Wire Prompt Input to `useChat`
Use `onSubmit` for Enter-to-submit. Shift+Enter inserts a new line.
```tsx
"use client";
import { useState, useCallback } from "react";
import { useChat } from "@ai-sdk/react";
import { DefaultChatTransport } from "ai";
import { Button } from "@/components/ui/button";
import PromptInput, {
PromptInputActions,
PromptInputAction,
PromptInputActionGroup,
PromptInputTextarea,
} from "@/components/nexus-ui/prompt-input";
import { ArrowUp02Icon, SquareIcon } from "@hugeicons/core-free-icons";
import { HugeiconsIcon } from "@hugeicons/react";
export default function ChatWithPromptInput() {
const { sendMessage, status } = useChat({
transport: new DefaultChatTransport({ api: "/api/chat" }),
});
const [input, setInput] = useState("");
const isLoading = status !== "ready";
const handleSubmit = useCallback(
(value?: string) => {
const trimmed = (value ?? input).trim();
if (trimmed) {
sendMessage({ text: trimmed });
setInput("");
}
},
[input, sendMessage],
);
return (
);
}
```
## API Reference
### PromptInput
The root container that wraps the textarea and action bar.
void (optional)",
description:
"Called when Enter is pressed in the textarea (without Shift). Receives the current textarea value. Use with value/onChange on PromptInputTextarea for controlled mode. Shift+Enter inserts a new line.",
},
className: {
type: "string",
description: "Additional CSS classes to apply to the container.",
},
onClick: {
type: "React.MouseEventHandler",
description:
"Called after the internal click handler. The internal handler focuses the textarea when clicking non-interactive areas.",
},
}}
/>
### PromptInputTextarea
An auto-resizing textarea wrapped in a scroll area. Accepts all standard `textarea` props including `disabled` and `onKeyDown`. Use `onSubmit` on PromptInput for Enter-to-submit; Shift+Enter inserts a new line.
",
description: "Called when the value changes. Use with value for controlled mode.",
},
onKeyDown: {
type: "React.KeyboardEventHandler",
description: "Called when a key is pressed. Fired after the internal Enter/Shift+Enter handler.",
},
placeholder: {
type: "string",
default: '"How can I help you today?"',
description: "Placeholder text displayed when the textarea is empty.",
},
ref: {
type: "React.Ref",
description:
"Forwarded ref to the textarea element. Merged with the internal ref used for click-to-focus.",
},
value: {
type: "string",
description: "Controlled value. Use with onChange for controlled mode.",
},
}}
/>
### PromptInputActions
A flex container for action buttons. Uses `justify-between` to position child groups at opposite ends.
### PromptInputActionGroup
Groups related action buttons together with a horizontal layout.
### PromptInputAction
A wrapper for individual action buttons. Supports polymorphism via `asChild`.