sdxc

Type to search, or start from one of these:

Message

A single conversational turn in a message log.

AR
Ana Ruiz
The deploy finished but the worker is still serving the old bundle. Is there a cache I should be busting?
SX
Sergio
The bundle is fingerprinted, so that is the CDN holding a stale index.
Ana Ruiz
Purging it now.
AR
That did it — thank you.
View code
<div mix={[vstack({ gap: 6, align: "stretch" })]}>
	<Message>
		<Message.Avatar>
			<Avatar>
				<Avatar.Fallback>AR</Avatar.Fallback>
			</Avatar>
		</Message.Avatar>
		<Message.Header>
			<strong>Ana Ruiz</strong>
			<time dateTime="2026-09-21T14:02">14:02</time>
		</Message.Header>
		<Message.Content>
						<Bubble variant="muted">
				<Bubble.Content id="turn-1-text">
					The deploy finished but the worker is still serving the old bundle. Is there a cache
					I should be busting?
				</Bubble.Content>
			</Bubble>
		</Message.Content>
		<Message.Footer>
			<Button
				type="button"
				variant="ghost"
				size="sm"
				aria-label="Copy message"
				commandfor="turn-1-text"
				command={COPY_COMMAND}
				mix={[copyToClipboard()]}
			>
				<CopyIcon />
			</Button>
			<Button type="button" variant="ghost" size="sm" aria-label="Reply to Ana Ruiz">
				<ReplyIcon />
			</Button>
		</Message.Footer>
	</Message>

	<Message>
		<Message.Avatar>
			<Avatar>
				<Avatar.Fallback>SX</Avatar.Fallback>
			</Avatar>
		</Message.Avatar>
		<Message.Header>
			<strong>Sergio</strong>
			<time dateTime="2026-09-21T14:05">14:05</time>
		</Message.Header>
		<Message.Content>
			<Bubble align="end">
				<Bubble.Content>
					The bundle is fingerprinted, so that is the CDN holding a stale index.
				</Bubble.Content>
			</Bubble>
		</Message.Content>
	</Message>

	<Message.Group>
		<Message>
			{/* A run's later turns carry the avatar, so the turns above it reserve its column. */}
			<Message.Avatar aria-hidden="true">
				<span mix={[is("2.5rem")]} />
			</Message.Avatar>
			<Message.Header>
				<strong>Ana Ruiz</strong>
				<time dateTime="2026-09-21T14:07">14:07</time>
			</Message.Header>
			<Message.Content>
				<Bubble variant="muted">
					<Bubble.Content>Purging it now.</Bubble.Content>
				</Bubble>
			</Message.Content>
		</Message>
		<Message>
			<Message.Avatar>
				<Avatar>
					<Avatar.Fallback>AR</Avatar.Fallback>
				</Avatar>
			</Message.Avatar>
			<Message.Content>
				<Bubble variant="muted">
					<Bubble.Content>That did it — thank you.</Bubble.Content>
				</Bubble>
			</Message.Content>
		</Message>
	</Message.Group>
</div>

Installation

An ordinary dependency: install it, import the theme once, and import the component where it is used.

npm add @sdxc/ui
import "@sdxc/ui/theme.css";

Usage

import { Message } from "@sdxc/ui";

Renders the message row as a two-column grid whose "avatar" area spans only the header and content rows, anchoring Message.Avatar to the bottom edge of Message.Content, regardless of whether Message.Footer renders.

Composition

The parts the component publishes, each a static property of the host.

  • Message
  • Message.AvatarRenders Message.AvatarProps.children as the row's avatar slot, aligned to the "avatar" area's block-end edge so it tracks the bottom edge of Message.Content.
  • Message.HeaderRenders Message.HeaderProps.children as the row's identity line, wrapping until the ui-message container passes 26rem, then settling onto one row with the sender's name first and later children as secondary metadata.
  • Message.ContentRenders Message.ContentProps.children as the row's content slot, capped to a comfortable reading measure and never narrower than its grid area.
  • Message.FooterRenders Message.FooterProps.children as the row's action slot, occupying the grid's "footer" area beneath Message.Content and never reached by Message.Avatar's bottom anchor.
  • Message.GroupRenders Message.GroupProps.children as a run of consecutive Message rows sharing the same sender, stacked with a hairline gap that reads as one continuous turn.

Props

Read from the component's own types, so every prop, every default and every allowed value is listed.

PropTypeDescription
childrenRemixNodeThe row's compound parts: Message.Avatar, Message.Header, Message.Content, and an optional Message.Footer.

Also accepts everything in TagProps<"article">.

Message.Avatar

PropTypeDescription
childrenRemixNodeAn Avatar instance identifying the message's sender.

Also accepts everything in TagProps<"div">.

Message.Header

PropTypeDescription
childrenRemixNodeThe sender's name, typically followed by a timestamp.

Also accepts everything in TagProps<"header">.

Message.Content

PropTypeDescription
childrenRemixNodeThe message's own surface — a Bubble, an attachment card, or any other rendered turn content.

Also accepts everything in TagProps<"div">.

PropTypeDescription
childrenRemixNodeThe row's actions, typically a copy Button and a like Button.

Also accepts everything in TagProps<"footer">.

Message.Group

PropTypeDescription
childrenRemixNodeA run of consecutive Message rows sharing the same sender.

Also accepts everything in TagProps<"div">.