Chat Bubble
Incoming/outgoing message bubbles with avatar, sender, timestamp, and delivery status. Group consecutive messages from the same sender to suppress repeated metadata, Messages/Slack-style.
Conversation
align='incoming' (default) renders on the left with a neutral surface; align='outgoing' renders on the right with the accent-filled surface. Each tail points toward its speaker, level with the avatar, and one drop shadow follows bubble and tail together, deepening under floating elevation.
Delivery status
status renders as an icon plus a text label next to the timestamp - never color alone.
Grouped runs
grouped suppresses the avatar/sender/timestamp/status and tightens spacing. Render the last bubble in a run with grouped={false} (the default) so metadata surfaces once per run.
- ChatBubble doesn't know about a list of messages - the consumer decides which consecutive bubbles to group
- Only the last bubble of a run carries the tail, so a run reads as one connected shape
- A grouped bubble hides its sender visually but still announces it to screen readers
With an attachment
ChatBubble.Attachment is a small file/media chip for use inside children - pass onClick to make it a real, keyboard-accessible button.
API reference
Which side the message renders on: "incoming" (left, neutral surface) or "outgoing" (right, the accent-filled surface). Default "incoming".
Avatar slot - typically an `<Avatar />`. Hidden (but its footprint reserved, so bubbles stay aligned) when `grouped`.
Per-slot class overrides, for styling one part without wrapping the whole bubble.
Marks a bubble inside a same-sender run: hides avatar/sender/timestamp/status and tightens the gap. Leave the run's last message ungrouped (the default); the consumer decides what groups.
Sender name, shown above the bubble. Hidden when `grouped`.
Delivery/read status, shown next to the timestamp as an icon + text label. Hidden when `grouped`.
Timestamp string/node, shown below the bubble in a de-emphasized style so it never reads as the primary content. Hidden when `grouped`.
Also accepts everything from React.HTMLAttributes<HTMLDivElement>.
ChatBubble.Attachment props
File/attachment name.
Per-slot class overrides. `preview` is the artwork box.
Icon shown before the name - defaults to a generic paperclip. Ignored when `preview` is given.
Secondary detail, e.g. a file size or an audio duration ("2.4 MB", "0:42").
Renders a keyboard-accessible `<button type="button">` (e.g. open/download). Without it the chip is a static `<div>`, so it can sit inside a consumer's own `<a>` without nesting.
Artwork in place of the icon (thumbnail, poster), cropped to a 40px square (`classNames.preview` resizes it). Give it an empty `alt` when `name` already describes the file.
Also accepts everything from Omit<React.HTMLAttributes<HTMLDivElement>, "onClick">.
ChatBubble.Typing props
Text announced in place of the hidden animated dots. Default "Typing". Pass a name for group threads ("Priya is typing") or a translated string.
Also accepts everything from React.HTMLAttributes<HTMLSpanElement>.
Coding agents read this reference, with its examples, from the version your project has installed, through the Fuji UI MCP server. Set up your agent
