Skip to content

Message

One turn in a conversation. User messages are bubbles; assistant and tool messages flow full-width next to their avatar, with the AI label beside the name. Every message is an article named by its speaker.

System
Kristina added the QA agent to this chat · Today
Kristina

Which token should I use for a card border?

Atomus AssistantAI

Use --color-border-secondary. It is the hairline for cards, tables and dividers, and it switches with Light and Dark mode. Keep border-primary for inputs and other controls.

Version 1 of 3
system · user · assistant with branch ‹ 1/3 ›, copy, regenerate and FeedbackLive · light and dark follow the theme switch

Add the source to a shadcn project

npx shadcn@latest add https://docs.atomus.io/r/ai-message.jsonOpen in v0

Installs the component source, its CSS and the Atomus tokens into components/atomus/. How the registry works

Atomus AssistantAI
Checking the token files for every border colour that
Atomus AssistantAI

Here are the three radius modes:

You stopped this response.
Atomus AssistantAI
QA agent
status="streaming" · "stopped" · "error" · role="tool"Live · light and dark follow the theme switch

From guidelines/components/ai-message.md

Properties, variants and anatomy of the Figma components. React props use the same names.

One turn in a conversation. The role sets the layout: user messages are right-aligned bubbles on bg-tertiary; assistant and tool messages flow full-width next to an avatar; system messages are a centred line between hairlines. Every message is an <article> named by its speaker, so it is always clear who said what. Part of the Agent kit.

Figma: component set Message on the 🤖 Agent kit page of Atomus 4.0 (node 25552:1473), connected to React with Code Connect. Default avatars: Message avatar (node 25552:989). React props use the same names as the Figma properties below.

Property Type / options
Role User · Assistant · System · Tool
Status Streaming · Done · Error · Stopped
Name text
Show name boolean (on, off for User)
AI label boolean (on)
Avatar instance swap (Avatar)
Timestamp text
Content slot (text, Reasoning, Tool call, Approval, Sources)
Actions Copy · Regenerate · Edit · Branch · slot (Feedback)
Actions visibility Always · Hover

Anatomy

  1. Avatar: the AI mark on bg-ai-subtle for assistants, a wrench for tools, an Avatar for people.
  2. Header: speaker name, AI label (assistants), timestamp.
  3. Content slot: text, then any Reasoning, Tool call, Approval, Streaming text and Sources, in the order they happened.
  4. Status notice: “You stopped this response.” or an error with Retry.
  5. Actions: branch switcher ‹ 1/3 ›, Copy, Edit (user), Regenerate (assistant), then the slot (Feedback).

Use for

  • Chat threads, copilot panels and agent logs.
  • Showing several agents in one thread: give each a distinct name and avatar.

Not for

  • Person-to-person chat without AI: see the Messaging guidelines.
  • Notifications and activity feeds: use the Activity item.

Accessibility

  • Speaker clarity: the name is always in the accessible name of the article, even when hidden visually for user messages.
  • Assistant messages carry the AI label, so AI content is never identified by colour or position alone.
  • status="streaming" sets aria-busy on the article; the Streaming text inside announces the reply.
  • Errors use role="alert"; Copy confirms “Copied to clipboard” in a status region.
  • Icon-only actions have names (“Copy”, “Regenerate response”, “Edit message”, “Previous version”).
import { Message, StreamingText, Feedback } from '@stanvision/atomus-react';
<Message role="user" name="Kristina" copyText={prompt} onEdit={edit}>
<p>{prompt}</p>
</Message>
<Message
role="assistant"
name="Atomus Assistant"
status={status} // 'streaming' | 'done' | 'error' | 'stopped'
copyText={answer}
onRegenerate={regenerate}
branch={{ index: 2, count: 3, onPrevious, onNext }}
actions={<Feedback onSubmit={sendFeedback} />}
>
<StreamingText text={answer} streaming={status === 'streaming'} />
</Message>

Full types and defaults are in React API at the end of the page.

  • role — user · assistant · system · tool; name is always announced (Primer: speaker clarity).
  • status — streaming hides the actions and sets aria-busy; error shows the message with Retry (onRegenerate); stopped notes that the person stopped it.
  • Actions: copyText (Copy), onRegenerate, onEdit, branch, and the actions slot. actionsVisibility="hover" for dense threads.
  • avatar, showName, aiLabel, time and dateTime for the header.

From the Figma guidelines.

Do

  • Name every speaker; use the product’s assistant name rather than “AI”.
  • Keep the order of what happened: reasoning, then tools, then approvals, then the answer.
  • Show actions on hover only in dense threads; they stay visible on touch screens and on focus.
  • Keep the latest assistant message’s actions visible.

Forbidden

  • Never style assistant text as a bubble that looks like a person’s message.
  • Never remove the speaker name from the accessible name.
  • Never show Regenerate on a user message or Edit on an assistant message.
  • Never hide an error behind a toast — keep it in the message with a Retry.

Generated from react/src/components by scripts/gen-react-api.mjs — the same tables agents read in guidelines/components/ai-message.md.

Use only these props; anything else is not part of the API.

Figma: Message — one turn in a conversation. Every message is an <article> named by its speaker, so screen-reader users always know who said what (Primer: speaker clarity).

import { Message } from '@stanvision/atomus-react'; — source: react/src/components/ai/Message.tsx

Prop Type Default Description
role 'user' | 'assistant' | 'system' | 'tool' 'assistant' Figma: Role — who is speaking. Sets layout, label and default name.
status 'streaming' | 'done' | 'error' | 'stopped' 'done' Figma: Status — streaming keeps the message busy; error and stopped show an inline notice.
name string — Figma: Name — the speaker (“You”, “Atomus AI”, “Research agent”). Always announced to screen readers.
avatar ReactNode — Figma: Avatar — an Avatar or logo; assistants default to the AI mark.
showName boolean — Figma: Show name — show the speaker name visually (screen readers always get it). Defaults to true except for user messages.
aiLabel boolean true Figma: AI label — shows the AI label next to an assistant’s name.
time string — Figma: Timestamp — display text (“2:41 PM”)
dateTime string — Machine-readable time (ISO 8601) for the <time> element
children ReactNode — Figma: Content
copyText string — Plain text of the message for the Copy action; Copy is hidden without it.
onRegenerate () => void — Figma: Regenerate — assistant messages; also the retry action for status="error".
onEdit () => void — Figma: Edit — user messages
branch MessageBranch — Figma: Branch — ‹ 1/3 › switcher between regenerated or edited versions
actions ReactNode — Extra actions after the built-in ones (e.g. Feedback)
actionsVisibility 'always' | 'hover' 'always' Figma: Actions visibility — always, or on hover and keyboard focus (always shown on touch screens)
errorMessage ReactNode 'Something went wrong while generating this response.' Error text for status="error"

Also accepts every native HTML attribute (id, role …), except role, which is replaced above.

MessageBranch:

Field Type Description
index number 1-based number of the version shown
count number How many versions exist
onPrevious? () => void Shows the previous version
onNext? () => void Shows the next version