Skip to content

Prompt input

The composer of an AI chat or agent panel. It grows with the text, shows attachment chips, hosts the Model selector and Context meter in its slots, and turns Send into Stop while the agent works. Focus draws the AI gradient around it.

  • checkout-flow.fig4.2 MB
  • audit-report.pdf820 KB
  • screenshot.pngUploading…

AI can make mistakes. Check important information.

Type / or @ to open a menu. Enter sends, Shift+Enter adds a line. The uploading file blocks Send until you remove it.

size="lg" · attachments · ModelSelector in toolbar · ContextMeter in actions · / and @ menusLive · light and dark follow the theme switch

Add the source to a shadcn project

npx shadcn@latest add https://docs.atomus.io/r/ai-prompt-input.jsonOpen in v0

Installs the component source, its CSS and the Atomus tokens into components/atomus/. How the registry works

Generating response
ready · streaming (Stop) · disabledLive · light and dark follow the theme switch

From guidelines/components/ai-prompt-input.md

Properties, variants and anatomy of the Figma components. React props use the same names.

The composer of an AI chat or agent panel: an auto-growing text area, attachment chips, a toolbar slot for the Model selector and tool toggles, and one button that switches between Send and Stop. Typing / or @ opens a command or mention menu. Part of the Agent kit.

Figma: component set Prompt input on the 🤖 Agent kit page of Atomus 4.0 (node 25553:1955), connected to React with Code Connect. Attachment chips: Prompt attachment (node 25553:1183). React props use the same names as the Figma properties below.

Property Type / options
Text text
Placeholder text
Size md · lg
State Ready · Submitted · Streaming · Error · Disabled
Attachments slot (attachment chips)
Attach button boolean (on)
Toolbar slot slot (Model selector, toggles)
Actions slot slot (Context meter, voice)
Command menu boolean (off)
Disclaimer text

Anatomy

  1. Container: bg-primary, border-primary, radius 2xl (3xl at lg). When focused, the border becomes --gradient-ai with a bg-ai-subtle glow.
  2. Attachment chips: file icon or thumbnail, name, size or upload state, remove button.
  3. Text area: grows from minRows (1) to maxRows (8), then scrolls.
  4. Bottom bar: Attach button and Toolbar slot on the left; Actions slot and Send / Stop on the right.
  5. Send / Stop: brand-solid arrow while ready; fg-contrast square while the agent works.
  6. Command menu: a listbox above the input, filtered by what follows / or @.
  7. Disclaimer: one centred line under the input.

Use for

  • The main input of a chat, copilot side panel or agent workspace.
  • Follow-up questions under an AI answer inside a card or drawer.

Not for

  • Search fields: use Input with a search icon.
  • Long-form writing without an AI reply: use a textarea.
  • Forms with several fields: use Input, Select and the other form components.

Keyboard

  • Enter sends; Shift+Enter adds a line. Enter never sends while the agent is working, and never during IME composition.
  • In the command menu: ↑ ↓ move, Enter or Tab inserts, Esc closes.
  • The Stop button is a normal button: Tab to it and press Enter or Space.

Accessibility

  • The text area has a visually hidden label (label, default “Message”); the placeholder is only a hint.
  • Send and Stop have accessible names (submitLabel, stopLabel) and change name with the state.
  • The command menu uses aria-activedescendant, so focus stays in the text area; a polite live region says how many suggestions there are.
  • “Generating response” is announced when the state turns busy.
  • The disclaimer is linked with aria-describedby.
import { PromptInput, ModelSelector, ContextMeter } from '@stanvision/atomus-react';
<PromptInput
status={status} // 'ready' | 'submitted' | 'streaming' | 'error'
onSubmit={(text, files) => send(text, files)}
onStop={stop}
attachments={files}
onAttach={openFilePicker}
onRemoveAttachment={removeFile}
toolbar={<ModelSelector models={models} value={model} onChange={setModel} />}
actions={<ContextMeter used={usage.tokens} limit={200000} />}
triggers={[{ char: '/', items: commands }, { char: '@', label: 'People', items: people }]}
disclaimer="AI can make mistakes. Check important information."
/>

