Bubble
Chat bubble atom: an inner-shadowed message surface with sender, recipient and ai variants, an author header (avatar, name, time, role badge), a glass reaction pill hanging off the corner and hover-revealed message actions.
Usage
import { Bubble, User } from "@exegia/corpora-ui"
;<User.Message
variant="info"
user={{
firstName: "Jenny",
lastName: "Hamilton",
role: "Editor",
direction: "sender",
description: "10 min ago",
}}
reactions={{
reactions: [
{ id: "heart", emoji: "❤️", count: 4, reacted: true, label: "heart" },
],
onToggle: toggleReaction,
}}
actions={
<Bubble.Actions>
<Button aria-label="Copy" size="icon-xs" variant="ghost">
<CopyIcon />
</Button>
</Bubble.Actions>
}
>
Can you check whether ¶12 keeps the boundary?
</User.Message>User.Message composes the identity header and bubble surface. Set user.direction to sender or recipient; it controls both the identity order and message alignment. Headers reach the thread edge while messages retain their inset. continued hides the repeated header. Reactions and actions remain outside the message surface. Use the underlying Bubble slots for custom layouts or AI content.
API reference
Attachment-only children automatically render without bubble padding, background, bezel, or tail, including attachments inside fragments. Use <Bubble.Message unstyled> explicitly for custom attachment wrappers. For a message with both text and attachments, put the text in a normal Bubble.Message and the attachments in a separate unstyled one.
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "ai" | "sender" | "recipient" | "recipient" | Who the bubble belongs to. sender is right-aligned on a lit inverted surface with the bottom-right tail pinched, recipient is its dim mirror, ai renders chrome-less prose so generated output never masquerades as a person's message. Sub-components inherit the variant from context. |
| continued | boolean | false | A follow-up in a run from the same author: tucks under the previous bubble. Render Bubble.Header on the first of the run only. |
| Bubble.Header | children / HTML div props | — | Author row composed through children: name, avatar, time, and role badge. Use User.Info as a child for a full identity row. The sender variant mirrors the row. |
| Bubble.Message | children | — | The message surface, styled by the inherited variant. |
| Bubble.Reactions | reactions / onToggle / onEmojiSelect | — | Frosted reaction pill overlapping the bubble's bottom corner. Each chip carries aria-pressed, springs its emoji on toggle and rolls its count; onToggle(reaction, index) fires on click. The trailing add-reaction button opens a frimousse emoji picker in a frosted-glass popover — onEmojiSelect({ emoji, label }) fires on pick. Accepts children for custom chips. |
| Bubble.Actions | children | — | role=toolbar row for per-message actions (copy, retry, …), hidden until the bubble is hovered or an action has focus. Compose with Button size=icon-xs. |
Last updated on