Skip to content
ConversationMessageMenu

Message

One turn in the thread. Users get a subtle bubble, the assistant writes like a document, and every lifecycle state has a designed look.

User bubble, flat assistant prose and a system line.

Installation

$ pnpm dlx shadcn@latest add https://chatcn.dev/r/message.json

Usage

tsx
import {
  Message,
  MessageAvatar,
  MessageContent,
  MessageMeta,
  MessageStatus,
} from "@/components/ui/chatcn/message"

<Message from="assistant" state="done" latest>
  <MessageAvatar />
  <MessageContent>{text}</MessageContent>
  <MessageMeta time={createdAt} durationMs={3400} tokens={412} />
</Message>

The role prop is from, so the ARIA role attribute stays free. Prose is 15/24 and capped at a 68ch measure; plain strings keep their line breaks, and markdown renderers drop in as children.

Examples

Every state

Streaming, done, edited, error, stopped and queued. MessageStatus renders the line for the states that need one; failed replies use MessageError.

Streaming, done, edited, error, stopped and queued.

Avatars and grouping

Assistants default to the kit's square mark, people to initials. grouped tightens the gap to 8 px and hides the repeated avatar while keeping its space.

The square mark, initials and grouped turns.

Compact

The dense log layout with grouped repeats.

Props

PropTypeNotes
from"user" | "assistant" | "system"Who wrote it
layout"auto" | "bubble" | "flat" | "compact"auto gives users a bubble and everyone else a flat block
state"streaming" | "done" | "edited" | "error" | "stopped" | "queued"Defaults to done
groupedbooleanFollows a message from the same author
latestbooleanKeeps its actions visible
animatebooleanDefaults to animating only messages added after mount
announcebooleanRead the text once when streaming finishes. Defaults to true
MessageAvatarsrc, name, variantImage, initials or the square mark. Children for a provider mark
MessageMetatime, model, tokens, durationMs, costRelative time, absolute on hover
MessageStatusonRetry, onContinueQueued, not sent, stopped

Accessibility

  • A streaming message is aria-busy. Inside a Conversation, the finished text is announced once.
  • Failure is never color alone: Not sent pairs the red icon with words and a Retry button.
  • Layout uses logical properties, so bubbles and gutters mirror in right-to-left languages.

Motion

  • New user turns rise 8 px and fade in over 200 ms with ease-chatcn-out-soft. Assistant turns only fade, over 150 ms. Text streams in with no per-word effect.
  • Under reduced motion only the fade remains.