f-ui
Components

Bubble

Message surface with default, muted, and ghost variants for chat turns.

Plus Registry

This component ships from registry.plus.json, not the public registry.json. Set up @f-ui-plus on the Installation page, then install @f-ui-plus/bubble.

Tracks Shadcn

Layout primitives track shadcn ui/bubble. The Plus path @f-ui-plus/bubble re-exports those parts for installers.

Bubble is the chat message surface — a padded chip for short turns, or a transparent shell when content (like markdown) owns the reading area. Pair it with Message for row alignment; use Markdown Renderer for assistant text instead of wrapping long prose in a solid bubble.

When To Use

  • Short user prompts that should read as “sent” chips (variant="default").
  • Compact assistant replies when you want a soft filled chip (muted).
  • Prefer ghost or no Bubble when the child is long markdown, code fences, or Mermaid — solid bubbles clip pre and double-pad prose.
  • Use Marker for system / status rows, not Bubble.

Features

AreaBehavior
DefaultPrimary filled chip, max width capped for short turns
MutedSoft filled surface for secondary chips
GhostTransparent — content owns padding and measure
ContentVisual chrome lives on BubbleContent (variant styles target the content slot)

Installing

Configure @f-ui-plus and FUI_PLUS_REGISTRY_TOKEN as in Installation — Plus Registry.

FUI_PLUS_REGISTRY_TOKEN=xxx pnpm dlx shadcn@latest add @f-ui-plus/bubble
FUI_PLUS_REGISTRY_TOKEN=xxx npx shadcn@latest add @f-ui-plus/bubble
FUI_PLUS_REGISTRY_TOKEN=xxx yarn dlx shadcn@latest add @f-ui-plus/bubble
FUI_PLUS_REGISTRY_TOKEN=xxx bun x shadcn@latest add @f-ui-plus/bubble

registryDependencies: bare shadcn bubble. No extra runtime packages.

Usage

import { Bubble, BubbleContent } from "@/components/f-ui/bubble/bubble";

<Bubble>
  <BubbleContent>
    <p className="whitespace-pre-wrap">Hello</p>
  </BubbleContent>
</Bubble>

Examples

Variants

Compare default, muted, and ghost surfaces. Prefer ghost (or no Bubble) for long assistant markdown in production layouts.

Default — solid primary chip

Muted — soft filled surface

Ghost — no chrome, content owns the surface

"use client";

import { Bubble, BubbleContent } from "@/components/f-ui/bubble/bubble";

export function BubbleDemo() {
  return (
    <div className="flex flex-col gap-4">
      <Bubble variant="default">
        <BubbleContent>
          <p className="whitespace-pre-wrap">Default — solid primary chip</p>
        </BubbleContent>
      </Bubble>
      <Bubble variant="muted">
        <BubbleContent>
          <p className="whitespace-pre-wrap">Muted — soft filled surface</p>
        </BubbleContent>
      </Bubble>
      <Bubble variant="ghost">
        <BubbleContent>
          <p className="whitespace-pre-wrap">Ghost — no chrome, content owns the surface</p>
        </BubbleContent>
      </Bubble>
    </div>
  );
}

Composition

Bubble
└── BubbleContent

API Reference

Props

PropTypeDefaultDescription
variant"default" | "muted" | "ghost""default"Surface chrome.
classNamestringMerged onto the bubble root.
childrenReactNodeUsually BubbleContent.

Slots

Presentational parts: Bubble, BubbleContent. No classNames map in v1 — style via className on each part.

On this page