Message Bubble
Chat message bubble for user, assistant, system, and tool messages with markdown support, thinking blocks, tool call chips, citation cards, streaming cursors, and error retry actions.
Preview
Preview
What's the weather in San Francisco?
It's currently 18°C and sunny in San Francisco. Perfect weather for a walk!
You are a helpful weather assistant.
Installation
$
flai add message_bubble
Import
import 'package:my_app/flai/components/message_bubble/message_bubble.dart';
Usage
The bubble automatically adapts its layout based on the message role:
// User message
MessageBubble(
message: Message(
id: '1',
role: MessageRole.user,
content: 'What is Flutter?',
timestamp: DateTime.now(),
),
)
// Assistant message with citations
MessageBubble(
message: Message(
id: '2',
role: MessageRole.assistant,
content: 'Flutter is a UI toolkit...',
timestamp: DateTime.now(),
citations: [
Citation(title: 'Flutter Docs', url: 'https://flutter.dev'),
],
),
onTapCitation: (citation) {
launchUrl(Uri.parse(citation.url!));
},
)
// Streaming message (shows blinking cursor)
MessageBubble(
message: Message(
id: '3',
role: MessageRole.assistant,
content: 'Flutter is a...',
timestamp: DateTime.now(),
status: MessageStatus.streaming,
),
)
Message Roles
The bubble renders four distinct layouts based on MessageRole:
| Role | Alignment | Style |
|---|---|---|
| user | Right-aligned | Uses userBubble color, rounded bottom-right corner |
| assistant | Left-aligned | Uses assistantBubble color, rounded bottom-left corner |
| system | Centered | Muted background, smaller text, bordered |
| tool | Left-aligned | Compact, bordered, with wrench icon |
Features
- Thinking blocks — Collapsible panel showing AI reasoning when
message.thinkingContentis set - Tool call chips — Inline chips for each tool call with status indicator
- Citation cards — Tappable cards linking to source material
- Streaming cursor — Blinking cursor animation when
status == MessageStatus.streaming - Error retry — Retry button on error messages when
onRetryis provided - Long press — Copy/share action when
onLongPressis provided - Timestamps — Subtle time label below each bubble
Properties
| Property | Type | Default | Description |
|---|---|---|---|
| message | Message | required | The message to display. |
| onTapCitation | Function(Citation)? | null | Called when a citation is tapped. |
| onRetry | Function(Message)? | null | Called when retry is tapped on an error message. |
| onLongPress | Function(Message)? | null | Called when the bubble is long-pressed. |
Message Model
class Message {
final String id;
final MessageRole role; // user, assistant, system, tool
final String content;
final DateTime timestamp;
final List<Attachment>? attachments;
final List<ToolCall>? toolCalls;
final String? thinkingContent;
final List<Citation>? citations;
final MessageStatus status; // streaming, complete, error
final UsageInfo? usage;
}