Chat input
Where you type a request to the assistant and send it off.
Examples
Amount
nonedefault
affordable
too much
Actions
nonedefault
with controls
States
empty
focus
ready
running
cannot afford
disabled
Usage
When to use it
- Use
- The box of an in-app assistant, where a request is sent as written.
- Use
- Any place a single message is composed and sent, with an optional amount.
- Use
- A box that must show the money it moves before the person sends.
- Not for
- A form field that saves with a Save button. Use Textarea.
- Not for
- A one-line search. Use Input.
Rules
10 rules
- Must
- Pass amount and available when sending moves money; Send turns off when funds cannot cover it. Because without them the person presses Send blind and Send never checks the balance.
- Must
- Set running and onStop while a request runs, so Send becomes Stop; do not disable the box. Because a disabled field drops focus to the body and leaves no way to cancel.
- Must
- Control value and restore the text on failure; the field clears when onSubmit returns. Because the field clears right after onSubmit, so a failed request loses the text.
- Must
- Give each icon control in actions an aria-label. Because an icon-only Button reads as "button" with no name to a screen reader.
- Never
- Add a second colored button to the row; Send is the only lime, so extra controls stay ghost. Because a second lime control splits the next step in two beside Send.
- Should
- Make the placeholder show a good request, such as "Ask about your money"; never "Type here...".
- Must
- Keep the 8-line cap; the field scrolls inside 200px. Because a taller field pushes the last message and Send off a phone screen.
- Should
- Give the composer at least 280px; with an action and an amount, less leaves the text too little room.
- Should
- Keep actions to one or two 32px ghost icon buttons; put more behind one menu button.
- Never
- Place a ChatInput inside another form; it is a form. Because nested forms are invalid HTML and the submit bubbles into the outer onSubmit.
Accessibility
4 checks
- The field is a textbox named by a visually hidden label, Message.
- Enter sends unless an IME is composing; Shift+Enter starts a new line.
- Send and Stop are buttons named "Send" and "Stop" unless labels says otherwise.
- The text is 16px so iOS does not zoom on focus; Send and Stop are 32px, inside a 44px row.
Edge cases
8 edge cases
- Long request
- The field grows to 8 lines then scrolls; Send stays on the last line.
- Phone at 320px
- The row holds; the text takes what the controls leave.
- Right to left
- The row follows the direction; the Send arrow points up in both.
- Spaces only
- Send stays off and Enter does nothing; trim() decides.
- Send fails
- The field already cleared; restore it from a controlled value.
- Enter held down
- Sends once, then the field is empty so repeats do nothing.
- Phone keyboard
- Enter sends; use the keyboard new-line key for a line break.
- Forced colors
- The panel keeps a 1px border; the focus border color change is overridden. Add an outline for focus.
API
9 props
onSubmit(text: string) => voidvalue, defaultValue, onValueChangestringdefault''placeholderstringdefault'Ask about your money'amount, availablenumbercurrencystringdefault'USD'running, onStopboolean, functiondefaultfalsedisabledbooleandefaultfalseactionsReactNodelabels{message?, send?, stop?}defaultEnglish words
Tokens
12 tokens
--field- #f6f5f2
--line-strong- #cfcdc6
--radius-sheet- 24px
--accent-line- #7c8700
--fg- #0f0f0d
--fg-3- #6b6a63
--text-base- 16px
--fg-disabled- #a6a49b
--control-sm- 32px
--accent- #e4f222
--ink- #0f0f0d
--dur-instant- 80ms