Message Bubble
Holds one chat message in a speech bubble.
Here’s the summary of the vendor thread: the renewal quote went up 12% because of the new seat tier, procurement wants a 2-year term to hold the price, and legal flagged the auto-renew clause in section 4.2. Finance can approve up to $18k without a committee review, so the 2-year option would need sign-off. I’d suggest replying to ask for the 1-year price with a cap on next year’s increase.
Dana joined the conversation
Couldn’t send. Tap to retry.
Draft saved
Installation
pnpm dlx shadcn@latest add @paneui/message-bubbleUsage
Composition
Examples
Motion
The collapsible's height transition is removed under reduced motion; interactive bubbles press to scale-98.
Accessibility
The Show more toggle is a real <button> with aria-expanded and aria-controls pointing at the clipped region. It only appears when the content overflows.
MessageBubble
A single conversational surface. Also accepts every prop of div (useRender).
- tone= "default"
- "default" | "primary" | "muted" | "outline" | "destructive" | "ghost"
primaryfor the sender,defaultfor replies,mutedfor system,outlinefor quiet,destructivefor errors andghostfor unframed messages.- size= "default"
- "default" | "sm"
- Padding, radius and text size.
- align
- "start" | "end"
- Side the bubble hugs. Inherited from
Message/MessageBubbleGroupwhen omitted, elsestart. - tail= true
- boolean
- Tighten the bottom corner toward the sender. Ignored for
ghost. - render
- ReactElement | (props, state) => ReactElement
- Render as another element, e.g.
<a />or<button />; the bubble becomes pressable.
| Prop | Type | Default | Description |
|---|---|---|---|
| tone | "default" | "primary" | "muted" | "outline" | "destructive" | "ghost" | "default" | primary for the sender, default for replies, muted for system, outline for quiet, destructive for errors and ghost for unframed messages. |
| size | "default" | "sm" | "default" | Padding, radius and text size. |
| align | "start" | "end" | — | Side the bubble hugs. Inherited from Message / MessageBubbleGroup when omitted, else start. |
| tail | boolean | true | Tighten the bottom corner toward the sender. Ignored for ghost. |
| render | ReactElement | (props, state) => ReactElement | — | Render as another element, e.g. <a /> or <button />; the bubble becomes pressable. |
MessageBubbleGroup
Stacks consecutive bubbles from one sender with joined corners. Also accepts every prop of div.
- align
- "start" | "end"
- Side for the whole group. Inherited from
Messagewhen omitted, elsestart.
| Prop | Type | Default | Description |
|---|---|---|---|
| align | "start" | "end" | — | Side for the whole group. Inherited from Message when omitted, else start. |
- data-align
startorend.
| Data attribute | Description |
|---|---|
| data-align | start or end. |
MessageBubbleCollapsible
Clips long content with a fade and a Show more toggle. Also accepts every prop of div.
- collapsedHeight= 120
- number
- Height in px while collapsed.
- defaultExpanded= false
- boolean
- Start expanded.
- moreLabel= "Show more"
- string
- Toggle label while collapsed.
- lessLabel= "Show less"
- string
- Toggle label while expanded.
| Prop | Type | Default | Description |
|---|---|---|---|
| collapsedHeight | number | 120 | Height in px while collapsed. |
| defaultExpanded | boolean | false | Start expanded. |
| moreLabel | string | "Show more" | Toggle label while collapsed. |
| lessLabel | string | "Show less" | Toggle label while expanded. |