# Prompt Input

The chat composer, growing with its text.

> Every page: https://constella.aayush.cv/llms.txt

```tsx
<PromptInput onSubmit={send}>
  <PromptInputTextarea
    onChange={(event) => setText(event.target.value)}
    value={text}
  />
  <PromptInputFooter>
    <PromptInputTools>
      <InputGroupButton aria-label="Attach" size="icon-sm">
        <HugeiconsIcon icon={Attachment01Icon} />
      </InputGroupButton>
    </PromptInputTools>
    <PromptInputSubmit onStop={stop} state={status} />
  </PromptInputFooter>
</PromptInput>
```

## Installation

```bash
npx shadcn@latest add @constella/prompt-input
```

## Usage

```tsx
import {
  PromptInput,
  PromptInputFooter,
  PromptInputSubmit,
  PromptInputTextarea,
} from "@/components/ai/prompt-input";
```

`PromptInput` is a form around an [Input Group](https://constella.aayush.cv/docs/components/input-group/index.md). Enter submits it; Shift+Enter, and Enter while an IME is composing, add a line. The text grows to six lines, then scrolls.

## Composition

```
PromptInputWell
├── PromptInputBar
│   └── PromptInputBarButton
├── PromptInput
│   ├── PromptInputHeader
│   ├── PromptInputTextarea
│   └── PromptInputFooter
│       ├── PromptInputTools
│       └── PromptInputSubmit
└── PromptInputBar
```

## Prompt Input Header

Put an [Attachment](https://constella.aayush.cv/docs/components/attachment/index.md) group in a `PromptInputHeader`, above the text. A submit can send files with no text.

```tsx
<PromptInput onSubmit={send}>
  <PromptInputHeader>
    <AttachmentGroup>
      {files.map((file) => (
        <Attachment key={file} size="sm">
          …
        </Attachment>
      ))}
    </AttachmentGroup>
  </PromptInputHeader>
  <PromptInputTextarea />
  <PromptInputFooter>…</PromptInputFooter>
</PromptInput>
```

## Prompt Input Well

Put the prompt input in a `PromptInputWell`, a tinted tray, when it needs context around it, like a project or connected apps. A `PromptInputBar` is a row above or below it, usually on one side. Its controls line up with the composer's.

```tsx
<PromptInputWell>
  <PromptInputBar>
    <PromptInputBarButton>
      <HugeiconsIcon data-icon="inline-start" icon={Folder01Icon} />
      Select a project
    </PromptInputBarButton>
  </PromptInputBar>
  <PromptInput onSubmit={send}>…</PromptInput>
</PromptInputWell>
```

## Prompt Input Submit

Pass the chat's `status` as `state`. While it's `streaming`, the arrow swaps to a stop square and the button calls `onStop`.

| State       | Button     |
| ----------- | ---------- |
| `ready`     | Send       |
| `submitted` | Send, busy |
| `streaming` | Stop       |

```tsx
<PromptInputSubmit onStop={stop} state={status} />
```

## API Reference

| Part | Adds |
| --- | --- |
| `PromptInputTextarea` | Submits on Enter |
| `PromptInputHeader` | Above the text, for attachments |
| `PromptInputWell` | A tray around the prompt input and its bars |
| `PromptInputBar` | A row in the well |
| `PromptInputBarButton` | A ghost `sm` pill in secondary text |
| `PromptInputSubmit` | `state`: `"ready"`, `"submitted"` or `"streaming"`; `onStop` |

Every part takes `sx`, applied last.
