From b18b81bdebbb4fa3ef5201fa60eec70724769623 Mon Sep 17 00:00:00 2001 From: cliffhall Date: Mon, 16 Mar 2026 22:45:05 -0400 Subject: [PATCH] spec: Add Storybook component plan with 43 components across 4 tiers Defines all presentational components to be built in Storybook with Mantine, organized bottom-up (atoms, molecules, organisms, layouts) with props interfaces, Mantine implementation notes, story variations, build order, and configuration. Co-Authored-By: Claude Opus 4.6 (1M context) --- specification/v2_ux_storybook.md | 1133 ++++++++++++++++++++++++++++++ 1 file changed, 1133 insertions(+) create mode 100644 specification/v2_ux_storybook.md diff --git a/specification/v2_ux_storybook.md b/specification/v2_ux_storybook.md new file mode 100644 index 00000000..616fa38a --- /dev/null +++ b/specification/v2_ux_storybook.md @@ -0,0 +1,1133 @@ +# Inspector V2 UX - Storybook Component Plan + +### [Brief](README.md) | [V1 Problems](v1_problems.md) | [V2 Scope](v2_scope.md) | [V2 Tech Stack](v2_web_client.md) | V2 UX +#### [Overview](v2_ux.md) | [Features](v2_ux_features.md) | [Handlers](v2_ux_handlers.md) | [Screenshots](v2_screenshots.md) | [Components](v2_ux_components.md) | Storybook + +--- + +This document defines every presentational component to be built in Storybook using Mantine. Components are organized bottom-up: atoms first, then molecules, then organisms. Each component receives all data and callbacks via props — no store access. + +## Table of Contents + * [Conventions](#conventions) + * [Tier 1 - Atoms](#tier-1---atoms) + * [Tier 2 - Molecules](#tier-2---molecules) + * [Tier 3 - Organisms](#tier-3---organisms) + * [Tier 4 - Page Layouts](#tier-4---page-layouts) + * [Build Order](#build-order) + * [Storybook Configuration](#storybook-configuration) + +--- + +## Conventions + +### File Structure +``` +src/components/ + atoms/ + StatusIndicator/ + StatusIndicator.tsx + StatusIndicator.stories.tsx + ... + molecules/ + ServerCard/ + ServerCard.tsx + ServerCard.stories.tsx + ... + organisms/ + ToolsScreen/ + ToolsScreen.tsx + ToolsScreen.stories.tsx + ... + layouts/ + AppShell/ + AppShell.tsx + AppShell.stories.tsx + ... +``` + +### Props Pattern +Every component exports a `Props` interface. Callbacks use the `onVerb` convention. Boolean flags use `canVerb` or `isState` naming. + +```typescript +// Example +export interface StatusIndicatorProps { + status: 'connected' | 'connecting' | 'disconnected' | 'failed'; + latencyMs?: number; + retryCount?: number; +} +``` + +### Story Pattern +Each component has at minimum a `Default` story plus stories for each meaningful state variation. + +```typescript +const meta: Meta = { + component: StatusIndicator, + decorators: [MantineDecorator], +}; + +export const Connected: Story = { args: { status: 'connected', latencyMs: 23 } }; +export const Failed: Story = { args: { status: 'failed', retryCount: 3 } }; +``` + +--- + +## Tier 1 - Atoms + +Small, single-purpose components. Most map directly to a Mantine component with specific props/styling. + +### 1.1 StatusIndicator + +Connection status dot with label. + +| Prop | Type | Description | +|------|------|-------------| +| `status` | `'connected' \| 'connecting' \| 'disconnected' \| 'failed'` | Current state | +| `latencyMs` | `number?` | Ping latency (shown when connected) | +| `retryCount` | `number?` | Retry attempts (shown when failed) | + +**Mantine:** Custom component using `Box` for the dot + `Text`. Pulsing animation via CSS for `connecting`. + +**Stories:** Connected, Connecting, Disconnected, Failed, FailedWithRetries + +--- + +### 1.2 AnnotationBadge + +Tag-style badge for tool/resource annotations. + +| Prop | Type | Description | +|------|------|-------------| +| `label` | `string` | Badge text (e.g., "user", "read-only", "destructive") | +| `variant` | `'audience' \| 'readOnly' \| 'destructive' \| 'longRun' \| 'priority' \| 'default'` | Visual style | + +**Mantine:** `Badge` with `variant` and `color` mapped from annotation type. Destructive = red outline, long-run = yellow, read-only = dark filled, audience = gray outline, priority = orange/yellow/green by level. + +**Stories:** Audience, ReadOnly, Destructive, LongRun, PriorityHigh, PriorityMedium, PriorityLow, Custom + +--- + +### 1.3 CapabilityItem + +Single capability row with check/cross icon and label. + +| Prop | Type | Description | +|------|------|-------------| +| `name` | `string` | Capability name | +| `supported` | `boolean` | Whether capability is available | +| `count` | `number?` | Optional count (e.g., "Tools (4)") | + +**Mantine:** `Group` with `ThemeIcon` (check or X) + `Text`. + +**Stories:** Supported, SupportedWithCount, NotSupported + +--- + +### 1.4 LogEntry + +Single log line with timestamp, level badge, and message. + +| Prop | Type | Description | +|------|------|-------------| +| `timestamp` | `string` | Formatted time (e.g., "14:32:01") | +| `level` | `'debug' \| 'info' \| 'notice' \| 'warning' \| 'error' \| 'critical' \| 'alert' \| 'emergency'` | RFC 5424 level | +| `message` | `string` | Log message text | +| `logger` | `string?` | Logger name | + +**Mantine:** `Group` with `Text` (timestamp) + `Badge` (level, color-coded) + `Text` (message). Level colors: debug=gray, info=blue, notice=teal, warning=yellow, error=red, critical=red+filled, alert=red+bold, emergency=red+filled+bold. + +**Stories:** Debug, Info, Notice, Warning, Error, Critical, Alert, Emergency, WithLogger + +--- + +### 1.5 ProgressDisplay + +Progress bar with percentage and optional step description. + +| Prop | Type | Description | +|------|------|-------------| +| `progress` | `number` | 0-100 percentage | +| `description` | `string?` | Current step text | +| `elapsed` | `string?` | Elapsed time display | + +**Mantine:** `Progress` bar + `Text` for description and percentage. + +**Stories:** ZeroPercent, HalfComplete, NearComplete, Complete, WithDescription, WithElapsed + +--- + +### 1.6 ContentViewer + +Renders text, JSON, image, or audio content with syntax highlighting. + +| Prop | Type | Description | +|------|------|-------------| +| `type` | `'text' \| 'json' \| 'image' \| 'audio'` | Content type | +| `content` | `string` | The content (text, JSON string, base64, or URL) | +| `mimeType` | `string?` | MIME type for images/audio | +| `onCopy` | `() => void` | Copy callback | + +**Mantine:** `Code` block for JSON/text (with `language` prop), `Image` for images, native `