Bubble

A hand-drawn chat bubble in a received or sent variant.

Overview

Bubble is a single chat bubble — a sketchy rounded box holding message text. It comes in two variants: received (a muted incoming bubble) and sent (a filled outgoing bubble in the primary colour). It only paints itself; alignment within a conversation is the caller’s concern (see the Message component).

Anatomy

A hand-drawn rounded box (outline + fill from @ghds/sketch-core) wrapping inline message text. Colour, padding, radius, and sketch parameters come from @ghds/tokens (comp.bubble.*). The box is inline-block with max-width: 100%, so long text wraps rather than overflowing.

Variants & States

Two variants, no interactive states — the bubble is static content.

State Status Notes
received Implemented A muted incoming bubble.
sent Implemented A filled outgoing bubble in the primary colour.
Hover / Focus Not implemented Not interactive on its own.
Disabled Not implemented
Loading Not implemented

Usage

Do

  • Use received for incoming messages and sent for the current user’s outgoing ones.
  • Wrap bubbles in Message to handle avatar, author, timestamp, and alignment.
  • Constrain the bubble’s max width in long threads so lines stay readable.

Don't

  • Don't rely on Bubble for alignment — it paints itself but doesn't position within a row.
  • Don't put interactive controls that need their own semantics directly inside a bubble without proper roles.

Accessibility

Content

Keep bubble content to the message itself. Author and timestamp belong in the surrounding Message header, not inside the bubble.

Props API

React@ghds/react

PropTypeDefaultDescription
variant'received' | 'sent''received''received' is a muted incoming bubble; 'sent' is a filled outgoing bubble.
...restHTMLAttributes<HTMLDivElement>Native <div> attributes (style for max-width, etc.) pass through.

Web Components@ghds/web-components

PropTypeDefaultDescription
variant'received' | 'sent''received'Reflected attribute; 'received' is muted incoming, 'sent' is a filled outgoing bubble.
slot(default)The message content.

React Native@ghds/react-native

PropTypeDefaultDescription
variant'received' | 'sent''received''received' is a muted incoming bubble; 'sent' is a filled outgoing bubble.
childrenReactNodeBubble content.
testIDstringTest handle for queries.

Code examples

// React — @ghds/react
import { Bubble } from '@ghds/react/bubble';

<Bubble variant="received">Hey — are we still on for tomorrow?</Bubble>
<Bubble variant="sent">Yes! See you at 10.</Bubble>;
<!-- Web Components — @ghds/web-components -->
<script type="module">
  import '@ghds/web-components/bubble';
</script>
<gh-bubble variant="received">Hey — are we still on for tomorrow?</gh-bubble>
<gh-bubble variant="sent">Yes! See you at 10.</gh-bubble>
// React Native — @ghds/react-native
import { Bubble } from '@ghds/react-native/bubble';

<Bubble variant="received">Hey — are we still on for tomorrow?</Bubble>
<Bubble variant="sent">Yes! See you at 10.</Bubble>;

Live Demo

React and Web Components render live below, driven by the same tokens — toggle dark mode in the header to see both respond identically. React Native can’t run in a browser without additional react-native-web wiring (not set up in this site), so its usage is shown as a code sample instead.

React @ghds/react

Web Components @ghds/web-components

Hey — are we still on for tomorrow?
Yes! See you at 10.