Bubble
Chat bubble surface with default, muted, accent and glass variants, optional tail and grouped spacing.
pnpm dlx @glinui/cli@latest add bubbleInstallation
pnpm dlx @glinui/cli@latest add bubblePrefer the package?
Usage
Inside a chat screen
Message wraps Bubble; this is the full screen.
Q3 revenue review
Glin assistant, 3 sources
import { ArrowsClockwise, Paperclip, ThumbsDown, ThumbsUp } from "@phosphor-icons/react"import { Attachment, Badge, Heading, Message, MessageAction, MessageActions, MessageAvatar, MessageContent, MessageCopyAction, MessageScroller, PromptInput, StreamingText, Text, Thinking} from "@glinui/ui"
const reply = "Revenue grew 12% quarter over quarter, driven mostly by the Pro plan. Churn stayed flat at 1.8%, so the gain came from expansion rather than new logos."
export function ChatScreen() { return ( <div className="flex h-[34rem] w-full max-w-2xl flex-col overflow-hidden rounded-2xl border border-[var(--line-soft)] bg-[var(--surface-1)] text-left"> <header className="flex items-center justify-between gap-3 border-b border-[var(--line-soft)] px-4 py-3"> <div className="flex flex-col"> <Heading level={2} size="sm">Q3 revenue review</Heading> <Text size="sm" variant="muted">Glin assistant, 3 sources</Text> </div> <Badge tone="success" variant="soft">Online</Badge> </header> <MessageScroller label="Conversation" className="min-h-0 flex-1"> <Message role="user"> <MessageAvatar fallback="MK" alt="" /> <MessageContent> <div className="flex flex-col gap-2"> <span>Summarize how Q3 went compared with Q2.</span> <div className="flex flex-wrap gap-2"> <Attachment name="q3-revenue.csv" size={48210} /> <Attachment name="board-notes.pdf" size={1203400} /> </div> </div> </MessageContent> </Message> <Message role="assistant"> <MessageAvatar fallback="G" alt="" /> <MessageContent actions={ <MessageActions> <MessageCopyAction value={reply} /> <MessageAction label="Regenerate"><ArrowsClockwise /></MessageAction> <MessageAction label="Good response" pressed><ThumbsUp /></MessageAction> <MessageAction label="Bad response"><ThumbsDown /></MessageAction> </MessageActions> } > <div className="flex flex-col gap-2"> <Thinking active={false} doneLabel="Thought for 4 seconds">Compared monthly totals, then split growth into new and expansion revenue.</Thinking> <span>{reply}</span> </div> </MessageContent> </Message> <Message role="user"> <MessageAvatar fallback="MK" alt="" /> <MessageContent>Which regions grew fastest?</MessageContent> </Message> <Message role="assistant"> <MessageAvatar fallback="G" alt="" /> <MessageContent> <StreamingText text="Europe led with 19% growth, followed by North America at 11%. APAC was flat after the pricing change in August." speed={30} /> </MessageContent> </Message> <Message role="assistant"> <MessageAvatar fallback="G" alt="" /> <MessageContent><Thinking /></MessageContent> </Message> </MessageScroller> <div className="border-t border-[var(--line-soft)] p-3"> <PromptInput placeholder="Ask a follow up" maxLength={500} onSubmit={(value) => console.log(value)} actions={<MessageAction label="Attach file"><Paperclip /></MessageAction>} /> </div> </div> )}Variants
import { Bubble } from "@glinui/ui"
export function Demo() { return ( <div className="flex flex-col items-start gap-2"> <Bubble>Default surface</Bubble> <Bubble variant="muted">Muted</Bubble> <Bubble variant="accent">Accent</Bubble> <Bubble variant="soft">Glass</Bubble> </div> )}Variants
Every vocabulary variant on the default tone. Omit variant to follow the ambient design style.
import { Bubble } from "@glinui/ui"
export function BubbleVariantsDemo() { return ( <div className="flex flex-wrap items-start gap-3"> <Bubble variant="glinr">glinr</Bubble> <Bubble variant="solid">solid</Bubble> <Bubble variant="plain">plain</Bubble> <Bubble variant="soft">soft</Bubble> <Bubble variant="outline">outline</Bubble> <Bubble variant="ghost">ghost</Bubble> <Bubble variant="gradient">gradient</Bubble> </div> )}Glass (opt-in)
Glass is opt-in and needs a backdrop behind it. Switch the preview stage to Vivid or Photo to see the frosted surface.
import { Bubble } from "@glinui/ui"
export function BubbleGlassDemo() { return ( <Bubble variant="glass">glass</Bubble> )}Accessibility
- Renders a plain div with no implicit role, so content stays readable inside a log region.
- Accent text uses the accent-foreground token for AA contrast in light and dark.
- Long words wrap instead of overflowing.
Reduced Motion
Bubble has no motion of its own.
API Reference
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
variant | BubbleVariant | No | ambient (glinr) | Surface variant. Omit to follow the ambient design style (glinr by default, plain for minimal, glass for glass). |
tone | SurfaceTone | No | neutral | Colour tone for the vocabulary variants. |
align | "start" | "end" | No | start | Which side the bubble sits on. Controls tail and group corners. |
tail | boolean | No | false | Square the corner nearest the sender. |
grouped | boolean | No | false | Tighten the aligned edge for stacked bubbles. |
Source
Import directly from the package or browse the source on GitHub. Click any file to view it.
Import
import { Bubble } from "@glinui/ui"Source Files
Dependencies
@glinui/uiclass-variance-authorityGenerated API Snapshot
Beta
Generated API Snapshot
BetaAuto-extracted from TypeScript source in packages/ui/src/components/bubble.tsx. This section is in beta and may lag behind hand-curated docs. Regenerate with pnpm --filter @glinui/docs api:generate.
Generated: 2026-10-08T01:41:21.546Z · Full index: /docs/api-metadata
Primary Props Type
BubbleProps
BubbleProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
align | "start" | "end" | No | - | - |
grouped | boolean | No | false | Tightens the aligned edge so stacked bubbles read as one group. |
tail | boolean | No | false | Squares the corner nearest the avatar to point at the sender. |
tone | SurfaceTone | No | - | - |
variant | BubbleVariant | No | - | Visual variant. Omit for the ambient design style (glinr: raised ringed bubble; plain: flat bordered bubble). Vocabulary: glinr, solid, plain, soft, outline, ghost, gradient, glass. `accent` is solid + accent tone, `muted` is soft. |