@lssm/example.graph-showcase
v3.0.2
Published
Interactive graph-richness showcase for ContractSpec P6 primitives: mini-map, focus-mode, custom renderers, edge labels, animations, and drilldown.
Readme
@lssm/example.graph-showcase
Showroom-grade interactive showcase — 23 graph demos across 8 categories, 4-engine layout (ELK DAG / Ortho / Tree + d3-force), 3-preset theme system with full dark-mode, pointer/touch/keyboard interactions, and Playwright integration tests.

What you'll see
| Category | Demo screens | Default preset |
|---|---|---|
| Templates | Workflow DAG, Agent Tree, Conversation Graph, Engineering Loop, Person Activity | n8n-card |
| Filtering | Facet Panel, Filter Chip Rack, Search Overlay, Path Highlight | gh-slim |
| Time | Time Scrub, Diff Animations, Saved View Restore | gh-slim |
| Structure | Clustering, Heatmap, Minimap, Focus Mode | gh-slim |
| AI | AI Input, AI Suggest+Confirm | n8n-card |
| Annotations | Annotations, Story Mode | obsidian-dot |
| Collab | Collab Cursors, Subscribe | obsidian-dot |
| Export | Export Pipeline | obsidian-dot |
Interactions
| Action | Pointer | Touch | Keyboard |
|---|---|---|---|
| Navigate sidebar | Click item | Tap item | ↑ / ↓, then Enter |
| Collapse sidebar | Click hamburger | Tap hamburger | ⌘B / Ctrl+B |
| Pan canvas | Drag background | 1-finger swipe | Space + drag |
| Zoom in / out | Scroll wheel | 2-finger pinch | + / - via ZoomCluster |
| Fit graph to view | Click Auto-fit | — | Auto-fit button |
| Select node | Click | Tap | Tab to node, Space |
| Deselect / close | Click empty area | Tap empty | Escape |
| Open search | Click search bar | — | / |
| Open command palette | Click search bar | — | ⌘K / Ctrl+K |
| Switch layout engine | Click pill in DemoHeader | — | Click only |
| Toggle dark mode | Click ☾ / ☀ in AppBar | — | Click only |
Shell
The showcase uses a hash-based router (useShowcaseRouter) with 23 SHOWCASE_ROUTES
entries (key / label / category / recommendedTheme). Each demo is wrapped in
<GraphThemeProvider themeId={recommendedTheme}> — the shell auto-selects the best
visual preset per route.
Global keyboard handlers in ShowcaseShell: ⌘K / Ctrl+K → CommandPalette;
/ → SearchBar.
Theme presets
Three presets ship with WCAG AA 4.5:1 verified tokens in both light and dark.
| Preset | Mode | Background | Node fill | Character |
|---|---|---|---|---|
| n8n-card | light | #FAF4EC warm cream | #FFF8F0 | Rounded cards, warm workflow builder |
| n8n-card | dark | #0E0D0B near-black | #1C1A17 warm | Immersive dark workflow |
| gh-slim | light | #F8FAFC cool white | #F1F5F9 | Compact GitHub-style DAG |
| gh-slim | dark | #020617 near-navy | #1E293B slate | Dark compact DAG |
| obsidian-dot | light | #F5F3FF violet tint | #EDE9FE | Knowledge-graph dot style |
| obsidian-dot | dark | #0A0110 deep violet | #1A0B2E | Atmospheric dark dots |
Toggle dark mode via ☾ in the AppBar. This sets DesignSystemThemeProvider mode="dark"
and the Tailwind dark class on <html>, updating both chrome surfaces (Tailwind dark:
utilities) and graph tokens (--graph-* CSS vars via CanvasVarsInjector).
Architecture
graph TD
DSP["DesignSystemThemeProvider\nmode: light | dark"]
Shell["ShowcaseShell\ncontext providers · dark toggle"]
AppBar["AppBar 48px\nlogo · search · GitHub · CTA · ☾"]
SidebarNav["SidebarNav 240px\n23 routes · 8 categories · ⌘B"]
DemoHeader["DemoHeader 56px\nbreadcrumb · role · layout pills"]
CanvasArea["CanvasArea\nadaptive dot-grid · border"]
GTP["GraphThemeProvider\nthemeId context"]
CVI["CanvasVarsInjector\n--graph-* CSS vars"]
Demo["Demo Screen\nWorkflowDagDemo · AgentTreeDemo …"]
GC["GraphCanvas\nSVG renderer · useGraphLayout"]
Atoms["Node / Edge Atoms\nN8nCardNode · GhSlimNode\nObsidianDotNode + edges"]
DSP -->|wraps| Shell
Shell --> AppBar
Shell --> SidebarNav
Shell --> DemoHeader
Shell --> CanvasArea
CanvasArea --> GTP
GTP --> CVI
CVI --> Demo
Demo --> GC
GC --> AtomsToken flow: DesignSystemThemeProvider(mode) → useGraphTheme(themeId) inside
CanvasVarsInjector → emits --graph-node-fill, --graph-kind-{kind}-{fill|stroke|label|accent}
CSS vars on a wrapper <div> → atom components read them as var(--graph-node-fill, <light-fallback>).
Fixture data
All demo screens share synthetic fixtures in src/fixtures.ts:
- 12 nodes spanning 4
kindvalues (contract,entity,event,feature) - 14 directed edges — mix of labeled and unlabeled
- A focus sub-graph (6-node cluster) for minimap + focus-mode demos
- Seed
Viewportandselectionvalues
Usage
import { SHOWCASE_ROUTES } from '@lssm/example.graph-showcase';
// Enumerate all 23 route keys:
SHOWCASE_ROUTES.forEach(r => console.log(r.key, r.category, r.recommendedTheme));Commands
bun run typecheck # tsgo --noEmit
bun test # unit + smoke tests (bun test runner)
bun run test:e2e # Playwright integration tests (showcase config, port 5999)
bun run lint:check # Biome lint checkPlaywright integration tests
| Suite | File | Coverage |
|---|---|---|
| Accessibility | playwright/a11y.spec.ts | S8.1–S8.5: landmarks, keyboard, reduced-motion |
| Lighthouse | playwright/lighthouse.spec.ts | S9.2: performance + ARIA structure |
| Touch | playwright/touch.spec.ts | S9.3: iPad Mini tap-to-navigate, sidebar |
| Dark-mode | playwright/template-darkmode.spec.ts | S9.4: 10 PNG baselines (5 templates × light/dark) |
| Responsive | playwright/responsive.spec.ts | E3: phone / tablet / desktop viewports |
Regenerate dark-mode baselines:
bun exec playwright test --config playwright.showcase.config.ts \
template-darkmode.spec.ts --update-snapshotsDeclaration builds use build:types through the shared Bun tool; build runs
bundle and declaration generation. Declared exports are preserved. Generated
artifacts exclude test-only files; tests/typecheck remain separate gates.
