Message

Shows one turn of a conversation.

From

  • Maya
    Refund order 4812, the headphones arrived broken.

    userdefault

  • Refund agent

    Refunded $48.00 to the original card.

    Worked for 14s,14:02glaze-large

    agent

Bubble

  • Maya
    Refund order 4812, the headphones arrived broken.

    defaultdefault

  • Maya
    Refund order 4812, the headphones arrived broken.

    outline

Divider

  • compaction

  • interrupted

  • day

  • handoff

States

  • Maya
    Refund order 4812, the headphones arrived broken.

    sent

  • Maya
    Refund order 4812, the headphones arrived broken.
    Sending

    sending

  • Maya
    Refund order 4812, the headphones arrived broken.
    Not sent

    not sent

  • Refund agent

    Refunded $48.00 to the original card.

    Worked for 14s,14:02glaze-large

    agent done

  • Refund agent

    Refunded $48.00 to the original card.

    Worked for 14s,14:02glaze-large

    footer in focus

  • Refund agentFailed

    The payment provider refused the refund.

    agent failed

  • Refund agentStopped

    Looking up order 4812

    agent stopped

Usage

When to use it
Use
A thread shows what a person wrote and what an agent did and said.
Use
A point in the thread needs marking: context compacted, a run interrupted, a handoff.
Not for
A one-off notice about the page, not a turn. Use Alert.
Not for
A list of runs or tickets. Use Item.

Rules

6 rules
Must
Build every agent turn with AgentTurn, its sections in order: reasoning, tool calls, the answer, the footer. Because every turn in a thread then shares one column and one header, read aloud, and a turn that failed or stopped shows its word in the same place.
Never
Put an agent turn in a card or a bubble; it is plain flow at the full width. Because the person's bubble is the only box in a thread, so a boxed answer reads as a second speaker and doubles every edge.
Must
Keep a message that did not send in the thread with MessageBubble status="fail" and MessageSendState state="failed" with onRetry. Because dropping it loses what the person wrote; the coral edge and "Not sent" say what happened and Retry sends the same text.
Must
Make the footer's actions ghost icon-sm Buttons or CopyButton, each with an aria-label. Because they show on hover and focus over a quiet line, and a glass key there would claim to be the turn's next step.
Should
Name the model that answered with MessageModel, and pass requested when a fallback answered. Because a turn answered by another model than the one picked should say so, and the footer is where a person looks.
Should
Mark compaction, interruption, a new day and a handoff with MessageDivider reason, not a rule of your own. Because reason sets the words, the glyph and the form, and a handoff to a person is the one centred line a thread has.

Accessibility

4 checks
Each turn has a header with the speaker and time, read aloud even where it is not drawn.
A failed or stopped agent turn says so in a word; the footer hides while the turn is live.
Footer buttons show on hover where there is a pointer, always on touch, and on keyboard focus.
A divider is role="separator" named by its words.

Edge cases

5 edge cases
Long word or URL in a bubble
Breaks anywhere; the bubble never passes 85% of the row.
A message that did not send
Keeps its text, the edge turns coral, "Not sent" and Retry sit under it.
Fallback model
MessageModel reads "glaze-small for glaze-large".
Right to left
The person's bubble sits at the start of the row instead of the end.
Dark theme
The bubble takes the dark shell, a step under the panel.

API

8 props
Message from
'agent' | 'user' default 'agent'
Message size
'default' | 'sm' default 'default'
AgentTurn name, time, state
string, ReactNode, 'live' | 'waiting' | 'fail' | 'stopped' | 'done' default state 'done'
MessageBubble variant, status
'default' | 'outline', 'fail' default 'default'
MessageBubbleContent render
ReactElement
MessageSendState state, onRetry
'sending' | 'sent' | 'failed', () => void
MessageFooter, MessageWorked, MessageModel, MessageMeta
parts
MessageDivider reason, to
'compaction' | 'interrupted' | 'handoff' | 'day', 'person' | 'agent' default to 'person'

Tokens

12 tokens
--shell
#f1f1f0
--paper
#ffffff
--line-faint
rgb(5 5 5 / 0.06)
--line-control
rgb(5 5 5 / 0.15)
--line
rgb(5 5 5 / 0.10)
--fail
#e35e49
--radius-overlay
10px
--type-body
400 14px/1.5 var(--font-sans)
--type-caption
400 12px/1.35 var(--font-sans)
--text-1
rgb(5 5 5 / 0.80)
--text-2
rgb(5 5 5 / 0.60)
--measure
68ch

Install

For your coding agent

GitHub

Please star me pookie

141

A new design system every week

Leave your email before you copy the prompt.