Full types and defaults are in React API at the end of the page.

  • status — submitted and streaming show Stop and block Enter; the text area stays editable.
  • value / defaultValue / onChange — controlled or uncontrolled text; onSubmit gets the trimmed text and the attachments.
  • attachments, onAttach, onRemoveAttachment — chips with an upload state; an uploading file blocks Send.
  • toolbar and actions — slots on the left and right of the bottom bar.
  • triggers — / and @ menus with keyboard support (↑ ↓, Enter or Tab, Esc).
  • size — md for panels, lg for full-page chat. minRows / maxRows set the growth.

From the Figma guidelines.

Do

  • Keep one Prompt input per conversation, docked at the bottom of the thread.
  • Put the Model selector in the Toolbar slot and the Context meter in the Actions slot.
  • Show Stop while the agent works and keep the text area editable, so people can draft the next message.
  • Block Send while a file is still uploading; show the upload state on its chip.
  • Add a one-line disclaimer when answers can be wrong.

Forbidden

  • Never disable the text area while streaming — only Send is blocked.
  • Never use the placeholder as the only label.
  • Never put more than one primary action in the bar: Send is the primary action.
  • Never move focus out of the text area when the reply arrives.
  • Never send on Enter while a command menu is open — Enter inserts the highlighted item.

Generated from react/src/components by scripts/gen-react-api.mjs — the same tables agents read in guidelines/components/ai-prompt-input.md.

Use only these props; anything else is not part of the API.

Figma: Prompt input — the composer of an AI chat: auto-growing text, attachments, a toolbar slot, send ↔ stop, and “/” or “@” menus. Enter sends, Shift+Enter adds a line, Esc closes a menu.

import { PromptInput } from '@stanvision/atomus-react'; — source: react/src/components/ai/PromptInput.tsx

Prop Type Default Description
value string — Figma: Text (controlled)
defaultValue string '' Initial text when uncontrolled
onChange (value: string) => void — Called with the new value.
onSubmit (text: string, attachments: PromptAttachment[]) => void — Called with the trimmed text and the attachments on Enter or the send button
onStop () => void — Called by the stop button while status is submitted or streaming
status 'ready' | 'submitted' | 'streaming' | 'error' 'ready' Figma: State — submitted and streaming turn Send into Stop and block new submits.
placeholder string 'Ask anything…' Figma: Placeholder — a hint, never the label
label string 'Message' Accessible name of the text area (visually hidden)
attachments PromptAttachment[] [] Figma: Attachments — chips above the text
onAttach () => void — Figma: Attach button — shows the paperclip button; open your file picker here
onRemoveAttachment (id: string) => void — Called by a chip’s remove button
toolbar ReactNode — Figma: Toolbar slot — left of the bottom bar (ModelSelector, tool toggles)
actions ReactNode — Figma: Actions slot — right of the bottom bar, before Send (ContextMeter, voice)
triggers PromptTrigger[] [] Figma: Command menu — “/” and “@” menus that open while typing
disclaimer ReactNode — Figma: Disclaimer — one line under the input (“AI can make mistakes. Check important info.”)
minRows number 1 Rows shown when empty
maxRows number 8 Rows before the text area scrolls
size 'md' | 'lg' 'md' Figma: Size — md for side panels, lg for a full-page chat
disabled boolean — Disables the control.
autoFocus boolean — Focuses the text area on mount — only on pages whose main task is the chat
submitLabel string 'Send message' Accessible name of the send button
stopLabel string 'Stop generating' Accessible name of the stop button
clearOnSubmit boolean true Clears the text after submit (uncontrolled only)
className string — Extra class on the root element (layout only — never restyle colours or sizes).

Accepts only the props above.

PromptAttachment:

Field Type Description
id string Stable key
name string File name shown on the chip
kind? 'file' | 'image' image shows previewUrl as a thumbnail
size? string Human-readable size (“2.4 MB”)
previewUrl? string Thumbnail for images
status? 'uploading' | 'ready' | 'error' uploading shows a spinner; error marks the chip

PromptTrigger:

Field Type Description
char string The character that opens the menu: “/” for commands, “@” for mentions
label? string Accessible name of the menu (“Commands”, “People”)
items PromptCommand[] The menu items, filtered by what is typed after the character
onSelect? (item: PromptCommand) => void Called when an item is chosen (after its text is inserted)

PromptCommand:

Field Type Description
value string Inserted after the trigger character (“summarize” → “/summarize “)
label string Text in the menu
description? string One line under the label
icon? ReactNode Leading icon (16px)
insert? string Exact text to insert instead of trigger + value