# Bubble

> The framed message surface inside a conversational row's content slot, sized to its own content up to a share of the row's width.

```ts
import { Bubble } from "@sdxc/ui";
```

Renders the frame, pushed to the edge `align` names via auto margins so it
aligns correctly regardless of its row's layout. Its nearest corner falls
back to a literal `0.125rem`, since `roundedCorner()` has no `"xs"` step.

## Examples

```tsx
<Bubble align="end">
	<Bubble.Content>{turn.text}</Bubble.Content>
</Bubble>
```

```tsx
<Bubble variant="muted" align="start">
	<Bubble.Content>{turn.text}</Bubble.Content>
</Bubble>
```

```tsx
<Bubble variant="ghost" align="start">
	<Bubble.Content>
		<Typeset preset="chat">{renderedMarkdownHtml}</Typeset>
	</Bubble.Content>
</Bubble>
```

## Props

| Prop | Type | Description |
| --- | --- | --- |
| `variant?` | `"default" \| "secondary" \| "muted" \| "tinted" \| "outline" \| "ghost" \| "destructive"` | Visual weight. Defaults to DEFAULT_VARIANT. |
| `align?` | `"start" \| "end"` | Edge of the row the frame hugs. Defaults to DEFAULT_ALIGN. |
| `children` | `RemixNode` | The frame's compound parts: Bubble.Content, an optional Bubble.Reactions, or any other content. |

Also accepts everything in `TagProps<"div">`.


### Bubble.Content

Renders Bubble.ContentProps.children as the frame's padded text slot, breaking long unbroken runs at the inline box edge and taking its text color from the ancestor Bubble's `variant` via CSS inheritance.

| Prop | Type | Description |
| --- | --- | --- |
| `children` | `RemixNode` | The turn's text — plain, or wrapped in a typography layer for rendered markdown. |

Also accepts everything in `TagProps<"div">`.


### Bubble.Reactions

Renders Bubble.ReactionsProps.children as a `role="group"` row: a negative block-start margin pins it into the frame's lower padding, aligned via the `--ui-bubble-reactions-justify` property the frame sets from `align`.

| Prop | Type | Description |
| --- | --- | --- |
| `"aria-label"` | `string` | Accessible label describing the row as a set of reactions. |
| `children` | `RemixNode` | One or more already-pressed toggle controls, each scoped to a single reaction. |

Also accepts everything in `Omit<TagProps<"div">, "aria-label">`.


### Bubble.Group

Renders Bubble.GroupProps.children as a tightly spaced column of consecutive Bubble frames, softening only the corners touching a neighbor to a smaller radius, so the run reads as one continuous shape.

| Prop | Type | Description |
| --- | --- | --- |
| `children` | `RemixNode` | Two or more Bubble frames from the same turn, stacked into one run. |

Also accepts everything in `TagProps<"div">`.


## Types

| Name | Values | What it decides |
| --- | --- | --- |
| `Variant` | `"default" \| "secondary" \| "muted" \| "tinted" \| "outline" \| "ghost" \| "destructive"` | Visual weight the frame renders with: solid `"default"`/`"secondary"` fills, soft `"muted"`/`"tinted"` tints, a bordered `"outline"`, an unframed `"ghost"`, and a solid danger fill for `"destructive"`. |
| `Align` | `"start" \| "end"` | Edge of the row the frame hugs: `"start"` stays flush with the row's leading edge (flipping under `dir="rtl"`), `"end"` stays flush with the trailing edge, typically paired with the reader's own turns vs everyone else's. |
