Skip to content
Design System
Contact

AI chat

A thread with streaming replies, suggestions, stop and retry, and a composer.

ComponentsStreaming UI

Playground

Replies are canned and chosen by keyword, then streamed word by word. Stop cuts a reply short, and every fourth message fails on purpose so you can see the error and retry.

Preview
Demo data
Atlas

Hi Lena. I can summarise calls, draft follow-ups and flag deals at risk in the Acme Corporation workspace. What do you need?

Summarise the Northwind call
LF
Atlas

Summary of the Northwind call on Sep 28:

  1. They want SSO in place before signing the renewal.
  2. Budget is approved for 40 seats, up from 32.
  3. Priya Raman sends the security questionnaire by Oct 2.

Next step: book a technical review with their IT lead.

Props

Density
Streaming speed
example.tsxtsx
1import { AiChat } from "@/components/ui/ai-chat"
2
3<AiChat
4 suggestions={["Which deals are at risk?", "List overdue invoices"]}
5 stream={(prompt, { signal }) => streamReply(prompt, { signal })}
6/>

States

The composer at rest, focused and disabled, and an assistant reply while streaming, hovered, failed and rated.

States
  • Defaultrest
  • Atlas

    Two invoices are overdue: INV-2041 for Initech and INV-2037 for Hooli.

    Hover:hover → actions
  • Focus:focus-visible
  • Atlas

    Two invoices are overdue: INV-2041 for

    Loadingaria-busy
  • Disableddisabled
  • Atlas

    Atlas couldn't finish this reply. The request timed out; your message is safe.

    Errorretry
  • Atlas

    Two invoices are overdue: INV-2041 for Initech and INV-2037 for Hooli.

    Successaria-pressed

Examples

Compact density in a record side panel, starting from the empty state with suggestions.

Record side panel
Demo data

Acme Corporation

Renewal, closes Oct 30

Stage
Negotiation
Value
$48,000
Owner
LF Lena Fischer

Ask Atlas about this account

Summaries, follow-up drafts and risk checks, grounded in the records you can see.

API

PropTypeDefaultDescription
stream(prompt: string, ctx: { signal: AbortSignal }) => AsyncIterable<string>—Yields the reply in chunks. Stop aborts the signal. The docs use a canned, keyword-matched stream.
assistantNamestring"Atlas"Shown above replies, in the placeholder and in announcements.
density"comfortable" | "compact""comfortable"Compact tightens spacing and uses 13px text for side panels.
revealSpeed"slow" | "normal" | "fast""normal"Smooths bursty streams by revealing buffered text at a steady pace: about 11, 22 or 60 words a second.
showAvatarsbooleantrueAvatars beside messages. Turn off in narrow panels.
showSuggestionsbooleantrueSuggestion chips above the composer. A chip sends its text immediately.
suggestionsstring[]—Prompts for the chips. Chips already asked are hidden.
initialMessagesChatMessage[][]Starting thread. Empty shows the welcome state.
onFeedback(id: string, value: "up" | "down" | undefined) => void—Called when a reply is rated. Pressing the same thumb again clears it.

Accessibility

Keyboard

Send the message
Enter
New line
Shift+Enter
Reach Stop, suggestions and reply actions
Tab

Semantics and ARIA

  • The thread is a role="log" with aria-busy while streaming. Its own live updates are off, so tokens aren't read one by one.
  • A separate polite role="status" region says when a reply starts, then reads the finished reply once. Stop and failures are announced too.
  • After sending, focus returns to the composer, including when a suggestion chip is used and removed. Stop moves focus back to the composer as well.
  • Send is disabled while the composer is empty, and becomes a labelled Stop generating button while a reply streams.
  • Reply actions are icon buttons with labels and tooltips; the thumbs use aria-pressed. They stay visible on touch screens.
  • Brand violet marks AI: the assistant avatar, streaming caret, send button and suggestion chips.