Prompt input

The box people type into. Grows with the text, sends on Enter, and turns into a stop button while a reply streams.

Loading preview…

Install

  1. 1

    Run this command in your Tailwind CSS project. It adds components/ai/prompt-input-card.tsx and installs its dependencies.

    $ npx shadcn@latest add https://gradientdeck.com/ai-components/r/prompt-input-card.json

Build a streaming chat interface in React →

Usage & API

Example

prompt-input-card.tsx
import { PromptInputCard } from "@/components/ai/prompt-input-card"

<PromptInputCard
  value="…"
  onChange={() => {}}
  onSubmit={() => {}}
/>

Props PromptInputCard

PropType & descriptionRequired
valuestringRequired
onChange(value: string) => voidRequired
onSubmit(value: string) => voidRequired
onStop() => voidOptional
streamingbooleanOptional
placeholderstringOptional
modelstringOptional
maxRowsnumberOptional

Dependencies

  • React
  • Tailwind CSS
  • motion
  • lucide-react
Implementation notes

Card with toolbar is PromptInputCard. The placeholder defaults to Ask anything, the textarea is labelled Message, and clicking the card focuses it. Send message stays visible whenever streaming is false, and it is disabled while the trim is empty. Stop generating replaces it only while streaming is true, with a filled square. Search is a local toggle. The model string sits in the toolbar and is not a menu. maxRows limits the auto-grow. The send key is a warm square, distinct from the dark stop key.

Choosing a layout

Use Prompt input for a conversation, where the next action is a message and the button has to become a stop control while tokens arrive. Card with toolbar is the everyday thread. Pill fits a narrow column or a mobile sheet. Hero fits the first screen of a builder, with suggestion strings that write themselves into the field and focus it. Floating dock fits a bar that stays on screen, because Ask, Agent and Plan travel out through onSubmit as a second argument. Workspace fits an empty project, with a heading and a leave link. Context bar fits an agent that must say where it runs before it sends.

Do not use it for image generation. Image prompt composer is the box that carries aspect ratio, a style, a count, a leave-out line and reference roles. Do not treat the card's model label as Model picker. That button never opens a list. Workspace has a real menu, with the models array, a check on the current row, and a Reasoning effort radio group of Low, Medium and High. Slash command menu and Mention menu are separate composers if / or @ has to filter a list and leave a chip. Suggestion chips are the prompts above an empty thread, not the field itself.

Why did Enter send while I was still confirming a character?

It should not. Each growing layout checks event.nativeEvent.isComposing and returns before onSubmit. Shift+Enter also returns without submitting, so a newline is possible. Floating dock is the exception: it is a single-line input with no key handler, so Enter only submits because it is inside a form. If a compose event is still firing, check that you did not wrap the textarea in another onKeyDown that calls submit first.

The paperclip and the model name do nothing. Is that a bug?

On Card with toolbar, Pill and the dock's mention button, those controls are visual. Search on the card toggles a local pressed style and never leaves the component. Pass model only to change the label. Wire a real list with the workspace menu, or put Model picker next to the field. Context bar's effort button is wired, but only as a cycle of Low, Medium and High, not as a catalog of models.