Marble UI
← Components

Chat Message

Preview: Bubble

One chat turn: avatar, name, time, message body and actions, for user and assistant roles.

Import

import { ChatMessage } from '@marbleui/ui'

Props

<ChatMessage>

PropTypeDefaultDescription
children *requiredReactNode—
role *required'user' | 'assistant' | 'system'—
actionsReactNode—Toolbar under assistant messages (MessageActions).
avatarReactNode—
classNamestring—
namestring—
timestring—
variant'flat' | 'bubble''bubble'"bubble": user on the right in a bubble. "flat": document style, everyone left-aligned.

Usage notes

One turn in a chat transcript: avatar, name, time, body and an actions row. Place turns inside ChatConversation. An assistant turn usually holds Reasoning, ToolCalls, a MarkdownResponse and Sources, in that order, with MessageActions in actions.

<ChatMessage role="user">Which accounts are at risk of churning?</ChatMessage>
<ChatMessage role="assistant" name="Acme AI" time="2:14 PM" actions={<MessageActions text={reply} onRegenerate={retry} />}>
  <MarkdownResponse>{reply}</MarkdownResponse>
</ChatMessage>
  • variant="bubble" (default) puts user text in a right-aligned bubble without avatar, name or time. variant="flat" left-aligns everyone and shows all three for both roles, which suits threads with several people.
  • Each turn is an article named from name and time (falling back to “You” or “Assistant”). role="system" renders a small centered note and ignores name, avatar, time and actions.
  • actions stay hidden until the turn is hovered or focused, or a feedback thumb is selected. Touch screens have no hover, so there they only show on focus.
Example source · show
import { MarkdownResponse } from '../markdown-response'
import { MessageActions } from '../message-actions'
import { ChatMessage } from './chat-message'

const reply = 'Your top churn risks are **Northwind** (−42% usage) and **Initech** (−35%). Both renew within 30 days.'

export const styles = {
  Bubble: () => (
    <div className="flex w-[32rem] flex-col gap-5">
      <ChatMessage role="user">Which accounts are at risk of churning?</ChatMessage>
      <ChatMessage role="assistant" name="Acme AI" time="2:14 PM" actions={<MessageActions text={reply} onRegenerate={() => {}} />}>
        <MarkdownResponse>{reply}</MarkdownResponse>
      </ChatMessage>
    </div>
  ),
  Flat: () => (
    <div className="flex w-[32rem] flex-col gap-5">
      <ChatMessage variant="flat" role="user" name="Maya Chen" time="2:13 PM">Which accounts are at risk of churning?</ChatMessage>
      <ChatMessage variant="flat" role="assistant" name="Acme AI" time="2:14 PM"><MarkdownResponse>{reply}</MarkdownResponse></ChatMessage>
      <ChatMessage role="system">Maya shared this conversation with #success</ChatMessage>
    </div>
  ),
}

Source: packages/ui/src/chat-message/chat-message.tsx

Catalog

Category
ai-agents
Priority
Pro
Primitive
composed