Quick replies
Choices the model offers inline. Single select sends on the first pick, multi select collects picks for one Send, and Other opens a field for anything the options missed. Once answered, the replies lock to a record of the choice.
On this page
Four answers and Other. A pick sends at once, then the replies lock to show the answer.
Installation
Usage
import { QuickReplies } from "@/components/ui/chatcn/quick-replies"
<QuickReplies
label="How should I handle the flaky test?"
allowOther
options={[
{ value: "fix", label: "Find the root cause" },
{ value: "retry", label: "Add a retry for now" },
]}
answer={part.output?.answer ?? null}
onSubmit={(answer) => addToolResult({ toolCallId: part.toolCallId, output: answer })}
/>onSubmit fires once with { values, other? }. Pass answer when rendering a thread from history, so replies answered earlier show as locked. While options stream, loading reserves expectedCount placeholder chips.
Examples
Multiple choice
mode="multi" toggles picks and sends them with the Send button (or Cmd+Enter). min and max bound the count, and options past max disable. layout="list" gives each option a full-width row with a description.
Chips with a typed Other, and a list with descriptions, a two pick limit and a disabled option.
States
Streaming, answered, answered with Other, disabled, and long labels without shortcuts.
Props
| Prop | Type | Notes |
|---|---|---|
options | { value, label, description?, disabled? }[] | |
mode | "single" | "multi" | Default single |
allowOther, otherLabel, otherPlaceholder | Other opens a text field | |
sendLabel | string | Default Send |
min, max | number | Multi select bounds |
onSubmit | (answer: { values, other? }) => void | Called once |
answer, defaultAnswer | QuickReplyAnswer | null | Locks the replies |
disabled | boolean | For example while the agent is still running |
layout | "chips" | "list" | Default chips |
shortcuts | boolean | 1 to 9 in Kbd. Default true |
label | string | The question, for screen readers |
loading, expectedCount | boolean, number | Placeholder chips |
labels | Partial<QuickRepliesLabels> | Every other string the replies show or announce, for translation |
Keyboard
| Key | Action |
|---|---|
Tab | Into the replies. The current option is the one focus stop |
| Arrow keys | Move between options, wrapping, skipping disabled ones. Mirrored in RTL |
Home, End | First or last option |
Enter, Space | Pick (single) or toggle (multi) |
1 to 9 | Pick or toggle that option while focus is inside |
Cmd+Enter, Ctrl+Enter | Send in multi mode |
Enter in Other | Send. Ignored while an IME is composing |
Escape in Other | Close the field and return to the Other chip |
Accessibility
- A toolbar named by
labelwith roving focus. Multi select options usearia-pressed, and shortcuts are exposed witharia-keyshortcuts. - Number keys only work while focus is inside, so they never steal digits from the composer.
- Answered replies are a group whose name includes the answer, for example How should I handle the flaky test, answered: Add a retry for now.
Motion
- The first time options appear they rise 4 px and fade in, 35 ms apart, at most six. They never animate again, and not at all under reduced motion.
- Picks press to 0.97. Focus moved by keys never animates.