Bubble
Conversational content in a message bubble, with variants, alignment, grouping, and reactions.
The Bubble component displays framed conversational content. Use it for chat
text, short structured output, quoted replies, and reactions. For full chat
rows (avatars, names, timestamps, and actions) use
Message; Bubble is intentionally scoped to the
bubble surface.
Usage
import { Bubble, BubbleContent, BubbleReactions } from '@epilot/spark-ui/bubble'<Bubble>
<BubbleContent>
I checked the meter reading and updated your tariff.
</BubbleContent>
<BubbleReactions role="img" aria-label="Reactions: thumbs up">
<span>👍</span>
</BubbleReactions>
</Bubble>Composition
Bubble
├── BubbleContent
└── BubbleReactionsUse BubbleGroup to group consecutive bubbles from the same sender:
BubbleGroup
├── Bubble
│ └── BubbleContent
└── Bubble
└── BubbleContentExamples
Variants
Use variant to change the visual treatment of the bubble.
| Variant | Description |
|---|---|
default | A strong accent bubble, usually for the current user. |
secondary | The standard neutral bubble for conversation content. |
muted | A lower-emphasis bubble for quiet supporting content. |
tinted | A subtle accent-tinted bubble. |
outline | A bordered bubble for secondary or rich content. |
ghost | Unframed content for assistant text or rich content. |
destructive | A destructive bubble for error or failed actions. |
A bubble sizes to its content, up to 80% of the container width. The ghost
variant removes the max-width so assistant text and rich content can span the
full row.
Alignment
Use align on Bubble to align it to the start or end of the conversation.
Note: When building chat interfaces, you usually want alignment on the
Message component itself rather than on Bubble.
Bubble group
Use BubbleGroup to group consecutive bubbles from the same sender. Set align
on each Bubble, not on the group.
Reactions
Use BubbleReactions for reactions or quick actions. Use side and align to
position the row. Reactions overlap the bubble edge, so leave vertical space
between rows.
Links and buttons
Turn a bubble into a link or button with the render prop on BubbleContent.
BubbleContent ships a visible focus ring for interactive elements.
<Bubble variant="muted" align="end">
<BubbleContent render={<button type="button" onClick={onReply} />}>
I forgot my password
</BubbleContent>
</Bubble>Accessibility
- Label reactions. A screen reader reads each emoji with no context, and
counters like
+8are announced as "plus eight". Group the row as a single image with a descriptivearia-label(role="img"also hides the individual emoji). When reactions are interactive, render buttons and give icon-only ones anaria-label. - Interactive bubbles. Render clickable bubbles as a real
<button>or<a>viarenderso they are focusable and expose the right role; the accessible name comes from the bubble text. - Meaning beyond color. Variants signal role and tone with color; keep the
meaning (e.g. an error reason for
destructive) in the text too.
API Reference
Bubble
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'default' | 'secondary' | 'muted' | 'tinted' | 'outline' | 'ghost' | 'destructive' | 'default' | The bubble visual treatment. |
align | 'start' | 'end' | 'start' | The inline alignment of the bubble. |
className | string | — | Additional classes. |
BubbleContent
| Prop | Type | Default | Description |
|---|---|---|---|
render | ReactElement | function | — | Render the content as a different element such as a link. |
className | string | — | Additional classes. |
BubbleReactions
| Prop | Type | Default | Description |
|---|---|---|---|
side | 'top' | 'bottom' | 'bottom' | The side of the bubble to anchor the reactions. |
align | 'start' | 'end' | 'end' | The inline alignment of the reactions. |
className | string | — | Additional classes. |
BubbleGroup
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional classes to apply to the group root. |