diff --git a/COMPONENT_GUIDE.md b/COMPONENT_GUIDE.md index 9a2988a..7e19fed 100644 --- a/COMPONENT_GUIDE.md +++ b/COMPONENT_GUIDE.md @@ -33,6 +33,7 @@ ### "I need to show status" - Dot indicator → **StatusDot** (live, stale, dead, success, warning, error, running) +- Inline colored status value → **StatusText** (success, warning, error, running, muted — with optional bold) - Labeled status → **Badge** with semantic color - Removable label → **Tag** @@ -57,6 +58,9 @@ - Event log → **EventFeed** - Processing pipeline (Gantt view) → **ProcessorTimeline** - Processing pipeline (flow diagram) → **RouteFlow** +- Row of summary KPIs → **KpiStrip** (horizontal strip with colored borders, trends, sparklines) +- Scrollable log output → **LogViewer** (timestamped, severity-colored monospace entries) +- Searchable, selectable entity list → **EntityList** (search header, selection highlighting, pairs with SplitPane) ### "I need to organize content" - Collapsible sections (standalone) → **Collapsible** @@ -64,15 +68,17 @@ - Tabbed content → **Tabs** - Tab switching with pill/segment style → **SegmentedTabs** - Side panel inspector → **DetailPanel** +- Master/detail split layout → **SplitPane** (list on left, detail on right, configurable ratio) - Section with title + action → **SectionHeader** - Empty content placeholder → **EmptyState** -- Grouped content box → **Card** (with optional accent) +- Grouped content box → **Card** (with optional accent and title) - Grouped items with header + meta + footer → **GroupCard** (e.g., app instances) ### "I need to display text" - Code/JSON payload → **CodeBlock** (with line numbers, copy button) - Monospace inline text → **MonoText** - Keyboard shortcut hint → **KeyboardHint** +- Colored inline status text → **StatusText** (semantic color + optional bold, see also "I need to show status") ### "I need to show people/users" - Single user avatar → **Avatar** @@ -115,6 +121,13 @@ Row of StatCard components (each with optional Sparkline and trend) Below: charts (AreaChart, LineChart, BarChart) ``` +### Master/detail management pattern +``` +SplitPane + EntityList for CRUD list/detail screens (users, groups, roles) + EntityList provides: search header, add button, selectable list + SplitPane provides: responsive two-column layout with empty state +``` + ### Detail/inspector pattern ``` DetailPanel (right slide) with Tabs for sections OR children for scrollable content @@ -162,7 +175,7 @@ URL-driven progressive filtering: /agents → /agents/:appId → /agents/:appId/ | Breadcrumb | composite | Navigation path showing current location | | Button | primitive | Action trigger (primary, secondary, danger, ghost) | | ButtonGroup | primitive | Multi-select toggle group with optional colored dot indicators. Props: items (value, label, color?), value (Set), onChange | -| Card | primitive | Content container with optional accent border | +| Card | primitive | Content container with optional accent border and title header | | Checkbox | primitive | Boolean input with label | | CodeBlock | primitive | Syntax-highlighted code/JSON display | | Collapsible | primitive | Single expand/collapse section | @@ -174,6 +187,7 @@ URL-driven progressive filtering: /agents → /agents/:appId → /agents/:appId/ | DetailPanel | composite | Slide-in side panel with tabs or children for scrollable content | | Dropdown | composite | Action menu triggered by any element | | EmptyState | primitive | Placeholder for empty content areas | +| EntityList | composite | Searchable, selectable entity list with add button. Pair with SplitPane for CRUD management screens | | EventFeed | composite | Chronological event log with severity | | FilterBar | composite | Search + filter controls for data views | | GroupCard | composite | Card with header, meta row, children, and optional footer/alert. Used for grouping instances by application. | @@ -183,8 +197,10 @@ URL-driven progressive filtering: /agents → /agents/:appId → /agents/:appId/ | InlineEdit | primitive | Click-to-edit text field. Enter saves, Escape/blur cancels. Props: value, onSave, placeholder, disabled, className | | Input | primitive | Single-line text input with optional icon | | KeyboardHint | primitive | Keyboard shortcut display | +| KpiStrip | composite | Horizontal row of KPI cards with colored left border, trend, subtitle, optional sparkline | | Label | primitive | Form label with optional required asterisk | | LineChart | composite | Time series line visualization | +| LogViewer | composite | Scrollable log output with timestamped, severity-colored monospace entries | | MenuItem | composite | Sidebar navigation item with health/count | | Modal | composite | Generic dialog overlay with backdrop | | MultiSelect | composite | Dropdown with searchable checkbox list and Apply action. Props: options, value, onChange, placeholder, searchable, disabled, className | @@ -202,9 +218,11 @@ URL-driven progressive filtering: /agents → /agents/:appId → /agents/:appId/ | ShortcutsBar | composite | Keyboard shortcuts reference bar | | Skeleton | primitive | Loading placeholder (text, circular, rectangular) | | Sparkline | primitive | Inline mini chart for trends | +| SplitPane | composite | Two-column master/detail layout with configurable ratio and empty state | | Spinner | primitive | Animated loading indicator | | StatCard | primitive | KPI card with value, trend, optional sparkline | | StatusDot | primitive | Colored dot for status indication | +| StatusText | primitive | Inline colored status span (success, warning, error, running, muted) with optional bold | | Tabs | composite | Tabbed content switcher with optional counts | | Tag | primitive | Removable colored label | | Textarea | primitive | Multi-line text input with resize control | diff --git a/src/pages/Inventory/Inventory.tsx b/src/pages/Inventory/Inventory.tsx index 68e1022..ba94051 100644 --- a/src/pages/Inventory/Inventory.tsx +++ b/src/pages/Inventory/Inventory.tsx @@ -39,6 +39,7 @@ const NAV_SECTIONS = [ { label: 'Spinner', href: '#spinner' }, { label: 'StatCard', href: '#statcard' }, { label: 'StatusDot', href: '#statusdot' }, + { label: 'StatusText', href: '#statustext' }, { label: 'Tag', href: '#tag' }, { label: 'Textarea', href: '#textarea' }, { label: 'Toggle', href: '#toggle' }, @@ -60,12 +61,15 @@ const NAV_SECTIONS = [ { label: 'DataTable', href: '#datatable' }, { label: 'DetailPanel', href: '#detailpanel' }, { label: 'Dropdown', href: '#dropdown' }, + { label: 'EntityList', href: '#entitylist' }, { label: 'EventFeed', href: '#eventfeed' }, { label: 'FilterBar', href: '#filterbar' }, { label: 'GroupCard', href: '#groupcard' }, + { label: 'KpiStrip', href: '#kpistrip' }, { label: 'LineChart', href: '#linechart' }, { label: 'LoginDialog', href: '#logindialog' }, { label: 'LoginForm', href: '#loginform' }, + { label: 'LogViewer', href: '#logviewer' }, { label: 'MenuItem', href: '#menuitem' }, { label: 'Modal', href: '#modal' }, { label: 'MultiSelect', href: '#multi-select' }, @@ -74,6 +78,7 @@ const NAV_SECTIONS = [ { label: 'RouteFlow', href: '#routeflow' }, { label: 'SegmentedTabs', href: '#segmented-tabs' }, { label: 'ShortcutsBar', href: '#shortcutsbar' }, + { label: 'SplitPane', href: '#splitpane' }, { label: 'Tabs', href: '#tabs' }, { label: 'Toast', href: '#toast' }, { label: 'TreeView', href: '#treeview' }, diff --git a/src/pages/Inventory/sections/CompositesSection.tsx b/src/pages/Inventory/sections/CompositesSection.tsx index dfde29f..3d938e2 100644 --- a/src/pages/Inventory/sections/CompositesSection.tsx +++ b/src/pages/Inventory/sections/CompositesSection.tsx @@ -12,12 +12,15 @@ import { DataTable, DetailPanel, Dropdown, + EntityList, EventFeed, FilterBar, GroupCard, + KpiStrip, LineChart, LoginDialog, LoginForm, + LogViewer, MenuItem, Modal, MultiSelect, @@ -26,13 +29,14 @@ import { RouteFlow, SegmentedTabs, ShortcutsBar, + SplitPane, Tabs, ToastProvider, useToast, TreeView, } from '../../../design-system/composites' import type { SearchResult } from '../../../design-system/composites' -import { Button } from '../../../design-system/primitives' +import { Avatar, Badge, Button } from '../../../design-system/primitives' // ── DemoCard helper ────────────────────────────────────────────────────────── @@ -178,6 +182,60 @@ const TREE_NODES = [ }, ] +// ── Sample data for new composites ─────────────────────────────────────────── + +const KPI_ITEMS = [ + { + label: 'Exchanges', + value: '12,847', + trend: { label: '\u2191 +8.2%', variant: 'success' as const }, + subtitle: 'Last 24h', + sparkline: [40, 55, 48, 62, 70, 65, 78], + borderColor: 'var(--amber)', + }, + { + label: 'Error Rate', + value: '0.34%', + trend: { label: '\u2191 +0.12pp', variant: 'error' as const }, + subtitle: 'Above threshold', + sparkline: [10, 12, 11, 15, 18, 22, 19], + borderColor: 'var(--error)', + }, + { + label: 'Avg Latency', + value: '142ms', + trend: { label: '\u2193 -12ms', variant: 'success' as const }, + subtitle: 'P95: 380ms', + borderColor: 'var(--success)', + }, + { + label: 'Active Routes', + value: '37', + trend: { label: '\u00b10', variant: 'muted' as const }, + subtitle: '3 paused', + borderColor: 'var(--running)', + }, +] + +const ENTITY_LIST_ITEMS = [ + { id: '1', name: 'Alice Johnson', email: 'alice@example.com', role: 'Admin' }, + { id: '2', name: 'Bob Chen', email: 'bob@example.com', role: 'Editor' }, + { id: '3', name: 'Carol Smith', email: 'carol@example.com', role: 'Viewer' }, + { id: '4', name: 'David Park', email: 'david@example.com', role: 'Editor' }, + { id: '5', name: 'Eva Martinez', email: 'eva@example.com', role: 'Admin' }, +] + +const LOG_ENTRIES = [ + { timestamp: '2026-03-24T10:00:01Z', level: 'info' as const, message: 'Route timer-aggregator started successfully' }, + { timestamp: '2026-03-24T10:00:03Z', level: 'debug' as const, message: 'Polling endpoint https://api.internal/health \u2014 200 OK' }, + { timestamp: '2026-03-24T10:00:15Z', level: 'warn' as const, message: 'Retry queue depth at 847 \u2014 approaching threshold (1000)' }, + { timestamp: '2026-03-24T10:00:22Z', level: 'error' as const, message: 'Exchange failed: Connection refused to jdbc:postgresql://db-primary:5432/orders' }, + { timestamp: '2026-03-24T10:00:23Z', level: 'info' as const, message: 'Failover activated \u2014 routing to db-secondary' }, + { timestamp: '2026-03-24T10:00:30Z', level: 'info' as const, message: 'Exchange completed in 142ms via fallback route' }, + { timestamp: '2026-03-24T10:00:45Z', level: 'debug' as const, message: 'Metrics flush: 328 data points written to InfluxDB' }, + { timestamp: '2026-03-24T10:01:00Z', level: 'warn' as const, message: 'Memory usage at 78% \u2014 GC scheduled' }, +] + // ── CompositesSection ───────────────────────────────────────────────────────── export function CompositesSection() { @@ -221,6 +279,10 @@ export function CompositesSection() { // MultiSelect const [multiValue, setMultiValue] = useState(['admin']) + // EntityList state + const [selectedEntityId, setSelectedEntityId] = useState('1') + const [entitySearch, setEntitySearch] = useState('') + // LoginDialog const [loginDialogOpen, setLoginDialogOpen] = useState(false) const [loginLoading, setLoginLoading] = useState(false) @@ -465,6 +527,38 @@ export function CompositesSection() { + {/* EntityList */} + +
+ + u.name.toLowerCase().includes(entitySearch.toLowerCase()) + )} + renderItem={(item, isSelected) => ( +
+ +
+
{item.name}
+
{item.email}
+
+ +
+ )} + getItemId={(item) => item.id} + selectedId={selectedEntityId} + onSelect={setSelectedEntityId} + searchPlaceholder="Search users..." + onSearch={setEntitySearch} + addLabel="+ Add user" + onAdd={() => {}} + /> +
+
+ {/* 11b. GroupCard */} + {/* KpiStrip */} + +
+ +
+
+ {/* 12. FilterBar */} + {/* LogViewer */} + +
+ +
+
+ {/* 14. MenuItem */} + {/* SplitPane */} + +
+ +
Items
+
Item A
+
Item B
+
Item C
+
+ } + detail={ +
+
Detail View
+
Select an item on the left to see its details here.
+
+ } + ratio="1:2" + /> + +
+ {/* 19. Tabs */}
Plain card
Amber accent
Success accent
Error accent
+ +
Card with title header and separator
+
+ +
Title + accent combined
+
{/* 6. Checkbox */} @@ -559,7 +566,31 @@ export function PrimitivesSection() { - {/* 29. Tag */} + {/* 29. StatusText */} + +
+
+ 99.8% uptime + SLA at risk + BREACH + Processing + N/A +
+
+ 99.8% uptime + SLA at risk + BREACH + Processing + N/A +
+
+
+ + {/* 30. Tag */} undefined} /> - {/* 30. Textarea */} + {/* 31. Textarea */} - {/* 31. Toggle */} + {/* 32. Toggle */} - {/* 32. Tooltip */} + {/* 33. Tooltip */}