Message
A composition-based chat message family for AI and messaging interfaces. A Message row with align-aware layout and semantic sender roles, plus Avatar, Header, Content, and Footer slots around a MessageBubble surface with four variants, grouping, and a reactions slot.
Pro Features
Unlock advanced capabilities with the Pro version
Chat-Ready Composition
A Message row with Avatar, Header, Content, and Footer slots around the MessageBubble surface — compose exactly the message anatomy your UI needs
Align-Aware Layout
Set align once on Message and it flows to content and bubble corners via context — start for received, end for sent messages
Four Bubble Variants
Default, muted, primary, and outline surfaces built on design tokens, so dark mode works automatically
Message Grouping
The grouped prop flattens corners on the aligned side so consecutive messages from one sender read as a single block
Reactions Slot
An absolutely positioned bottom-right slot on the bubble for emoji reaction chips or any custom ReactNode
Semantic and Accessible
role=article by default with an htmlRole escape hatch for list semantics, plus data-role and data-align hooks for styling and analytics
Installation
Install via CLI
npx @moontra/moonui-cli add messageUsage
Examples
Basic Conversation
A short exchange between an assistant and the current user. Received messages use align start with the muted bubble, sent messages use align end with the primary bubble; each message composes Avatar, Header, Content, and Footer slots.
Grouped Messages
Mark follow-up messages from the same sender with the grouped prop: the corners on the aligned side flatten, so consecutive bubbles read as one visual block while the first message keeps its rounded tail.
Reactions and Variants
The reactions slot renders chips in an absolutely positioned area at the bottom-right edge of the bubble — give the bubble bottom margin (mb-3) so following content does not overlap. Below it, the four bubble variants side by side: default, muted, primary, and outline.
System Messages and List Semantics
role="system" marks informational rows — center them with justify-center and a pill-shaped outline bubble. When rendering a conversation inside a role="list" container, pass htmlRole="listitem" so each message becomes a valid list item instead of the default article.
Swipe to Reply
Message does not bake swiping in — it composes: wrap each Message in the SwipeActions component for WhatsApp-style chat interactions. Drag a message right to reply (a reply bar appears below the thread) or left to add a reaction chip; arrow keys trigger the same actions for keyboard users.