Suggestion chip
A suggestion a person can start from, next to a composer (the box where they type a question). Pressing it writes the suggestion into the box; it never sends it. A pill-shaped outline button: among buttons with words in them the pill means a suggestion, so it never reads as a state badge or an ordinary action.
Anatomy
The kit's Button (the design system's), variant outline at size sm (32px tall, text-xs medium), with one change: rounded-full. No icon. A long suggestion is cut at maxChars with an ellipsis and the whole of it moves into a Tooltip.
- 1Pill
Button outline, size sm, as the design system draws it: a 1px border, the page background, hover:bg-accent and the focus ring. rounded-full is what tells a suggestion apart from a state badge (8px radius, 20px, with an icon) and from an action button (8px radius); it is the one declared exception to Button's rounded-md.
- 2Suggestion
The text exactly as it will be written into the composer. Cut at maxChars (80 by default) with an ellipsis; the whole text goes into a Tooltip and stays the button's accessible name.
Recipes
Pressing a chip writes it into the box; the person can edit it and sends with the send button. Try it: the chip fills the box, and nothing is sent until you press send.
Nothing sent yet. Chips only fill the box.
import * as React from "react";
import { SuggestionChip } from "@/components/ui/suggestion-chip";
import { Textarea } from "@/components/ui/textarea";
const suggestions = ["Why did approvals drop yesterday?", "Refund order 88213"];
// Inside your component:
const [draft, setDraft] = React.useState("");
<Textarea value={draft} onChange={(e) => setDraft(e.target.value)} placeholder="Ask Yuno anything" />
<div className="flex flex-wrap gap-2">
{suggestions.map((q) => (
// Fills the box. Sending stays the person's act (the send button).
<SuggestionChip key={q} onPick={setDraft}>{q}</SuggestionChip>
))}
</div>The next questions an answer suggests. Same chip, same rule: it fills the composer, it does not ask on its own.
import { SuggestionChip } from "@/components/ui/suggestion-chip";
// setDraft writes into the composer's state (see the recipe above).
const next = ["Break it down by provider", "Compare with last month"];
<div className="flex flex-wrap gap-2">
{next.map((q) => (
<SuggestionChip key={q} onPick={setDraft}>{q}</SuggestionChip>
))}
</div>Past maxChars the text is cut with an ellipsis and the whole of it moves into a Tooltip. The chip also never outgrows its row: in a container narrower than the cut, CSS truncation takes over. Lower maxChars where the row is narrow.
import { SuggestionChip } from "@/components/ui/suggestion-chip";
// setDraft writes into the composer's state (see the first recipe).
const longSuggestion =
"Show me every declined card payment in Brazil over 500 USD from the last seven days, grouped by issuer and by decline reason";
<SuggestionChip onPick={setDraft}>{longSuggestion}</SuggestionChip>
<SuggestionChip onPick={setDraft} maxChars={40}>{longSuggestion}</SuggestionChip>Import
Copy this import line at the top of the file where you compose this atom.
import { SuggestionChip } from "@/components/ui/suggestion-chip";Props
Everything else from the underlying HTML or Radix primitive is forwarded via ...props.
| Prop | Type | Default | Description |
|---|---|---|---|
| children | string (required) | — | The suggestion, exactly as it will be written into the composer. |
| onPick | (suggestion: string) => void (required) | — | Write the suggestion into the composer. Never submit it here. |
| maxChars | number | 80 | Characters shown before an ellipsis; the whole suggestion moves into a Tooltip. |
| className | string | — | Extra classes on the button. Keep the pill and the size. |
Related
Cross-links to atoms and patterns you may reach for next.