# Prompt composer

A shadcn/ui prompt composer for AI assistants: a capsule with Enter to send, quick prompts, permission mode, model and depth controls, and usage limits.

> For the complete documentation index, see [llms.txt](/llms.txt). Markdown variants are available for the docs, pricing and about pages: append `.md` to the URL or send an `Accept: text/markdown` header (the home page answers the header too). An agent skill is available at [/.well-known/agent-skills/site-skill.md](/.well-known/agent-skills/site-skill.md).

## At a glance

- **Good for:** AI assistant and copilot chat inputs; CRM and sales dashboard prompts; Agent consoles and internal tools; Any app where people write prompts to a model
- **Category:** Inputs · **Type:** Text inputs · **Style:** Motion, Minimal, Dark mode
- **See it:** [Live preview](https://www.craftui.space/docs/components/prompt-composer) · [Video](https://pub-52b0d9cec7c64f638ba3f33a29718fa6.r2.dev/Videos_product_cards/inputs-prompt-composer.48a28305.mp4)

## Install

```bash
pnpm dlx shadcn@latest add https://www.craftui.space/r/prompt-composer.json
```

This is a paid item (CMP-HCWPB1): the install needs a craftUI plan or a purchase of it. Signed in, the docs page gives your personal install command. Plans: https://www.craftui.space/pricing

## Usage

```tsx
import PromptComposer from "@/components/ui/prompt-composer";

export default function Page() {
  return <PromptComposer />;
}
```

With no props it renders with demo content; pass your own through the props below.

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `value` | `string` | — | The controlled text value for the prompt input. |
| `onChange` | `(value: string) => void` | — | Called whenever the text input value changes. |
| `onSubmit` | `(prompt: string, attachments: ComposerAttachment[]) => void` | — | Called when the user presses Enter or clicks the Send button. |
| `placeholder` | `string` | — | Input placeholder string. Defaults to "Ask anything...". |
| `showQuickPrompts` | `boolean` | `true` | Whether quick prompts drawer above the composer is visible. Defaults to true. |
| `quickPrompts` | `string[]` | `built-in demo content` | List of quick prompt strings to show in the dropdown. |
| `onSelectQuickPrompt` | `(prompt: string) => void` | — | Called when a quick prompt is clicked. If omitted or returns true/undefined, the composer automatically fills the prompt input. |
| `isListening` | `boolean` | — | Controlled voice listening state. |
| `onListeningChange` | `(listening: boolean) => void` | — | Called when the microphone voice listening state toggles. |
| `models` | `Model[]` | `built-in demo content` | Available AI models with depths and descriptions. Defaults to ChatGPT, Claude, Gemini, DeepSeek. |
| `selectedModelId` | `string` | — | Controlled selected model ID. |
| `selectedDepthId` | `string` | — | Controlled selected depth ID. |
| `onSelectModel` | `(modelId: string, depthId: string) => void` | — | Called when a model or reasoning depth is selected. |
| `permissionModes` | `PermissionMode[]` | `built-in demo content` | Available permission modes (e.g. Auto-approve, Full access). |
| `selectedPermissionId` | `string` | — | Controlled selected permission mode ID. |
| `onSelectPermission` | `(id: string) => void` | — | Called when a permission mode is chosen. |
| `usageLimits` | `UsageLimit[]` | `built-in demo content` | Usage limit indicators shown at the bottom of the model dropdown. |
| `attachments` | `ComposerAttachment[]` | — | Controlled attachments list. When provided, attachments pills are shown above the input. If omitted, a sample mock attachment is created on clicking file/image/folders to demonstrate the UI. |
| `onAddAttachment` | `(attachment: ComposerAttachment) => void` | — | Called when an attachment is added. |
| `onRemoveAttachment` | `(id: string) => void` | — | Called when an attachment pill is dismissed. |
| `onSelectAttachmentType` | `(type: AddAttachmentType) => void` | — | Raw attachment type click handler if custom handling (e.g. opening a system file picker) is needed. |
| `disabled` | `boolean` | `false` | Disable the composer inputs and buttons. |

It also accepts every `<div>` attribute (`className`, `id`, `aria-*` and so on).

### `ComposerAttachment`

| Field | Type | Description |
| --- | --- | --- |
| `id` (required) | `string` | — |
| `name` (required) | `string` | — |
| `type` (required) | `AddAttachmentType` | — |
| `size` | `string` | — |
| `file` | `globalThis.File` | — |

### `Model`

| Field | Type | Description |
| --- | --- | --- |
| `id` (required) | `string` | — |
| `name` (required) | `string` | — |
| `description` (required) | `string` | — |
| `speed` (required) | `string` | — |
| `depths` (required) | `ModelDepth[]` | — |

### `PermissionMode`

| Field | Type | Description |
| --- | --- | --- |
| `id` (required) | `string` | — |
| `label` (required) | `string` | — |
| `subtitle` (required) | `string` | — |

### `UsageLimit`

| Field | Type | Description |
| --- | --- | --- |
| `id` (required) | `string` | — |
| `label` (required) | `string` | — |
| `percentLeft` (required) | `number` | — |
| `resetLabel` (required) | `string` | — |

### `ModelDepth`

| Field | Type | Description |
| --- | --- | --- |
| `id` (required) | `string` | — |
| `label` (required) | `string` | — |

## Files

The install adds:

- `components/ui/prompt-composer.tsx`

npm dependencies (installed for you): `motion`, `lucide-react`.