Message
StableOne turn in a conversation: a bubble for the person, open text across the full width for the assistant.
Also known as chat bubble, chat message, response, turn
Install with npm install @tattva/ui (setup), or copy the code from the kit in Downloads.
User and assistant
The team agreed to ship on Friday and review the open risks on Wednesday.
<div className="w-full max-w-xl space-y-6">
<Message role="user">Can you summarize the meeting?</Message>
<Message role="assistant">
<p>The team agreed to ship on Friday and review the open risks on Wednesday.</p>
</Message>
</div>The person's bubble never fills the whole width. The assistant has no bubble.
When to use it
One turn in a chat. The person's words sit in a bubble on the right; the assistant's reply is open text across the full width, so long answers and code have room.
Made of: Mark and name (optional, above) · Bubble or plain text · Blinking cursor · Bottom area
Use it for
- Each turn of a conversation, from the person or the assistant.
- A reply that is still being written: turn on streaming.
- A finished reply with actions, feedback or sources underneath.
Not for
- A whole conversation that should be read out as it grows: use MessageList.
- Notes from the app itself, such as limits or errors: use Callout.
- A refusal or a safety stop: use RefusalNotice.
Do and avoid
Do
- Keep the assistant's text out of a bubble so long text and code have room.
- Put actions and feedback at the bottom, and only after the reply ends.
- Wrap the messages in an area that announces new replies if your app should read them out.
- Show the AI mark once, on the first reply, or not at all. The thread already says who is speaking.
Avoid
- Do not put the assistant's text in a bubble. The layout needs it open.
- Do not put a mark beside every reply. It pushes the text in and fills the thread with repeated marks.
- Do not add a bottom area to a person's message. It is ignored.
- Remember to mark the reply as finished, or the blinking cursor stays.
On a phone
- The user bubble is at most 80% of the width, and the assistant text takes the full width.
- The assistant text can shrink to the width of the screen and wraps. Wide children such as tables or code must scroll inside themselves.
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "bubble" | "plain" | "bubble" | How the person's own turn looks. bubble is a right-aligned bubble. plain is left-aligned serif text with no box, like a line in a letter. It only changes user messages. |
| mark | "none" | "top" | "none" | Assistant only. none shows no mark: the reply uses the full width. top shows a small AI mark and the name above the reply. Use it once per thread, or on every reply when more than one assistant speaks. |
| name | string | "Assistant" | Assistant only. Shown with the mark, and read by screen readers before every reply. |
| showAvatar | boolean | none | Deprecated: use mark. true shows the mark above the reply. |
| rolerequired | "user" | "assistant" | none | Chooses the layout. User renders a bubble, assistant renders open text across the full width. |
| streaming | boolean | none | Assistant only. Shows a blinking caret, sets aria-busy and sets aria-live="off" on the text while tokens arrive. |
| completeLabel | string | "Response complete" | Assistant only. Announced once through a polite status region when streaming changes from true to false. |
| childrenrequired | ReactNode | none | Message content. |
| footer | ReactNode | none | Assistant only. Slot under the content for MessageActions, FeedbackBar or sources. |
| className | string | none | Extra classes on the outer wrapper. |
"Show code under the preview gives the code for the example on the stage."
In Figma
In Figma, one Message switches all of this from its properties panel, across 16 variants. Each property sets the React prop beside it, so design and code use the same names.
| Figma property | React | Values |
|---|---|---|
| Variant | variant | Bubble, Plain |
| Role | role | User, Assistant |
| Mark | mark | None, Top |
| Streaming | streaming | On or off |
| Text | children | Any text |
Tokens
Change one of these and every part that uses it follows.
--surface-sunken--fg--fg-muted--lime--on-lime--radius-card
Built in
- Screen readers stay quiet while words arrive, then say "Response complete" once.
- The blinking cursor is hidden from screen readers.
- Screen readers hear the name ("Assistant" by default) before every reply, whether or not the mark shows.
- The rise-in motion stops when people turn off motion in their system settings.
What you need to do
- Set streaming to false when the reply ends. Until then the cursor keeps blinking and nothing is announced.
- Put conversations in MessageList, so screen readers hear new replies as they arrive.
- Give images and charts inside a reply their own text alternatives.
- When more than one assistant or agent speaks, give each its name and set mark to top, so people can see who said what.
Built toward WCAG 2.2 AA and checked automatically; no independent audit yet. Read the accessibility guide