tsimport {XDSChatMessage} from '@xds/core/Chat'
| Guidance | Practices |
|---|---|
| Do | Compose messages using MessageList > Message > Bubble for consistent sender-aware styling and density. |
| Do | Set the density prop to control spacing globally — compact for sidebars, balanced for most views, spacious for long-form reading. Individual messages can override. |
| Do | Use the group prop on bubbles (first, middle, last) when a single sender sends multiple consecutive messages — it tightens corner radius to visually connect them. |
| Do | Use XDSChatSystemMessage with variant="divider" for date separators and default for inline status notices like joins, leaves, or topic changes. |
| Do | Put name on the first bubble and metadata on the last bubble in a message so they align with the bubble's inline padding. |
| Do | Provide an emptyState prop so new users see a clear prompt to start a conversation instead of a blank screen. |
| Do | Use the ghost bubble variant for AI-style responses that show rich content like code blocks or markdown without a visible boundary. |
| Don't | Don't use XDSChatSystemMessage for sender content — it has no avatar, alignment, or bubble. Use XDSChatMessage with a sender role instead. |
| Don't | Don't put long or multi-line content in a system message — keep it to a single short sentence. If you need more, use a bubble or a card. |
| Don't | Don't nest XDSChatMessage inside another XDSChatMessage — each message is a standalone article element with its own sender context. |
| Don't | Don't apply a fixed height directly on the message list — wrap it in a sized container and let the list fill with flex: 1. |
| Don't | Don't mix filled and ghost bubble variants within the same sender's messages — pick one style per side and use it consistently. |
| Don't | Don't place metadata or names on both the bubble and the message wrapper — pick one based on whether the content has a bubble boundary. |
tsx'use client';import {XDSChatMessageList,XDSChatMessage,XDSChatMessageBubble,XDSChatMessageMetadata,} from '@xds/core/Chat';import {XDSAvatar} from '@xds/core/Avatar';import {XDSTimestamp} from '@xds/core/Timestamp';import {XDSText} from '@xds/core/Text';import {XDSStack} from '@xds/core/Layout';export default function ChatMessageAvatarName() {return (<XDSStack direction="vertical" gap={4}><XDSText type="supporting" color="secondary">Avatar and name on the bubble</XDSText><XDSChatMessageList><XDSChatMessagesender="assistant"avatar={<XDSAvatar name="Agent" size="small" />}><XDSChatMessageBubblename={<XDSText type="supporting" weight="semibold" color="secondary">Agent</XDSText>}metadata={<XDSChatMessageMetadatatimestamp={<XDSTimestamp value="2026-04-28T10:15:00" format="time" />}/>}>I reviewed the pull request. The changes look solid — clean code andgood test coverage.</XDSChatMessageBubble></XDSChatMessage><XDSChatMessage sender="user"><XDSChatMessageBubblemetadata={<XDSChatMessageMetadatatimestamp={<XDSTimestamp value="2026-04-28T10:16:00" format="time" />}status="read"/>}>Thanks! Merging it now.</XDSChatMessageBubble></XDSChatMessage><XDSChatMessagesender="assistant"avatar={<XDSAvatar name="Agent" size="small" />}><XDSChatMessageBubblename={<XDSText type="supporting" weight="semibold" color="secondary">Agent</XDSText>}metadata={<XDSChatMessageMetadatatimestamp={<XDSTimestamp value="2026-04-28T10:17:00" format="time" />}/>}>I can run the deployment pipeline once it lands. Just let me know.</XDSChatMessageBubble></XDSChatMessage></XDSChatMessageList></XDSStack>);}
tsx'use client';import {XDSChatMessageList,XDSChatMessage,XDSChatMessageBubble,XDSChatMessageMetadata,} from '@xds/core/Chat';import {XDSTimestamp} from '@xds/core/Timestamp';import {XDSText} from '@xds/core/Text';import {XDSStack} from '@xds/core/Layout';export default function ChatMessageGhost() {return (<XDSStack direction="vertical" gap={4}><XDSText type="supporting" color="secondary">Ghost bubbles — no visible boundary</XDSText><XDSChatMessageList><XDSChatMessage sender="assistant"><XDSChatMessageBubblevariant="ghost"metadata={<XDSChatMessageMetadatatimestamp={<XDSTimestamp value="2026-04-28T09:45:00" format="time" />}footer={<XDSText type="supporting" color="secondary">Claude Opus 4.6</XDSText>}/>}>Here is an analysis of your production metrics from last week.Traffic peaked at 12,400 requests per second on Wednesday, with ap99 latency of 45ms. Error rate stayed below 0.1% across allendpoints.</XDSChatMessageBubble></XDSChatMessage><XDSChatMessage sender="user"><XDSChatMessageBubble>That looks great. Can you compare it to the week before?</XDSChatMessageBubble></XDSChatMessage><XDSChatMessage sender="assistant"><XDSChatMessageBubblevariant="ghost"metadata={<XDSChatMessageMetadatatimestamp={<XDSTimestamp value="2026-04-28T09:46:00" format="time" />}footer={<XDSText type="supporting" color="secondary">Claude Opus 4.6</XDSText>}/>}>Compared to the previous week, traffic is up 8% and latency improvedby 3ms. The deployment on Tuesday seems to have helped.</XDSChatMessageBubble></XDSChatMessage></XDSChatMessageList></XDSStack>);}
tsx'use client';import {XDSChatMessageList,XDSChatMessage,XDSChatMessageBubble,XDSChatMessageMetadata,} from '@xds/core/Chat';import {XDSAvatar} from '@xds/core/Avatar';import {XDSTimestamp} from '@xds/core/Timestamp';import {XDSText} from '@xds/core/Text';import {XDSStack} from '@xds/core/Layout';export default function ChatMessageMultiBubble() {return (<XDSStack direction="vertical" gap={4}><XDSText type="supporting" color="secondary">Grouped bubbles with corner radius reduction</XDSText><XDSChatMessageList><XDSChatMessage sender="user"><XDSChatMessageBubble group="first">I have a couple of questions about the new API.</XDSChatMessageBubble><XDSChatMessageBubble group="middle">First, how should we handle pagination?</XDSChatMessageBubble><XDSChatMessageBubblegroup="last"metadata={<XDSChatMessageMetadatatimestamp={<XDSTimestamp value="2026-04-28T11:00:00" format="time" />}status="delivered"/>}>And second, what's the rate limit?</XDSChatMessageBubble></XDSChatMessage><XDSChatMessagesender="assistant"avatar={<XDSAvatar name="Agent" size="small" />}><XDSChatMessageBubblegroup="first"name={<XDSText type="supporting" weight="semibold" color="secondary">Agent</XDSText>}>Great questions! For pagination, use cursor-based with a limitparameter. The response includes a nextCursor field.</XDSChatMessageBubble><XDSChatMessageBubblegroup="last"metadata={<XDSChatMessageMetadatatimestamp={<XDSTimestamp value="2026-04-28T11:01:00" format="time" />}/>}>Rate limit is 100 requests per minute per API key. You'll get a 429response with a Retry-After header if you exceed it.</XDSChatMessageBubble></XDSChatMessage></XDSChatMessageList></XDSStack>);}
tsx'use client';import {XDSChatMessageList,XDSChatMessage,XDSChatMessageBubble,XDSChatMessageMetadata,} from '@xds/core/Chat';import {XDSAvatar} from '@xds/core/Avatar';import {XDSTimestamp} from '@xds/core/Timestamp';import {XDSText} from '@xds/core/Text';import {XDSStack} from '@xds/core/Layout';import * as stylex from '@stylexjs/stylex';const styles = stylex.create({root: {maxWidth: 600,},});export default function ChatMessageShowcase() {return (<XDSStack direction="vertical" gap={4} xstyle={styles.root}><XDSChatMessageList><XDSChatMessage sender="user"><XDSChatMessageBubble group="first">I just pushed the refactored auth module.</XDSChatMessageBubble><XDSChatMessageBubblegroup="last"metadata={<XDSChatMessageMetadatatimestamp={<XDSTimestamp value="2026-04-28T14:30:00" format="time" />}status="read"/>}>Can you review the token validation changes?</XDSChatMessageBubble></XDSChatMessage><XDSChatMessagesender="assistant"avatar={<XDSAvatar name="Agent" size="small" />}name={<XDSText type="supporting" weight="semibold" color="secondary">Agent</XDSText>}metadata={<XDSChatMessageMetadatatimestamp={<XDSTimestamp value="2026-04-28T14:31:00" format="time" />}footer={<XDSText type="supporting" color="secondary">Claude Opus 4.6</XDSText>}/>}><XDSChatMessageBubble variant="ghost">Looks good — the refresh token rotation is solid and the errorhandling covers all the edge cases. Ship it.</XDSChatMessageBubble></XDSChatMessage></XDSChatMessageList></XDSStack>);}