inspector/clients/web/src/components/atoms/MessageBubble/MessageBubble.tsx
cliffhall 39ef184b53 feat: Add Mantine theme, 12 atom components, and 25 molecule components with Storybook stories
- Mantine theme with component extensions (Badge, Card, Paper, Button, etc.)
- CSS custom properties for design tokens (--inspector-* vars)
- Dark/light mode support with auto detection
- 12 atoms: StatusIndicator, AnnotationBadge, CapabilityItem, LogEntry,
  ProgressDisplay, ContentViewer, ListChangedIndicator, CopyButton,
  ConnectionToggle, TransportBadge, InlineError, MessageBubble
- 25 molecules: ServerCard, AddServerMenu, SchemaForm, ToolListItem,
  ToolDetailPanel, ResultPanel, ResourceListItem, ResourcePreviewPanel,
  ResourceTemplateInput, PromptArgumentsForm, PromptMessagesDisplay,
  LogControls, TaskCard, HistoryEntry, ServerInfoContent, ServerSettingsForm,
  RootsTable, SamplingRequestPanel, ElicitationFormPanel, ElicitationUrlPanel,
  InlineSamplingRequest, InlineElicitationRequest, PendingClientRequests,
  ImportServerJsonPanel, ExperimentalFeaturesPanel
- Exclude storybook-static from version control
- Exclude .stories.tsx from app tsconfig (Storybook-only modules)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 10:23:56 -04:00

44 lines
1.1 KiB
TypeScript

import { Image, Paper, Stack, Text } from '@mantine/core';
export interface MessageBubbleProps {
index: number;
role: 'user' | 'assistant';
content: string;
imageContent?: { data: string; mimeType: string };
audioContent?: { data: string; mimeType: string };
}
export function MessageBubble({
index,
role,
content,
imageContent,
audioContent,
}: MessageBubbleProps) {
return (
<Paper p="md" radius="md" withBorder>
<Stack gap="xs">
<Text size="xs" c="dimmed">
[{index}] role: {role}
</Text>
<Text size="sm">&quot;{content}&quot;</Text>
{imageContent && (
<Image
src={`data:${imageContent.mimeType};base64,${imageContent.data}`}
maw={300}
radius="sm"
mt="xs"
/>
)}
{audioContent && (
<audio controls>
<source
src={`data:${audioContent.mimeType};base64,${audioContent.data}`}
type={audioContent.mimeType}
/>
</audio>
)}
</Stack>
</Paper>
);
}