input
Prompt Input
An auto-growing chat composer with attachments and a keyboard-navigable slash-command menu.
- input
- chat
- composer
- slash-command
Live preview
Quick usage
usage
import { PromptInput } from "@pinky-ui/ai-ui";
<PromptInput
value={value}
onChange={setValue}
onSubmit={sendMessage}
commands={[{ id: "clear", label: "clear", description: "Clear the thread" }]}
/>Install
Add @pinky-ui/ai-ui as a dependency, or use the CLI to copy this component's source directly into your project — no dependency to manage, fully editable.
shell
npm install @pinky-ui/ai-uishell
pnpm add @pinky-ui/ai-uishell
yarn add @pinky-ui/ai-uishell — copies source into your project
npx pinky-ui add prompt-inputPrefer to run the whole repository locally instead?
repository
git clone https://github.com/florash/Pinky-UI.git
cd Pinky-UI
npm install
npm run devProps
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | — | The composer's current text. |
| onChange | (value: string) => void | — | Fires on every keystroke. |
| onSubmit | (value: string) => void | — | Fires on Enter (without Shift) or the send button, when the value isn't empty. |
| placeholder | string | "Message…" | Placeholder text. |
| disabled | boolean | false | Disables the field and the send button, e.g. while a response streams. |
| maxRows | number | 8 | The textarea stops growing past this many lines and scrolls instead. |
| attachments | PromptAttachment[] | [] | Attachment chips shown above the field. |
| onRemoveAttachment | (id: string) => void | — | Shows a remove control on each attachment chip. |
| onAttach | () => void | — | Shows an attach button when provided. |
| commands | SlashCommand[] | [] | Typing "/" at the start of an empty line opens this menu. |
| onCommand | (command: SlashCommand) => void | — | Fires when a slash command is chosen; the field is cleared after. |
| className | string | — | Applied to the outer element. |
Accessibility
- The field exposes `role="combobox"` with `aria-expanded`/`aria-controls`/`aria-autocomplete` only while the command menu is open, so it reads as plain text input the rest of the time.
- The command menu is a real `role="listbox"`/`role="option"` pair, fully operable with ArrowUp/ArrowDown/Enter/Escape.
Performance
- Textarea height is read from `scrollHeight` and written directly to the DOM node — no controlled re-render for the resize.
Reduced motion
The command menu appears and disappears without its slide/fade transition; the textarea's height still adjusts, since that is layout, not decoration.
When to use
- The primary composer for a chat or agent interface.
When not to use
- A single-line search or filter field — this is sized and keyed for multi-line prompts.