@principal-ai/subsystems-react 0.17.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/index.d.ts +7 -44
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +6 -32
  4. package/dist/index.js.map +1 -1
  5. package/package.json +2 -2
  6. package/src/index.ts +9 -199
  7. package/src/components/ConfigurationSelector.tsx +0 -133
  8. package/src/components/GraphRenderer.tsx +0 -3195
  9. package/src/components/MultiCanvasRenderer.tsx +0 -295
  10. package/src/components/NodeTooltip.tsx +0 -279
  11. package/src/components/PendingChanges.test.tsx +0 -375
  12. package/src/components/SelectionSidebar.tsx +0 -352
  13. package/src/components/SequenceDiagramRenderer.tsx +0 -1156
  14. package/src/components/WorkflowSequenceDiagram.tsx +0 -270
  15. package/src/components/dashboard/DashboardRenderer.tsx +0 -317
  16. package/src/components/dashboard/MetricPanel.tsx +0 -254
  17. package/src/components/dashboard/MockDataProvider.ts +0 -330
  18. package/src/components/dashboard/components/BarChart.tsx +0 -299
  19. package/src/components/dashboard/components/LineChart.tsx +0 -279
  20. package/src/components/dashboard/components/MetricCard.tsx +0 -270
  21. package/src/components/dashboard/components/SourceLink.tsx +0 -63
  22. package/src/components/dashboard/components/TimeRangeSelector.tsx +0 -280
  23. package/src/components/dashboard/components/index.ts +0 -5
  24. package/src/components/dashboard/index.ts +0 -47
  25. package/src/components/dashboard/types.ts +0 -126
  26. package/src/components/state-view/PipelineView.tsx +0 -347
  27. package/src/components/state-view/index.ts +0 -14
  28. package/src/components/state-view/types.ts +0 -261
  29. package/src/components/state-view/useStateView.ts +0 -205
  30. package/src/contexts/GraphEditContext.tsx +0 -27
  31. package/src/contexts/TooltipPortalContext.ts +0 -8
  32. package/src/edges/CustomEdge.tsx +0 -402
  33. package/src/edges/GenericEdge.tsx +0 -36
  34. package/src/hooks/usePathBasedEvents.ts +0 -192
  35. package/src/hooks/useSequenceLayout.ts +0 -543
  36. package/src/hooks/useUndoRedo.ts +0 -144
  37. package/src/nodes/CustomNode.tsx +0 -1231
  38. package/src/nodes/GenericNode.tsx +0 -55
  39. package/src/nodes/otel/OtelBoundaryNode.tsx +0 -224
  40. package/src/nodes/otel/OtelEventNode.tsx +0 -225
  41. package/src/nodes/otel/OtelResourceNode.tsx +0 -251
  42. package/src/nodes/otel/OtelScopeNode.tsx +0 -221
  43. package/src/nodes/otel/OtelSpanConventionNode.tsx +0 -295
  44. package/src/nodes/otel/index.ts +0 -23
  45. package/src/nodes/otel/shared/NodeBadges.tsx +0 -295
  46. package/src/nodes/otel/shared/NodeContent.tsx +0 -204
  47. package/src/nodes/otel/shared/index.ts +0 -8
  48. package/src/nodes/otel/shared/types.ts +0 -138
  49. package/src/nodes/otel/shared/useNodeBehavior.ts +0 -114
  50. package/src/stories/Audit/BoundaryNodes.stories.tsx +0 -385
  51. package/src/stories/Audit/CanvasEdgeTypes.stories.tsx +0 -1448
  52. package/src/stories/Audit/CanvasNodeTypes.stories.tsx +0 -1049
  53. package/src/stories/Audit/ColorPriority.stories.tsx +0 -895
  54. package/src/stories/Audit/DiamondBadges.stories.tsx +0 -629
  55. package/src/stories/Audit/NodeDimensionsTesting.stories.tsx +0 -724
  56. package/src/stories/Audit/NodeFieldsAudit.stories.tsx +0 -996
  57. package/src/stories/Audit/NodeFontSizeTesting.stories.tsx +0 -715
  58. package/src/stories/Audit/NodeShapes.stories.tsx +0 -1208
  59. package/src/stories/Audit/WideNodesTesting.stories.tsx +0 -1045
  60. package/src/stories/Components/DashboardRenderer.stories.tsx +0 -263
  61. package/src/stories/Components/GraphRenderer.stories.tsx +0 -3236
  62. package/src/stories/Components/MultiCanvasRenderer.stories.tsx +0 -370
  63. package/src/stories/Components/SequenceDiagram.stories.tsx +0 -255
  64. package/src/stories/Components/StateView.stories.tsx +0 -417
  65. package/src/stories/Components/TraceViewer.stories.tsx +0 -442
  66. package/src/stories/Components/WorkflowSequenceDiagram.stories.tsx +0 -802
  67. package/src/stories/Features/AnimationWorkshop.stories.tsx +0 -727
  68. package/src/stories/Features/ChangeTypeVisual.stories.tsx +0 -67
  69. package/src/stories/Features/EventDrivenAnimations.stories.tsx +0 -513
  70. package/src/stories/Features/MultiConfig.stories.tsx +0 -539
  71. package/src/stories/Layout/ElkEdgeRouting.stories.tsx +0 -539
  72. package/src/stories/Layout/GraphOrientation.stories.tsx +0 -500
  73. package/src/stories/Layout/MultiDirectionalConnections.stories.tsx +0 -352
  74. package/src/stories/Nodes/NodeDefinitionComparison.stories.tsx +0 -560
  75. package/src/stories/Nodes/NodeNameFallbacks.stories.tsx +0 -491
  76. package/src/stories/Nodes/NumericColors.stories.tsx +0 -440
  77. package/src/stories/OTEL/EventNameDisplay.stories.tsx +0 -694
  78. package/src/stories/OTEL/EventNameFallback.stories.tsx +0 -578
  79. package/src/stories/OTEL/OtelComponents.stories.tsx +0 -422
  80. package/src/stories/OTEL/OtelNodeTypesPrototype.stories.tsx +0 -806
  81. package/src/stories/OTEL/RawEventCards.stories.tsx +0 -57
  82. package/src/stories/OTEL/SpanBadges.stories.tsx +0 -840
  83. package/src/stories/OTEL/ValidationEventsCanvas.stories.tsx +0 -209
  84. package/src/stories/RealWorld/BacklogMdCanvases.stories.tsx +0 -721
  85. package/src/stories/RealWorld/FileCitySequence.stories.tsx +0 -516
  86. package/src/stories/RealWorld/RealCanvasFiles.stories.tsx +0 -336
  87. package/src/stories/__traces__/test-run.canvas.json +0 -241
  88. package/src/stories/data/activity-feed-analytics.dashboard.json +0 -300
  89. package/src/stories/data/file-city-images-transformed.otel.canvas.json +0 -295
  90. package/src/stories/data/file-city-workflows.json +0 -269
  91. package/src/stories/data/graph-converter-test-execution.json +0 -443
  92. package/src/stories/data/graph-converter-test.workflow.json +0 -105
  93. package/src/stories/data/graph-converter-validated-execution.json +0 -58
  94. package/src/utils/animationMapping.ts +0 -166
  95. package/src/utils/canvasBounds.ts +0 -146
  96. package/src/utils/graphConverter.ts +0 -148
  97. package/src/utils/iconResolver.tsx +0 -53
  98. package/src/utils/orientationUtils.ts +0 -73
