Prompt input
Takes the next instruction for an agent.
Layout
stackeddefault
inline
States
empty
with text
focus
working
not sent
disabled
Usage
Rules
7 rules
- Never
- Add a second primary inside the composer; your tools are ghost buttons or values, and Send stays the one slab. Because Send is the one action the composer leads with, and a second slab beside it splits the eye.
- Must
- Pass the run's status and onStop, so Send turns into Stop while the agent works. Because without them the person can only wait, and Escape has nothing to stop.
- Must
- On a failed send, set status="error" and error to a sentence; keep the text. Because the edge turns red and the sentence says why, and an instruction the person wrote is never lost.
- Should
- Write the placeholder as an example of an instruction for this place ("Backfill yesterday for eu-west-2"). Because a concrete example says what the agent can do here, where "Type a message" says nothing.
- Never
- Restyle the composer's edge, corners or height; place it with className only. Because the edge and the body carry the rest, hover, focus and failure states, and every control sits 6px inside that edge so Send is as far from the end as Attach is from the start.
- Must
- Make a tool in the footer 26px (--control-sm), a small Button or a value in a 26px box. Because Attach, your tools, the hint and Send share one centre line 6px above the bottom edge, and a 32px tool pushes the row taller than Send.
- Must
- Read the sent text from onSubmit, which trims it and never fires on an empty prompt. Because reading the textarea on a click sends spaces and sends twice on Enter.
State order
6 states, highest first
- 1
- disabled
- 2
- not sent
- 3
- working
- 4
- focus
- 5
- hover
- 6
- rest
Accessibility
4 checks
- The textarea is named "Message the agent" (labels.label); the hint is decoration.
- Send stays in the tab order while the prompt is empty, so it can be found, and refuses the press.
- A failed send sets aria-invalid and describes the field by its error sentence.
- Focus turns the body white with the edge --focus doubled inward and a pale halo, as in every Sodium field; Send is the real Button, so its disabled look and focus ring are the button's.
Keyboard
3 keys
- Enter
- Sends; nothing fires while an IME is composing.
- Shift+Enter
- Breaks the line.
- Escape
- Stops the run while the agent works.
Edge cases
5 edge cases
- Long instruction
- Grows to ten lines (six inline), then scrolls.
- Enter while working
- Still sends, so the product can queue it.
- Only spaces
- Never sends.
- No field-sizing in the browser
- Grows by measuring its scroll height instead.
- Dark theme
- Send becomes the yellow tint with a yellow line and label.
API
11 props
onSubmit(text: string) => voidstatus'ready' | 'submitted' | 'streaming' | 'error'default'ready'onStop() => voidonAttach() => voidlayout'stacked' | 'inline'default'stacked'value, defaultValue, onValueChangestring, string, functiondefault''toolsReactNodeerrorstringminRows, maxRowsnumberdefault2, 10 (inline 1, 6)disabledbooleandefaultfalselabelsPromptInputLabelsdefaultEnglish
Tokens
23 tokens
--field-bg- #f8f7f3
--field-hover- #fefefd
--field-edge-hover- #ecebe5
--field-ring-hover- #f4f3ee
--field-focus-bg- #ffffff
--field-ring-focus- #fff1b8
--field-ring-fail- #fbdcd8
--line- #e2dfd5
--focus- #7a5d00
--fail- #b3261e
--fail-text- #b3261e
--well- #f4f3ee
--text-1- #161512
--text-3- #6b675e
--type-body-sm- 400 14px/20px var(--font-sans)
--type-micro- 400 11px/14px var(--font-mono)
--type-caption- 400 13px/18px var(--font-sans)
--control-sm- 26px
--space-1-5- 6px
--primary-bg- #ffd400
--primary-text- #161512
--primary-edge- #d9b400
--dur-light- 240ms