Prompt Input
The PromptInput component is a compound component for AI chat interfaces. It includes a textarea with auto-resize, keyboard shortcuts, and an optional toolbar for actions.
Variations
With toolbar and button
Put tool buttons inside PromptInput.Tools. Each PromptInput.Button is an icon-only toggle for a toolbar action (attach, mention, and so on).
Streaming state
Pass status="streaming" to PromptInput.Submit while a response is generating. The submit icon becomes a stop icon so the same control cancels the stream.
Installation
import { PromptInput } from '@harnessio/ui/components'
return ( <PromptInput.Root onSubmit={handleSubmit}> <PromptInput.Textarea placeholder="What would you like to know?" onChange={(e) => setValue(e.target.value)} /> <PromptInput.Toolbar> <PromptInput.Tools> <PromptInput.Button prefixIcon="plus" tooltipProps={{ title: 'Add' }} /> </PromptInput.Tools> <PromptInput.Submit /> </PromptInput.Toolbar> </PromptInput.Root>)Anatomy
PromptInput is a compound component. PromptInput.Root is a real <form>; the textarea and toolbar are composed inside it.
<PromptInput.Root onSubmit={handleSubmit}> <PromptInput.Textarea placeholder="What would you like to know?" /> <PromptInput.Toolbar> <PromptInput.Tools> <PromptInput.Button prefixIcon="plus" tooltipProps={{ title: "Add" }} /> </PromptInput.Tools> <PromptInput.Submit /> </PromptInput.Toolbar></PromptInput.Root>PromptInput.Root— the form wrapper. It renders a native<form>and forwards standard form attributes, includingonSubmit. It holds no value state of its own.PromptInput.Textarea— an auto-resizing textarea. It grows with its content, submits the form onEnter, and inserts a newline onShift + Enter. Its field name ismessage.PromptInput.Toolbar— a container that lays out the tools on the left and the submit button on the right.PromptInput.Tools— a container for toolbar buttons.PromptInput.Button— an icon-only toggle for a toolbar action.PromptInput.Submit— the submit button. It shows a send icon by default and a stop icon whilestatus="streaming".PromptInput.Tags— an optional row of removable tags (for example, attached context), rendered when you pass a non-emptytagsarray.
Best practices
Do
- Keep the placeholder short and action-oriented (“Ask me anything…”).
- Switch
PromptInput.Submittostatus="streaming"while a response generates, so the control doubles as a stop button. - Group related toolbar actions inside
PromptInput.Tools, and give eachPromptInput.Buttona tooltip so its icon reads clearly.
Don’t
- Don’t add a separate submit
<button>—PromptInput.Submitalready submits the form, and the textarea submits onEnter. - Don’t rely on the toolbar for critical actions on very narrow layouts where the buttons may crowd the submit control.
Content
- The textarea placeholder should describe what the person can ask, not label the field (“Ask me anything…”, not “Prompt”).
- Give each toolbar button a concise tooltip title that names the action (“Add”, “Attach”, “Mention”).
Accessibility
Keyboard
Entersubmits the form;Shift + Enterinserts a new line.- The toolbar buttons and submit control are standard buttons, reachable and activatable with the keyboard in the usual way.
Labeling
PromptInput.Textareais not labeled on its own — the placeholder is not a substitute for an accessible name. Pass alabel(oraria-label) so the field is announced.PromptInput.SubmitandPromptInput.Buttonare icon-only. Give the submit control anaria-label(for example, “Send” / “Stop”), and give each toolbar button atooltipProps.title(which names the toggle).
Known limitations
- The component does not set an accessible name on the textarea or the submit button for you. Provide those in the surrounding markup.
Properties
PromptInput.Root
Renders a <form> and accepts all standard form attributes (onSubmit, className, and so on).
Prop | Required | Default | Type |
|---|---|---|---|
| onSubmit | false | FormEventHandler<HTMLFormElement> | |
| children | false | ReactNode | |
| className | false | string |
PromptInput.Textarea
Accepts all Textarea props. autoResize is always on and the field name is message.
Prop | Required | Default | Type |
|---|---|---|---|
| placeholder | false | 'What would you like to know?' | string |
| value | false | string | |
| onChange | false | ChangeEventHandler<HTMLTextAreaElement> | |
| label | false | string | |
| disabled | false | boolean |
PromptInput.Submit
Extends Button (rendered icon-only, type="submit", size xs).
Prop | Required | Default | Type |
|---|---|---|---|
| status | false | 'streaming' | |
| children | false | ReactNode | |
| disabled | false | boolean |
PromptInput.Button
Extends Toggle (rendered icon-only, default variant='outline', size xs).
Prop | Required | Default | Type |
|---|---|---|---|
| prefixIcon | true | IconV2 name | |
| prefixIconProps | false | Partial<IconPropsV2> | |
| tooltipProps | false | IconWithTooltipProps | |
| selected | false | boolean | |
| onChange | false | (selected: boolean) => void | |
| disabled | false | boolean |
PromptInput.Toolbar & PromptInput.Tools
Both are layout containers and accept standard <div> attributes, including className and children.
PromptInput.Tags
Prop | Required | Default | Type |
|---|---|---|---|
| tags | false | PromptInputTag[] | |
| onRemove | false | (id: string) => void |