Message

One turn in a conversation. The two roles are shaped differently on purpose — a user message is a bubble, an assistant message is full-width prose, because a long answer in a bubble is unreadable.

src/components/ui/message.tsx

About

From the component's own source, where it was written.

One turn in a conversation.

The two roles are shaped differently on purpose: a user message is a bubble pinned to the trailing edge, an assistant message is full-width prose. Giving both the same bubble makes a long answer unreadable, and makes it harder to tell at a glance who said what.

Install

npx astralyx-ui add message

Usage

import { Message } from '@/components/ui/message'

<Message role="user" name="Ada">How do the colour sets work?</Message>
<Message role="assistant" onRetry={retry} onVote={vote} copyText={text}>
  Every variant reads the same --ui-* set…
</Message>

Composer

Change the props and the source below follows.

Assistant
Every variant reads the same --ui-* colour set, so one prop restyles solid, secondary, outline and ghost together.
Props
tsx
<Message
  role="assistant"
  onRetry={retry}
  onVote={vote}
>
  …
</Message>

Examples

A short exchange

API

Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.

Message

One turn in a conversation.

Extends Omit<ComponentProps<'div'>, 'onCopy'>.

PropTypeDefaultDescription
roleAriaRolerequiredDecides the shape: a trailing bubble, or full-width prose with an avatar.
namestring—Author name, used for the avatar's initials.
avatarReactNode——
actionsbooleanrole === 'assistant'Copy, retry and vote row under the message.
onCopy() => void——
onRetry() => void—Each adds its button only when provided.
onVote(vote: 'up' | 'down') => void—Each adds its button only when provided.
copyTextstring—What the copy button writes to the clipboard.
copyLabelstring'Copy'—
copiedLabelstring'Copied'Replaces copyLabel in the tooltip once copied.
retryLabelstring'Retry'—
upvoteLabelstring'Good response'—
downvoteLabelstring'Bad response'—

MessagePending

The three-dot pulse, with role="status" and a screen-reader label — a purely visual animation says nothing about why the interface went quiet.

Extends ComponentProps<'div'>.

PropTypeDefaultDescription
labelstring'Generating a response'—