---
id: "packages/active-ui/bubble"
title: "Bubble"
description: "The shape that holds the text of a message, in seven variants, with reactions and as a button."
url: "/packages/active-ui/bubble"
locale: "en"
revision: "1692f492bf2ed14c"
---

# Bubble

A bubble holds the text of one message. It sizes to its content up to 80% of the column, sits on
the start or end side, and can carry reactions. Use it inside a [message](/packages/active-ui/message),
or on its own for a short note in a stream.

**Example: Variants, alignment, reactions and a button**

Client: Runs entirely in your browser. Source: `examples/ui/bubble.tsx`.

```tsx
// apps/docs/examples/ui/bubble.tsx
'use client';

import {useState} from 'react';

import {
  Bubble,
  BubbleContent,
  BubbleGroup,
  BubbleReactions,
} from '@workspace/active-ui/components/primitives/bubble';

const VARIANTS = [
  'default',
  'secondary',
  'muted',
  'tinted',
  'outline',
  'ghost',
  'destructive',
] as const;

/**
 * The shape of a message: seven variants, a bubble aligned to the end, a
 * bubble with reactions, and a bubble that is a button.
 */
export default function BubbleExample() {
  const [liked, setLiked] = useState(false);
  return (
    <div className="flex w-full max-w-md flex-col gap-6">
      <BubbleGroup>
        {VARIANTS.map((variant) => (
          <Bubble key={variant} variant={variant}>
            <BubbleContent>The {variant} variant</BubbleContent>
          </Bubble>
        ))}
      </BubbleGroup>
      <BubbleGroup>
        <Bubble align="end">
          <BubbleContent>Aligned to the end</BubbleContent>
        </Bubble>
        <Bubble variant="secondary">
          <BubbleContent>With a reaction</BubbleContent>
          <BubbleReactions aria-label="1 reaction">👍</BubbleReactions>
        </Bubble>
        <Bubble variant="outline">
          <BubbleContent
            render={<button type="button" />}
            aria-pressed={liked}
            onClick={() => setLiked(!liked)}
          >
            {liked ? 'Liked: press to undo' : 'Press this bubble to like it'}
          </BubbleContent>
        </Bubble>
      </BubbleGroup>
    </div>
  );
}
```

## Usage

```tsx
import {
  Bubble,
  BubbleContent,
} from '@workspace/active-ui/components/primitives/bubble';

<Bubble variant="muted">
  <BubbleContent>Could you check the address?</BubbleContent>
</Bubble>;
```

## Anatomy

- `BubbleGroup`: a column of bubbles with a small gap.
- `Bubble`: the frame. `variant`: `default` (primary), `secondary`, `muted`, `tinted` (a light
  tint of the primary colour), `outline`, `ghost` (no shape, for long text) or `destructive` (a
  message that failed). `align`: `start` or `end`.
- `BubbleContent`: the text. `render` makes it another element, such as a button or a link; it
  then gets a hover state.
- `BubbleReactions`: reactions on the edge. `align` (`start`, `end`) and `side` (`top`,
  `bottom`) place them.

## What your application provides

- The content and the side.
- The meaning behind a variant in text as well: a failed message says that it failed, not only in
  red.

## Accessibility

A bubble is read as its text. A bubble rendered as a button is an ordinary button; give it a name
that says what pressing does when the text alone does not.

## API

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `align` | `"end" \| "start"` | no | The side the bubble sits on. |
| `variant` | `"default" \| "destructive" \| "ghost" \| "muted" \| "outline" \| "secondary" \| "tinted" \| null` | no | The look: `default` (primary), `secondary`, `muted`, `tinted`, `outline`, `ghost` (no shape) or `destructive` (a failed message). |

### Other parts

**BubbleGroup**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |

BubbleGroup has no props of its own.

**BubbleContent**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `render` | `ComponentRenderFn<HTMLProps, {}> \| ReactElement<unknown, string \| JSXElementConstructor<any>>` | no | Allows you to replace the component's HTML element with a different tag, or compose it with another component.  Accepts a `ReactElement` or a function that returns the element to render. |

**BubbleReactions**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `align` | `"end" \| "start"` | no | The corner the reactions sit at, along the bubble. |
| `side` | `"bottom" \| "top"` | no | The edge the reactions sit on. |