@@ -1,1045 +0,0 @@
1
- import React from 'react';
2
- import type { Meta, StoryObj } from '@storybook/react';
3
- import { GraphRenderer } from '../../components/GraphRenderer';
4
- import type { ExtendedCanvas } from '@principal-ai/subsystems-core';
5
- import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
6
- import type { Theme } from '@principal-ade/industry-theme';
7
-
8
- const meta = {
9
- title: 'Audit/WideNodesTesting',
10
- component: GraphRenderer,
11
- parameters: {
12
- layout: 'fullscreen',
13
- },
14
- tags: ['autodocs'],
15
- } satisfies Meta<typeof GraphRenderer>;
16
-
17
- export default meta;
18
- type Story = StoryObj<typeof meta>;
19
-
20
- /**
21
- * Create theme with 16px base font
22
- */
23
- const theme16px: Theme = {
24
- ...defaultEditorTheme,
25
- fontSizes: [16, 18, 20, 22, 24, 28, 36, 52, 68, 100],
26
- };
27
-
28
- /**
29
- * Large workflow event names for testing
30
- */
31
- const WORKFLOW_EVENTS = [
32
- 'Analysis Started',
33
- 'FileTree Built',
34
- 'Packages Discovered',
35
- 'Canvases Discovered',
36
- 'Executions Discovered',
37
- 'Library Loaded',
38
- 'Discovery Complete',
39
- 'Validation Started',
40
- 'File Parsed',
41
- 'Type Detected',
42
- 'Canvas Validated',
43
- 'Workflow Validated',
44
- 'Execution Validated',
45
- 'Library Validated',
46
- 'Rules Executed',
47
- 'Results Aggregated',
48
- 'Validation Complete',
49
- 'Validation Error',
50
- 'Config Saved',
51
- 'Report Generated',
52
- ];
53
-
54
- /**
55
- * Generate colors based on category
56
- */
57
- const getEventColor = (name: string): string => {
58
- if (name.includes('Started')) return '#22c55e';
59
- if (name.includes('Complete')) return '#22c55e';
60
- if (name.includes('Error')) return '#ef4444';
61
- if (name.includes('Validated')) return '#8b5cf6';
62
- if (name.includes('Discovered')) return '#f59e0b';
63
- return '#3b82f6';
64
- };
65
-
66
- /**
67
- * Main story: 200×75 with 16px font - Large workflow
68
- */
69
- export const WideNodes_200x75_ManyNodes: Story = {
70
- render: () => {
71
- const theme = defaultEditorTheme;
72
-
73
- const canvas: ExtendedCanvas = {
74
- nodes: WORKFLOW_EVENTS.map((event, idx) => ({
75
- id: `event-${idx}`,
76
- type: 'text',
77
- x: 100,
78
- y: 80 + idx * 120,
79
- width: 200,
80
- height: 75,
81
- text: event,
82
- color: getEventColor(event),
83
- pv: {
84
- name: event,
85
- shape: 'roundedRect',
86
- otel: {
87
- kind: 'event',
88
- category: event.includes('Started') || event.includes('Complete') ? 'lifecycle' : 'operation',
89
- },
90
- },
91
- })),
92
- edges: WORKFLOW_EVENTS.slice(0, -1).map((_, idx) => ({
93
- id: `edge-${idx}`,
94
- fromNode: `event-${idx}`,
95
- toNode: `event-${idx + 1}`,
96
- fromSide: 'bottom' as const,
97
- toSide: 'top' as const,
98
- })),
99
- };
100
-
101
- return (
102
- <div style={{ padding: '32px' }}>
103
- <h1 style={{
104
- marginBottom: '16px',
105
- fontSize: theme.fontSizes[7],
106
- color: theme.colors.text,
107
- }}>
108
- Wide Nodes: 200×75 with 16px Font
109
- </h1>
110
- <p style={{
111
- marginBottom: '24px',
112
- fontSize: theme.fontSizes[2],
113
- color: theme.colors.textSecondary,
114
- maxWidth: '1000px',
115
- }}>
116
- Testing wider aspect ratio (200×75) with 16px font size. This shows {WORKFLOW_EVENTS.length} nodes
117
- in a complete validation workflow to see how the design scales.
118
- </p>
119
-
120
- <div style={{
121
- display: 'flex',
122
- gap: '16px',
123
- marginBottom: '24px',
124
- padding: '16px',
125
- backgroundColor: theme.colors.surface,
126
- borderRadius: '8px',
127
- }}>
128
- <div style={{
129
- flex: 1,
130
- padding: '12px',
131
- backgroundColor: theme.colors.backgroundSecondary,
132
- borderRadius: '6px',
133
- }}>
134
- <div style={{ fontSize: theme.fontSizes[0], color: theme.colors.textMuted, marginBottom: '4px' }}>
135
- Dimensions
136
- </div>
137
- <div style={{ fontSize: theme.fontSizes[3], fontFamily: theme.fonts.monospace, color: theme.colors.text }}>
138
- 200 × 75
139
- </div>
140
- </div>
141
- <div style={{
142
- flex: 1,
143
- padding: '12px',
144
- backgroundColor: theme.colors.backgroundSecondary,
145
- borderRadius: '6px',
146
- }}>
147
- <div style={{ fontSize: theme.fontSizes[0], color: theme.colors.textMuted, marginBottom: '4px' }}>
148
- Font Size
149
- </div>
150
- <div style={{ fontSize: theme.fontSizes[3], fontFamily: theme.fonts.monospace, color: theme.colors.text }}>
151
- 16px
152
- </div>
153
- </div>
154
- <div style={{
155
- flex: 1,
156
- padding: '12px',
157
- backgroundColor: theme.colors.backgroundSecondary,
158
- borderRadius: '6px',
159
- }}>
160
- <div style={{ fontSize: theme.fontSizes[0], color: theme.colors.textMuted, marginBottom: '4px' }}>
161
- Aspect Ratio
162
- </div>
163
- <div style={{ fontSize: theme.fontSizes[3], fontFamily: theme.fonts.monospace, color: theme.colors.text }}>
164
- 2.67:1
165
- </div>
166
- </div>
167
- <div style={{
168
- flex: 1,
169
- padding: '12px',
170
- backgroundColor: theme.colors.backgroundSecondary,
171
- borderRadius: '6px',
172
- }}>
173
- <div style={{ fontSize: theme.fontSizes[0], color: theme.colors.textMuted, marginBottom: '4px' }}>
174
- Nodes
175
- </div>
176
- <div style={{ fontSize: theme.fontSizes[3], fontFamily: theme.fonts.monospace, color: theme.colors.text }}>
177
- {WORKFLOW_EVENTS.length}
178
- </div>
179
- </div>
180
- </div>
181
-
182
- <div style={{
183
- backgroundColor: theme.colors.background,
184
- border: `2px solid ${theme.colors.border}`,
185
- borderRadius: '8px',
186
- overflow: 'hidden',
187
- }}>
188
- <ThemeProvider theme={theme16px}>
189
- <GraphRenderer
190
- canvas={canvas}
191
- height={2600}
192
- width="100%"
193
- />
194
- </ThemeProvider>
195
- </div>
196
- </div>
197
- );
198
- },
199
- };
200
-
201
- /**
202
- * Compare different heights with 200px width and 16px font
203
- */
204
- export const HeightComparison_200Width_16pxFont: Story = {
205
- render: () => {
206
- const theme = defaultEditorTheme;
207
-
208
- const heights = [
209
- { label: '200×70 (2.86:1)', height: 70, description: 'Very wide, minimal vertical padding' },
210
- { label: '200×75 (2.67:1)', height: 75, description: 'Wide, compact vertical spacing' },
211
- { label: '200×80 (2.5:1)', height: 80, description: 'Wide, balanced spacing' },
212
- { label: '200×85 (2.35:1)', height: 85, description: 'Wide, more vertical breathing room' },
213
- { label: '200×90 (2.22:1)', height: 90, description: 'Wide, generous vertical spacing' },
214
- ];
215
-
216
- const sampleEvents = [
217
- 'Analysis Started',
218
- 'File Parsed',
219
- 'Canvas Validated',
220
- 'Results Aggregated',
221
- 'Validation Complete',
222
- ];
223
-
224
- return (
225
- <div style={{ padding: '32px' }}>
226
- <h1 style={{
227
- marginBottom: '16px',
228
- fontSize: theme.fontSizes[7],
229
- color: theme.colors.text,
230
- }}>
231
- Height Comparison: 200px Width, 16px Font
232
- </h1>
233
- <p style={{
234
- marginBottom: '32px',
235
- fontSize: theme.fontSizes[2],
236
- color: theme.colors.textSecondary,
237
- }}>
238
- Testing different heights with fixed 200px width and 16px font to find the optimal aspect ratio.
239
- </p>
240
-
241
- {heights.map((config, idx) => {
242
- const canvas: ExtendedCanvas = {
243
- nodes: sampleEvents.map((event, eventIdx) => ({
244
- id: `${idx}-${eventIdx}`,
245
- type: 'text',
246
- x: 100,
247
- y: 80 + eventIdx * (config.height + 30),
248
- width: 200,
249
- height: config.height,
250
- text: event,
251
- color: getEventColor(event),
252
- pv: {
253
- name: event,
254
- shape: 'roundedRect',
255
- },
256
- })),
257
- edges: sampleEvents.slice(0, -1).map((_, eventIdx) => ({
258
- id: `edge-${idx}-${eventIdx}`,
259
- fromNode: `${idx}-${eventIdx}`,
260
- toNode: `${idx}-${eventIdx + 1}`,
261
- fromSide: 'bottom' as const,
262
- toSide: 'top' as const,
263
- })),
264
- };
265
-
266
- return (
267
- <div
268
- key={idx}
269
- style={{
270
- marginBottom: '40px',
271
- padding: '24px',
272
- backgroundColor: theme.colors.surface,
273
- border: `1px solid ${theme.colors.border}`,
274
- borderRadius: '8px',
275
- }}
276
- >
277
- <div style={{
278
- display: 'flex',
279
- justifyContent: 'space-between',
280
- alignItems: 'center',
281
- marginBottom: '16px',
282
- }}>
283
- <div>
284
- <h3 style={{
285
- fontSize: theme.fontSizes[3],
286
- fontWeight: theme.fontWeights.semibold,
287
- color: theme.colors.text,
288
- marginBottom: '4px',
289
- }}>
290
- {config.label}
291
- </h3>
292
- <p style={{
293
- fontSize: theme.fontSizes[1],
294
- color: theme.colors.textSecondary,
295
- }}>
296
- {config.description}
297
- </p>
298
- </div>
299
- {config.height === 75 && (
300
- <div style={{
301
- padding: '6px 12px',
302
- backgroundColor: theme.colors.primary,
303
- color: theme.colors.background,
304
- borderRadius: '4px',
305
- fontSize: theme.fontSizes[0],
306
- fontWeight: theme.fontWeights.bold,
307
- }}>
308
- ⭐ Recommended
309
- </div>
310
- )}
311
- </div>
312
-
313
- <div style={{
314
- backgroundColor: theme.colors.background,
315
- border: `2px solid ${config.height === 75 ? theme.colors.primary : theme.colors.border}`,
316
- borderRadius: '6px',
317
- overflow: 'hidden',
318
- }}>
319
- <ThemeProvider theme={theme16px}>
320
- <GraphRenderer
321
- canvas={canvas}
322
- height={700}
323
- width="100%"
324
- />
325
- </ThemeProvider>
326
- </div>
327
- </div>
328
- );
329
- })}
330
- </div>
331
- );
332
- },
333
- };
334
-
335
- /**
336
- * Side-by-side comparison of current vs proposed
337
- */
338
- export const CurrentVsProposed: Story = {
339
- render: () => {
340
- const theme = defaultEditorTheme;
341
- const theme12px = defaultEditorTheme;
342
-
343
- const testEvents = WORKFLOW_EVENTS.slice(0, 12); // First 12 events
344
-
345
- const configs = [
346
- {
347
- title: 'Current Standard',
348
- description: '200×100 with 12px font',
349
- width: 200,
350
- height: 100,
351
- theme: theme12px,
352
- color: theme.colors.textSecondary,
353
- },
354
- {
355
- title: 'Proposed Wide',
356
- description: '200×75 with 16px font',
357
- width: 200,
358
- height: 75,
359
- theme: theme16px,
360
- color: theme.colors.primary,
361
- },
362
- ];
363
-
364
- return (
365
- <div style={{ padding: '32px' }}>
366
- <h1 style={{
367
- marginBottom: '16px',
368
- fontSize: theme.fontSizes[7],
369
- color: theme.colors.text,
370
- }}>
371
- Current vs Proposed Wide Design
372
- </h1>
373
- <p style={{
374
- marginBottom: '32px',
375
- fontSize: theme.fontSizes[2],
376
- color: theme.colors.textSecondary,
377
- maxWidth: '1000px',
378
- }}>
379
- Direct comparison between current standard (200×100, 12px) and proposed wide design (200×75, 16px).
380
- Notice the improved readability with larger font while maintaining compact vertical space.
381
- </p>
382
-
383
- <div style={{
384
- display: 'grid',
385
- gridTemplateColumns: '1fr 1fr',
386
- gap: '32px',
387
- }}>
388
- {configs.map((config, idx) => {
389
- const canvas: ExtendedCanvas = {
390
- nodes: testEvents.map((event, eventIdx) => ({
391
- id: `${idx}-${eventIdx}`,
392
- type: 'text',
393
- x: 100,
394
- y: 80 + eventIdx * (config.height + 30),
395
- width: config.width,
396
- height: config.height,
397
- text: event,
398
- color: getEventColor(event),
399
- pv: {
400
- name: event,
401
- shape: 'roundedRect',
402
- otel: {
403
- kind: 'event',
404
- category: event.includes('Started') || event.includes('Complete') ? 'lifecycle' : 'operation',
405
- },
406
- },
407
- })),
408
- edges: testEvents.slice(0, -1).map((_, eventIdx) => ({
409
- id: `edge-${idx}-${eventIdx}`,
410
- fromNode: `${idx}-${eventIdx}`,
411
- toNode: `${idx}-${eventIdx + 1}`,
412
- fromSide: 'bottom' as const,
413
- toSide: 'top' as const,
414
- })),
415
- };
416
-
417
- return (
418
- <div key={idx}>
419
- <div style={{
420
- marginBottom: '16px',
421
- padding: '16px',
422
- backgroundColor: theme.colors.surface,
423
- borderRadius: '8px',
424
- border: `2px solid ${config.color}`,
425
- }}>
426
- <h3 style={{
427
- fontSize: theme.fontSizes[3],
428
- fontWeight: theme.fontWeights.semibold,
429
- color: config.color,
430
- marginBottom: '4px',
431
- }}>
432
- {config.title}
433
- </h3>
434
- <p style={{
435
- fontSize: theme.fontSizes[1],
436
- color: theme.colors.textSecondary,
437
- marginBottom: '12px',
438
- }}>
439
- {config.description}
440
- </p>
441
- <div style={{
442
- display: 'flex',
443
- gap: '16px',
444
- fontSize: theme.fontSizes[1],
445
- fontFamily: theme.fonts.monospace,
446
- }}>
447
- <div>
448
- <span style={{ color: theme.colors.textMuted }}>Size:</span>{' '}
449
- <span style={{ color: theme.colors.text }}>{config.width}×{config.height}</span>
450
- </div>
451
- <div>
452
- <span style={{ color: theme.colors.textMuted }}>Font:</span>{' '}
453
- <span style={{ color: theme.colors.text }}>{config.theme.fontSizes[0]}px</span>
454
- </div>
455
- <div>
456
- <span style={{ color: theme.colors.textMuted }}>Ratio:</span>{' '}
457
- <span style={{ color: theme.colors.text }}>{(config.width / config.height).toFixed(2)}:1</span>
458
- </div>
459
- </div>
460
- </div>
461
-
462
- <div style={{
463
- backgroundColor: theme.colors.background,
464
- border: `2px solid ${config.color}`,
465
- borderRadius: '8px',
466
- overflow: 'hidden',
467
- }}>
468
- <ThemeProvider theme={config.theme}>
469
- <GraphRenderer
470
- canvas={canvas}
471
- height={1700}
472
- width="100%"
473
- />
474
- </ThemeProvider>
475
- </div>
476
- </div>
477
- );
478
- })}
479
- </div>
480
-
481
- <div style={{
482
- marginTop: '40px',
483
- padding: '24px',
484
- backgroundColor: theme.colors.backgroundSecondary,
485
- border: `2px solid ${theme.colors.primary}`,
486
- borderRadius: '8px',
487
- }}>
488
- <h3 style={{
489
- marginBottom: '16px',
490
- fontSize: theme.fontSizes[4],
491
- color: theme.colors.text,
492
- }}>
493
- Key Differences
494
- </h3>
495
- <div style={{
496
- display: 'grid',
497
- gridTemplateColumns: '1fr 1fr',
498
- gap: '24px',
499
- fontSize: theme.fontSizes[1],
500
- color: theme.colors.text,
501
- lineHeight: 1.8,
502
- }}>
503
- <div>
504
- <strong style={{ color: theme.colors.textSecondary }}>Current (200×100, 12px)</strong>
505
- <ul style={{ paddingLeft: '20px', marginTop: '8px', color: theme.colors.textSecondary }}>
506
- <li>More vertical space per node</li>
507
- <li>Smaller font requires good vision</li>
508
- <li>Square-ish aspect ratio (2:1)</li>
509
- <li>More vertical scrolling needed</li>
510
- </ul>
511
- </div>
512
- <div>
513
- <strong style={{ color: theme.colors.primary }}>Proposed (200×75, 16px)</strong>
514
- <ul style={{ paddingLeft: '20px', marginTop: '8px', color: theme.colors.text }}>
515
- <li>✨ 33% larger font for better readability</li>
516
- <li>✨ 25% less vertical space (more compact)</li>
517
- <li>✨ Wider aspect ratio (2.67:1)</li>
518
- <li>✨ Fits more nodes on screen</li>
519
- </ul>
520
- </div>
521
- </div>
522
- </div>
523
- </div>
524
- );
525
- },
526
- };
527
-
528
- /**
529
- * Ultra-wide aspect ratios
530
- */
531
- export const UltraWideRatios: Story = {
532
- render: () => {
533
- const theme = defaultEditorTheme;
534
-
535
- const configs = [
536
- { label: '220×70 (3.14:1)', width: 220, height: 70 },
537
- { label: '240×75 (3.2:1)', width: 240, height: 75 },
538
- { label: '200×65 (3.08:1)', width: 200, height: 65 },
539
- { label: '200×75 (2.67:1) ⭐', width: 200, height: 75 },
540
- ];
541
-
542
- const sampleEvents = [
543
- 'Analysis Started',
544
- 'Packages Discovered',
545
- 'Canvas Validated',
546
- 'Validation Complete',
547
- ];
548
-
549
- return (
550
- <div style={{ padding: '32px' }}>
551
- <h1 style={{
552
- marginBottom: '16px',
553
- fontSize: theme.fontSizes[7],
554
- color: theme.colors.text,
555
- }}>
556
- Ultra-Wide Aspect Ratios (16px Font)
557
- </h1>
558
- <p style={{
559
- marginBottom: '32px',
560
- fontSize: theme.fontSizes[2],
561
- color: theme.colors.textSecondary,
562
- }}>
563
- Exploring very wide aspect ratios (2.67:1 to 3.2:1) with 16px font. These create a more horizontal,
564
- streamlined appearance.
565
- </p>
566
-
567
- <div style={{
568
- display: 'grid',
569
- gridTemplateColumns: 'repeat(2, 1fr)',
570
- gap: '32px',
571
- }}>
572
- {configs.map((config, idx) => {
573
- const canvas: ExtendedCanvas = {
574
- nodes: sampleEvents.map((event, eventIdx) => ({
575
- id: `${idx}-${eventIdx}`,
576
- type: 'text',
577
- x: 100,
578
- y: 80 + eventIdx * (config.height + 30),
579
- width: config.width,
580
- height: config.height,
581
- text: event,
582
- color: getEventColor(event),
583
- pv: {
584
- name: event,
585
- shape: 'roundedRect',
586
- },
587
- })),
588
- edges: [],
589
- };
590
-
591
- return (
592
- <div
593
- key={idx}
594
- style={{
595
- padding: '20px',
596
- backgroundColor: theme.colors.surface,
597
- border: `1px solid ${theme.colors.border}`,
598
- borderRadius: '8px',
599
- }}
600
- >
601
- <h3 style={{
602
- fontSize: theme.fontSizes[2],
603
- fontWeight: theme.fontWeights.semibold,
604
- color: theme.colors.text,
605
- marginBottom: '12px',
606
- }}>
607
- {config.label}
608
- </h3>
609
-
610
- <div style={{
611
- backgroundColor: theme.colors.background,
612
- border: `2px solid ${theme.colors.border}`,
613
- borderRadius: '6px',
614
- overflow: 'hidden',
615
- }}>
616
- <ThemeProvider theme={theme16px}>
617
- <GraphRenderer
618
- canvas={canvas}
619
- height={500}
620
- width="100%"
621
- />
622
- </ThemeProvider>
623
- </div>
624
- </div>
625
- );
626
- })}
627
- </div>
628
- </div>
629
- );
630
- },
631
- };
632
-
633
- /**
634
- * Compare 200×90 specifically against other options
635
- */
636
- export const Compare_200x90: Story = {
637
- render: () => {
638
- const theme = defaultEditorTheme;
639
-
640
- const configs = [
641
- {
642
- title: 'Current Standard',
643
- description: '200×100 with 12px font',
644
- width: 200,
645
- height: 100,
646
- theme: defaultEditorTheme,
647
- ratio: '2:1',
648
- },
649
- {
650
- title: 'Proposed 200×90',
651
- description: '200×90 with 16px font',
652
- width: 200,
653
- height: 90,
654
- theme: theme16px,
655
- ratio: '2.22:1',
656
- highlight: true,
657
- },
658
- {
659
- title: 'Ultra-Wide Option',
660
- description: '200×75 with 16px font',
661
- width: 200,
662
- height: 75,
663
- theme: theme16px,
664
- ratio: '2.67:1',
665
- },
666
- ];
667
-
668
- const sampleEvents = WORKFLOW_EVENTS.slice(0, 10);
669
-
670
- return (
671
- <div style={{ padding: '32px' }}>
672
- <h1 style={{
673
- marginBottom: '16px',
674
- fontSize: theme.fontSizes[7],
675
- color: theme.colors.text,
676
- }}>
677
- 200×90 Comparison
678
- </h1>
679
- <p style={{
680
- marginBottom: '32px',
681
- fontSize: theme.fontSizes[2],
682
- color: theme.colors.textSecondary,
683
- maxWidth: '1000px',
684
- }}>
685
- Direct comparison of 200×90 (2.22:1 aspect ratio) against current standard and ultra-wide option.
686
- The 200×90 option balances improved readability (16px font) with generous vertical spacing.
687
- </p>
688
-
689
- <div style={{
690
- display: 'grid',
691
- gridTemplateColumns: 'repeat(3, 1fr)',
692
- gap: '24px',
693
- }}>
694
- {configs.map((config, idx) => {
695
- const canvas: ExtendedCanvas = {
696
- nodes: sampleEvents.map((event, eventIdx) => ({
697
- id: `${idx}-${eventIdx}`,
698
- type: 'text',
699
- x: 100,
700
- y: 80 + eventIdx * (config.height + 30),
701
- width: config.width,
702
- height: config.height,
703
- text: event,
704
- color: getEventColor(event),
705
- pv: {
706
- name: event,
707
- shape: 'roundedRect',
708
- otel: {
709
- kind: 'event',
710
- category: event.includes('Started') || event.includes('Complete') ? 'lifecycle' : 'operation',
711
- },
712
- },
713
- })),
714
- edges: sampleEvents.slice(0, -1).map((_, eventIdx) => ({
715
- id: `edge-${idx}-${eventIdx}`,
716
- fromNode: `${idx}-${eventIdx}`,
717
- toNode: `${idx}-${eventIdx + 1}`,
718
- fromSide: 'bottom' as const,
719
- toSide: 'top' as const,
720
- })),
721
- };
722
-
723
- return (
724
- <div key={idx}>
725
- <div style={{
726
- marginBottom: '16px',
727
- padding: '16px',
728
- backgroundColor: config.highlight ? theme.colors.primary : theme.colors.surface,
729
- borderRadius: '8px',
730
- border: `2px solid ${config.highlight ? theme.colors.primary : theme.colors.border}`,
731
- }}>
732
- <div style={{
733
- display: 'flex',
734
- justifyContent: 'space-between',
735
- alignItems: 'flex-start',
736
- marginBottom: '8px',
737
- }}>
738
- <h3 style={{
739
- fontSize: theme.fontSizes[2],
740
- fontWeight: theme.fontWeights.semibold,
741
- color: config.highlight ? theme.colors.background : theme.colors.text,
742
- }}>
743
- {config.title}
744
- </h3>
745
- {config.highlight && (
746
- <div style={{
747
- padding: '2px 6px',
748
- backgroundColor: theme.colors.background,
749
- color: theme.colors.primary,
750
- borderRadius: '4px',
751
- fontSize: theme.fontSizes[0],
752
- fontWeight: theme.fontWeights.bold,
753
- }}>
754
- ⭐ Testing
755
- </div>
756
- )}
757
- </div>
758
- <p style={{
759
- fontSize: theme.fontSizes[1],
760
- color: config.highlight ? theme.colors.background : theme.colors.textSecondary,
761
- marginBottom: '12px',
762
- }}>
763
- {config.description}
764
- </p>
765
- <div style={{
766
- display: 'flex',
767
- gap: '12px',
768
- fontSize: theme.fontSizes[0],
769
- fontFamily: theme.fonts.monospace,
770
- color: config.highlight ? theme.colors.background : theme.colors.text,
771
- }}>
772
- <div>Ratio: {config.ratio}</div>
773
- <div>•</div>
774
- <div>Font: {config.theme.fontSizes[0]}px</div>
775
- </div>
776
- </div>
777
-
778
- <div style={{
779
- backgroundColor: theme.colors.background,
780
- border: `3px solid ${config.highlight ? theme.colors.primary : theme.colors.border}`,
781
- borderRadius: '8px',
782
- overflow: 'hidden',
783
- }}>
784
- <ThemeProvider theme={config.theme}>
785
- <GraphRenderer
786
- canvas={canvas}
787
- height={1400}
788
- width="100%"
789
- />
790
- </ThemeProvider>
791
- </div>
792
- </div>
793
- );
794
- })}
795
- </div>
796
-
797
- <div style={{
798
- marginTop: '40px',
799
- padding: '24px',
800
- backgroundColor: theme.colors.surface,
801
- border: `2px solid ${theme.colors.primary}`,
802
- borderRadius: '8px',
803
- }}>
804
- <h3 style={{
805
- marginBottom: '16px',
806
- fontSize: theme.fontSizes[4],
807
- color: theme.colors.text,
808
- }}>
809
- Why 200×90 Works Well
810
- </h3>
811
- <div style={{
812
- display: 'grid',
813
- gridTemplateColumns: '1fr 1fr',
814
- gap: '24px',
815
- fontSize: theme.fontSizes[1],
816
- lineHeight: 1.8,
817
- }}>
818
- <div>
819
- <strong style={{ color: theme.colors.primary }}>vs. Current (200×100, 12px)</strong>
820
- <ul style={{ paddingLeft: '20px', marginTop: '8px', color: theme.colors.text }}>
821
- <li>✨ 33% larger font (12px → 16px)</li>
822
- <li>✨ 10% less vertical space per node</li>
823
- <li>✨ Better readability for longer event names</li>
824
- <li>✨ More modern, accessible design</li>
825
- </ul>
826
- </div>
827
- <div>
828
- <strong style={{ color: theme.colors.primary }}>vs. Ultra-Wide (200×75, 16px)</strong>
829
- <ul style={{ paddingLeft: '20px', marginTop: '8px', color: theme.colors.text }}>
830
- <li>✨ 20% more vertical breathing room</li>
831
- <li>✨ Less cramped appearance</li>
832
- <li>✨ Accommodates badges/states better</li>
833
- <li>✨ More balanced aspect ratio (2.22:1 vs 2.67:1)</li>
834
- </ul>
835
- </div>
836
- </div>
837
- </div>
838
- </div>
839
- );
840
- },
841
- };
842
-
843
- /**
844
- * Dense workflow - many nodes on one screen
845
- */
846
- export const DenseWorkflowView: Story = {
847
- render: () => {
848
- const theme = defaultEditorTheme;
849
-
850
- // Create a branching workflow with many nodes
851
- const canvas: ExtendedCanvas = {
852
- nodes: [
853
- // Main flow
854
- ...WORKFLOW_EVENTS.slice(0, 10).map((event, idx) => ({
855
- id: `main-${idx}`,
856
- type: 'text',
857
- x: 100,
858
- y: 80 + idx * 140,
859
- width: 200,
860
- height: 90,
861
- text: event,
862
- color: getEventColor(event),
863
- pv: {
864
- name: event,
865
- shape: 'roundedRect',
866
- otel: { kind: 'event' as const, category: 'operation' as const },
867
- },
868
- })),
869
- // Branch 1
870
- ...['Config Loaded', 'Settings Validated', 'Plugins Initialized'].map((event, idx) => ({
871
- id: `branch1-${idx}`,
872
- type: 'text',
873
- x: 400,
874
- y: 220 + idx * 140,
875
- width: 200,
876
- height: 90,
877
- text: event,
878
- color: '#8b5cf6',
879
- pv: {
880
- name: event,
881
- shape: 'roundedRect',
882
- },
883
- })),
884
- // Branch 2
885
- ...['Cache Checked', 'Cache Hit', 'Data Loaded'].map((event, idx) => ({
886
- id: `branch2-${idx}`,
887
- type: 'text',
888
- x: 700,
889
- y: 220 + idx * 140,
890
- width: 200,
891
- height: 90,
892
- text: event,
893
- color: '#f59e0b',
894
- pv: {
895
- name: event,
896
- shape: 'roundedRect',
897
- },
898
- })),
899
- // Final nodes
900
- ...['Merge Results', 'Final Validation', 'Complete'].map((event, idx) => ({
901
- id: `final-${idx}`,
902
- type: 'text',
903
- x: 400,
904
- y: 780 + idx * 140,
905
- width: 200,
906
- height: 90,
907
- text: event,
908
- color: getEventColor(event),
909
- pv: {
910
- name: event,
911
- shape: 'roundedRect',
912
- },
913
- })),
914
- ],
915
- edges: [
916
- // Main flow edges
917
- ...Array.from({ length: 9 }, (_, i) => ({
918
- id: `main-edge-${i}`,
919
- fromNode: `main-${i}`,
920
- toNode: `main-${i + 1}`,
921
- fromSide: 'bottom' as const,
922
- toSide: 'top' as const,
923
- })),
924
- // Branch edges
925
- { id: 'to-branch1', fromNode: 'main-2', toNode: 'branch1-0', fromSide: 'right' as const, toSide: 'left' as const },
926
- { id: 'branch1-1', fromNode: 'branch1-0', toNode: 'branch1-1', fromSide: 'bottom' as const, toSide: 'top' as const },
927
- { id: 'branch1-2', fromNode: 'branch1-1', toNode: 'branch1-2', fromSide: 'bottom' as const, toSide: 'top' as const },
928
- { id: 'to-branch2', fromNode: 'main-2', toNode: 'branch2-0', fromSide: 'right' as const, toSide: 'left' as const },
929
- { id: 'branch2-1', fromNode: 'branch2-0', toNode: 'branch2-1', fromSide: 'bottom' as const, toSide: 'top' as const },
930
- { id: 'branch2-2', fromNode: 'branch2-1', toNode: 'branch2-2', fromSide: 'bottom' as const, toSide: 'top' as const },
931
- // Merge edges
932
- { id: 'to-merge', fromNode: 'main-5', toNode: 'final-0', fromSide: 'right' as const, toSide: 'left' as const },
933
- { id: 'branch1-merge', fromNode: 'branch1-2', toNode: 'final-0', fromSide: 'bottom' as const, toSide: 'left' as const },
934
- { id: 'branch2-merge', fromNode: 'branch2-2', toNode: 'final-0', fromSide: 'bottom' as const, toSide: 'right' as const },
935
- { id: 'final-1', fromNode: 'final-0', toNode: 'final-1', fromSide: 'bottom' as const, toSide: 'top' as const },
936
- { id: 'final-2', fromNode: 'final-1', toNode: 'final-2', fromSide: 'bottom' as const, toSide: 'top' as const },
937
- ],
938
- };
939
-
940
- const totalNodes = canvas.nodes.length;
941
-
942
- return (
943
- <div style={{ padding: '32px' }}>
944
- <h1 style={{
945
- marginBottom: '16px',
946
- fontSize: theme.fontSizes[7],
947
- color: theme.colors.text,
948
- }}>
949
- Dense Workflow: {totalNodes} Nodes
950
- </h1>
951
- <p style={{
952
- marginBottom: '24px',
953
- fontSize: theme.fontSizes[2],
954
- color: theme.colors.textSecondary,
955
- maxWidth: '1000px',
956
- }}>
957
- Complex branching workflow with {totalNodes} nodes using 200×90 dimensions and 16px font.
958
- This tests how the balanced aspect ratio handles a realistic, dense workflow with multiple branches.
959
- </p>
960
-
961
- <div style={{
962
- marginBottom: '24px',
963
- padding: '20px',
964
- backgroundColor: theme.colors.surface,
965
- borderRadius: '8px',
966
- border: `2px solid ${theme.colors.primary}`,
967
- }}>
968
- <div style={{
969
- display: 'grid',
970
- gridTemplateColumns: 'repeat(4, 1fr)',
971
- gap: '16px',
972
- }}>
973
- <div>
974
- <div style={{ fontSize: theme.fontSizes[0], color: theme.colors.textMuted }}>Total Nodes</div>
975
- <div style={{ fontSize: theme.fontSizes[4], fontFamily: theme.fonts.monospace, color: theme.colors.text }}>
976
- {totalNodes}
977
- </div>
978
- </div>
979
- <div>
980
- <div style={{ fontSize: theme.fontSizes[0], color: theme.colors.textMuted }}>Node Size</div>
981
- <div style={{ fontSize: theme.fontSizes[4], fontFamily: theme.fonts.monospace, color: theme.colors.text }}>
982
- 200×90
983
- </div>
984
- </div>
985
- <div>
986
- <div style={{ fontSize: theme.fontSizes[0], color: theme.colors.textMuted }}>Font Size</div>
987
- <div style={{ fontSize: theme.fontSizes[4], fontFamily: theme.fonts.monospace, color: theme.colors.text }}>
988
- 16px
989
- </div>
990
- </div>
991
- <div>
992
- <div style={{ fontSize: theme.fontSizes[0], color: theme.colors.textMuted }}>Branches</div>
993
- <div style={{ fontSize: theme.fontSizes[4], fontFamily: theme.fonts.monospace, color: theme.colors.text }}>
994
- 3
995
- </div>
996
- </div>
997
- </div>
998
- </div>
999
-
1000
- <div style={{
1001
- backgroundColor: theme.colors.background,
1002
- border: `2px solid ${theme.colors.border}`,
1003
- borderRadius: '8px',
1004
- overflow: 'hidden',
1005
- }}>
1006
- <ThemeProvider theme={theme16px}>
1007
- <GraphRenderer
1008
- canvas={canvas}
1009
- height={1600}
1010
- width="100%"
1011
- />
1012
- </ThemeProvider>
1013
- </div>
1014
-
1015
- <div style={{
1016
- marginTop: '32px',
1017
- padding: '20px',
1018
- backgroundColor: theme.colors.surface,
1019
- borderRadius: '8px',
1020
- }}>
1021
- <h3 style={{
1022
- marginBottom: '12px',
1023
- fontSize: theme.fontSizes[3],
1024
- color: theme.colors.text,
1025
- }}>
1026
- Benefits of 200×90 with 16px Font
1027
- </h3>
1028
- <ul style={{
1029
- fontSize: theme.fontSizes[1],
1030
- color: theme.colors.textSecondary,
1031
- lineHeight: 1.8,
1032
- paddingLeft: '20px',
1033
- }}>
1034
- <li>Balanced aspect ratio (2.22:1) - wider than traditional but not extreme</li>
1035
- <li>Generous vertical spacing accommodates 16px font comfortably</li>
1036
- <li>10% less vertical space than current 200×100 while improving readability</li>
1037
- <li>16px font remains highly readable even with many nodes</li>
1038
- <li>Streamlined appearance reduces visual clutter</li>
1039
- <li>Better use of modern widescreen displays</li>
1040
- </ul>
1041
- </div>
1042
- </div>
1043
- );
1044
- },
1045
- };