@principal-ai/principal-view-react 0.6.10 → 0.6.12

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 (66) hide show
  1. package/README.md +2 -5
  2. package/dist/components/ConfigurationSelector.js +4 -2
  3. package/dist/components/ConfigurationSelector.js.map +1 -1
  4. package/dist/components/EdgeInfoPanel.d.ts.map +1 -1
  5. package/dist/components/EdgeInfoPanel.js +43 -13
  6. package/dist/components/EdgeInfoPanel.js.map +1 -1
  7. package/dist/components/GraphRenderer.d.ts.map +1 -1
  8. package/dist/components/GraphRenderer.js +133 -83
  9. package/dist/components/GraphRenderer.js.map +1 -1
  10. package/dist/components/NodeInfoPanel.d.ts.map +1 -1
  11. package/dist/components/NodeInfoPanel.js +143 -45
  12. package/dist/components/NodeInfoPanel.js.map +1 -1
  13. package/dist/edges/CustomEdge.d.ts +1 -0
  14. package/dist/edges/CustomEdge.d.ts.map +1 -1
  15. package/dist/edges/CustomEdge.js +18 -4
  16. package/dist/edges/CustomEdge.js.map +1 -1
  17. package/dist/edges/GenericEdge.d.ts.map +1 -1
  18. package/dist/edges/GenericEdge.js +2 -2
  19. package/dist/edges/GenericEdge.js.map +1 -1
  20. package/dist/hooks/usePathBasedEvents.d.ts +1 -1
  21. package/dist/hooks/usePathBasedEvents.d.ts.map +1 -1
  22. package/dist/hooks/usePathBasedEvents.js +9 -9
  23. package/dist/hooks/usePathBasedEvents.js.map +1 -1
  24. package/dist/index.d.ts +2 -2
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/nodes/CustomNode.d.ts.map +1 -1
  28. package/dist/nodes/CustomNode.js +62 -45
  29. package/dist/nodes/CustomNode.js.map +1 -1
  30. package/dist/nodes/GenericNode.d.ts.map +1 -1
  31. package/dist/nodes/GenericNode.js.map +1 -1
  32. package/dist/utils/animationMapping.d.ts.map +1 -1
  33. package/dist/utils/animationMapping.js +12 -12
  34. package/dist/utils/animationMapping.js.map +1 -1
  35. package/dist/utils/graphConverter.d.ts.map +1 -1
  36. package/dist/utils/graphConverter.js +47 -19
  37. package/dist/utils/graphConverter.js.map +1 -1
  38. package/dist/utils/iconResolver.d.ts.map +1 -1
  39. package/dist/utils/iconResolver.js +1 -1
  40. package/dist/utils/iconResolver.js.map +1 -1
  41. package/package.json +2 -1
  42. package/src/components/ConfigurationSelector.tsx +5 -5
  43. package/src/components/EdgeInfoPanel.tsx +79 -37
  44. package/src/components/GraphRenderer.tsx +526 -365
  45. package/src/components/NodeInfoPanel.tsx +209 -86
  46. package/src/edges/CustomEdge.tsx +40 -7
  47. package/src/edges/GenericEdge.tsx +2 -6
  48. package/src/hooks/usePathBasedEvents.ts +54 -45
  49. package/src/index.ts +11 -2
  50. package/src/nodes/CustomNode.tsx +137 -109
  51. package/src/nodes/GenericNode.tsx +4 -3
  52. package/src/stories/AnimationWorkshop.stories.tsx +131 -12
  53. package/src/stories/CanvasEdgeTypes.stories.tsx +980 -0
  54. package/src/stories/CanvasNodeTypes.stories.tsx +898 -0
  55. package/src/stories/ColorPriority.stories.tsx +20 -10
  56. package/src/stories/EventDrivenAnimations.stories.tsx +8 -0
  57. package/src/stories/EventLog.stories.tsx +1 -1
  58. package/src/stories/GraphRenderer.stories.tsx +23 -10
  59. package/src/stories/IndustryThemes.stories.tsx +481 -0
  60. package/src/stories/MultiConfig.stories.tsx +8 -0
  61. package/src/stories/MultiDirectionalConnections.stories.tsx +8 -0
  62. package/src/stories/NodeFieldsAudit.stories.tsx +124 -37
  63. package/src/stories/NodeShapes.stories.tsx +73 -59
  64. package/src/utils/animationMapping.ts +19 -23
  65. package/src/utils/graphConverter.ts +61 -21
  66. package/src/utils/iconResolver.tsx +5 -1
@@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { GraphRenderer } from '../components/GraphRenderer';
4
4
  import type { ExtendedCanvas, GraphEvent } from '@principal-ai/principal-view-core';
5
+ import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
5
6
 
6
7
  // Helper component that sets initial node states via events
7
8
  const GraphWithInitialStates: React.FC<{
@@ -15,13 +16,15 @@ const GraphWithInitialStates: React.FC<{
15
16
 
16
17
  useEffect(() => {
17
18
  if (initialStates) {
18
- const stateEvents: GraphEvent[] = Object.entries(initialStates).map(([nodeId, newState], idx) => ({
19
- id: `init-state-${idx}`,
20
- type: 'state_changed',
21
- timestamp: Date.now(),
22
- category: 'state' as const,
23
- payload: { nodeId, newState },
24
- }));
19
+ const stateEvents: GraphEvent[] = Object.entries(initialStates).map(
20
+ ([nodeId, newState], idx) => ({
21
+ id: `init-state-${idx}`,
22
+ type: 'state_changed',
23
+ timestamp: Date.now(),
24
+ category: 'state' as const,
25
+ payload: { nodeId, newState },
26
+ })
27
+ );
25
28
  setEvents(stateEvents);
26
29
  }
27
30
  }, []);
@@ -44,6 +47,13 @@ const meta = {
44
47
  layout: 'centered',
45
48
  },
46
49
  tags: ['autodocs'],
50
+ decorators: [
51
+ (Story) => (
52
+ <ThemeProvider theme={defaultEditorTheme}>
53
+ <Story />
54
+ </ThemeProvider>
55
+ ),
56
+ ],
47
57
  } satisfies Meta<typeof GraphRenderer>;
48
58
 
49
59
  export default meta;
@@ -425,7 +435,7 @@ const iconPriorityCanvas: ExtendedCanvas = {
425
435
  pv: {
426
436
  nodeType: 'icon-type-demo',
427
437
  shape: 'rectangle',
428
- icon: 'settings',
438
+ icon: 'Settings',
429
439
  },
430
440
  },
431
441
  // 2. State icon (when in a state)
@@ -441,9 +451,9 @@ const iconPriorityCanvas: ExtendedCanvas = {
441
451
  pv: {
442
452
  nodeType: 'icon-state-demo',
443
453
  shape: 'rectangle',
444
- icon: 'settings', // Type icon - should be overridden
454
+ icon: 'Settings', // Type icon - should be overridden
445
455
  states: {
446
- complete: { label: 'Complete', color: '#00FF00', icon: 'check' },
456
+ complete: { label: 'Complete', color: '#00FF00', icon: 'Check' },
447
457
  },
448
458
  },
449
459
  },
@@ -3,6 +3,7 @@ import { GraphRenderer } from '../components/GraphRenderer';
3
3
  import type { GraphEvent, ExtendedCanvas } from '@principal-ai/principal-view-core';
4
4
  import { useState, useEffect } from 'react';
5
5
  import React from 'react';
6
+ import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
6
7
 
7
8
  const meta = {
8
9
  title: 'Workshop/Event-Driven Animations',
@@ -11,6 +12,13 @@ const meta = {
11
12
  layout: 'fullscreen',
12
13
  },
13
14
  tags: ['autodocs'],
15
+ decorators: [
16
+ (Story) => (
17
+ <ThemeProvider theme={defaultEditorTheme}>
18
+ <Story />
19
+ </ThemeProvider>
20
+ ),
21
+ ],
14
22
  } satisfies Meta<typeof GraphRenderer>;
15
23
 
16
24
  export default meta;
@@ -133,7 +133,7 @@ export const ManyEvents: Story = {
133
133
  ...sampleEvents,
134
134
  ...Array.from({ length: 20 }, (_, i) => ({
135
135
  id: `evt-gen-${i}`,
136
- timestamp: Date.now() - (i * 500),
136
+ timestamp: Date.now() - i * 500,
137
137
  type: 'node_updated',
138
138
  category: 'node' as const,
139
139
  operation: 'update' as const,
@@ -3,6 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { GraphRenderer } from '../components/GraphRenderer';
4
4
  import type { GraphRendererHandle, PendingChanges } from '../components/GraphRenderer';
5
5
  import type { ExtendedCanvas } from '@principal-ai/principal-view-core';
6
+ import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
6
7
 
7
8
  const meta = {
8
9
  title: 'Components/GraphRenderer',
@@ -11,6 +12,13 @@ const meta = {
11
12
  layout: 'centered',
12
13
  },
13
14
  tags: ['autodocs'],
15
+ decorators: [
16
+ (Story) => (
17
+ <ThemeProvider theme={defaultEditorTheme}>
18
+ <Story />
19
+ </ThemeProvider>
20
+ ),
21
+ ],
14
22
  } satisfies Meta<typeof GraphRenderer>;
15
23
 
16
24
  export default meta;
@@ -283,11 +291,11 @@ const serviceArchitectureCanvas: ExtendedCanvas = {
283
291
  pv: {
284
292
  nodeType: 'client',
285
293
  shape: 'circle',
286
- icon: 'user',
294
+ icon: 'User',
287
295
  states: {
288
- idle: { color: '#94a3b8', icon: 'user' },
289
- connected: { color: '#22c55e', icon: 'user-check' },
290
- error: { color: '#ef4444', icon: 'user-x' },
296
+ idle: { color: '#94a3b8', icon: 'User' },
297
+ connected: { color: '#22c55e', icon: 'UserCheck' },
298
+ error: { color: '#ef4444', icon: 'UserX' },
291
299
  },
292
300
  },
293
301
  },
@@ -303,7 +311,7 @@ const serviceArchitectureCanvas: ExtendedCanvas = {
303
311
  pv: {
304
312
  nodeType: 'api-server',
305
313
  shape: 'rectangle',
306
- icon: 'server',
314
+ icon: 'Server',
307
315
  states: {
308
316
  idle: { color: '#94a3b8' },
309
317
  processing: { color: '#3b82f6' },
@@ -323,7 +331,7 @@ const serviceArchitectureCanvas: ExtendedCanvas = {
323
331
  pv: {
324
332
  nodeType: 'database',
325
333
  shape: 'hexagon',
326
- icon: 'database',
334
+ icon: 'Database',
327
335
  },
328
336
  },
329
337
  {
@@ -338,7 +346,7 @@ const serviceArchitectureCanvas: ExtendedCanvas = {
338
346
  pv: {
339
347
  nodeType: 'cache',
340
348
  shape: 'diamond',
341
- icon: 'zap',
349
+ icon: 'Zap',
342
350
  },
343
351
  },
344
352
  ],
@@ -537,12 +545,16 @@ const EditableTemplate = () => {
537
545
  Reset
538
546
  </button>
539
547
  {hasChanges && (
540
- <span style={{ fontSize: 12, color: '#f5a623', fontStyle: 'italic' }}>Unsaved changes</span>
548
+ <span style={{ fontSize: 12, color: '#f5a623', fontStyle: 'italic' }}>
549
+ Unsaved changes
550
+ </span>
541
551
  )}
542
552
  </div>
543
553
  {lastSavedChanges && (
544
554
  <div style={{ marginTop: 12 }}>
545
- <div style={{ fontSize: 11, fontWeight: 'bold', color: '#666' }}>Last saved changes:</div>
555
+ <div style={{ fontSize: 11, fontWeight: 'bold', color: '#666' }}>
556
+ Last saved changes:
557
+ </div>
546
558
  <pre
547
559
  style={{
548
560
  marginTop: 4,
@@ -621,7 +633,8 @@ export const ServiceArchitectureEditable: Story = {
621
633
  parameters: {
622
634
  docs: {
623
635
  description: {
624
- story: 'Service architecture canvas with editing enabled. Edit nodes, create edges, and track changes.',
636
+ story:
637
+ 'Service architecture canvas with editing enabled. Edit nodes, create edges, and track changes.',
625
638
  },
626
639
  },
627
640
  },
@@ -0,0 +1,481 @@
1
+ import React, { useState } from 'react';
2
+ import type { Meta, StoryObj } from '@storybook/react';
3
+ import { GraphRenderer } from '../components/GraphRenderer';
4
+ import type { ExtendedCanvas } from '@principal-ai/principal-view-core';
5
+ import {
6
+ terminalTheme,
7
+ matrixTheme,
8
+ slateTheme,
9
+ regalTheme,
10
+ glassmorphismTheme,
11
+ landingPageTheme,
12
+ defaultEditorTheme,
13
+ ThemeProvider,
14
+ } from '@principal-ade/industry-theme';
15
+
16
+ const meta = {
17
+ title: 'Themes/IndustryThemes',
18
+ component: GraphRenderer,
19
+ parameters: {
20
+ layout: 'fullscreen',
21
+ },
22
+ } satisfies Meta<typeof GraphRenderer>;
23
+
24
+ export default meta;
25
+ type Story = StoryObj<typeof meta>;
26
+
27
+ // ============================================================================
28
+ // Theme Registry from @principal-ade/industry-theme
29
+ // ============================================================================
30
+
31
+ interface IndustryTheme {
32
+ colors: {
33
+ text: string;
34
+ background: string;
35
+ primary: string;
36
+ secondary: string;
37
+ accent: string;
38
+ success: string;
39
+ warning: string;
40
+ error: string;
41
+ info: string;
42
+ border: string;
43
+ surface: string;
44
+ [key: string]: string;
45
+ };
46
+ fonts: {
47
+ body: string;
48
+ heading: string;
49
+ monospace: string;
50
+ };
51
+ [key: string]: unknown;
52
+ }
53
+
54
+ const themes: Record<string, { theme: IndustryTheme; name: string; description: string }> = {
55
+ terminal: {
56
+ theme: terminalTheme as IndustryTheme,
57
+ name: 'Terminal',
58
+ description: 'Dark terminal-style theme with monospace fonts',
59
+ },
60
+ matrix: {
61
+ theme: matrixTheme as IndustryTheme,
62
+ name: 'Matrix',
63
+ description: 'Green-on-black hacker aesthetic',
64
+ },
65
+ slate: {
66
+ theme: slateTheme as IndustryTheme,
67
+ name: 'Slate',
68
+ description: 'Modern dark gray theme with amber accents',
69
+ },
70
+ regal: {
71
+ theme: regalTheme as IndustryTheme,
72
+ name: 'Regal',
73
+ description: 'Elegant dark theme with gold accents',
74
+ },
75
+ glassmorphism: {
76
+ theme: glassmorphismTheme as IndustryTheme,
77
+ name: 'Glassmorphism',
78
+ description: 'Frosted glass effect with purple tones',
79
+ },
80
+ landingPage: {
81
+ theme: landingPageTheme as IndustryTheme,
82
+ name: 'Landing Page',
83
+ description: 'Cyan accent on dark background',
84
+ },
85
+ editor: {
86
+ theme: defaultEditorTheme as IndustryTheme,
87
+ name: 'Editor',
88
+ description: 'VS Code inspired dark theme',
89
+ },
90
+ };
91
+
92
+ // ============================================================================
93
+ // Sample Canvas that uses theme colors
94
+ // ============================================================================
95
+
96
+ function createThemedCanvas(theme: IndustryTheme): ExtendedCanvas {
97
+ const colors = theme.colors;
98
+
99
+ return {
100
+ nodes: [
101
+ {
102
+ id: 'api-gateway',
103
+ type: 'text',
104
+ x: 100,
105
+ y: 200,
106
+ width: 140,
107
+ height: 70,
108
+ text: '# API Gateway',
109
+ pv: {
110
+ nodeType: 'api-gateway',
111
+ shape: 'rectangle',
112
+ icon: 'Globe',
113
+ fill: colors.primary,
114
+ },
115
+ },
116
+ {
117
+ id: 'auth-service',
118
+ type: 'text',
119
+ x: 320,
120
+ y: 100,
121
+ width: 140,
122
+ height: 70,
123
+ text: '# Auth Service',
124
+ pv: {
125
+ nodeType: 'service',
126
+ shape: 'hexagon',
127
+ icon: 'Shield',
128
+ fill: colors.success,
129
+ },
130
+ },
131
+ {
132
+ id: 'user-service',
133
+ type: 'text',
134
+ x: 320,
135
+ y: 300,
136
+ width: 140,
137
+ height: 70,
138
+ text: '# User Service',
139
+ pv: {
140
+ nodeType: 'service',
141
+ shape: 'hexagon',
142
+ icon: 'Users',
143
+ fill: colors.info,
144
+ },
145
+ },
146
+ {
147
+ id: 'database',
148
+ type: 'text',
149
+ x: 540,
150
+ y: 200,
151
+ width: 100,
152
+ height: 100,
153
+ text: '# Database',
154
+ pv: {
155
+ nodeType: 'database',
156
+ shape: 'circle',
157
+ icon: 'Database',
158
+ fill: colors.secondary,
159
+ },
160
+ },
161
+ {
162
+ id: 'cache',
163
+ type: 'text',
164
+ x: 540,
165
+ y: 350,
166
+ width: 80,
167
+ height: 80,
168
+ text: '# Cache',
169
+ pv: {
170
+ nodeType: 'cache',
171
+ shape: 'diamond',
172
+ icon: 'Zap',
173
+ fill: colors.warning,
174
+ },
175
+ },
176
+ {
177
+ id: 'queue',
178
+ type: 'text',
179
+ x: 320,
180
+ y: 450,
181
+ width: 80,
182
+ height: 80,
183
+ text: '# Queue',
184
+ pv: {
185
+ nodeType: 'queue',
186
+ shape: 'diamond',
187
+ icon: 'Inbox',
188
+ fill: colors.accent,
189
+ },
190
+ },
191
+ ],
192
+ edges: [
193
+ {
194
+ id: 'e1',
195
+ fromNode: 'api-gateway',
196
+ toNode: 'auth-service',
197
+ fromSide: 'right',
198
+ toSide: 'left',
199
+ pv: { edgeType: 'http' },
200
+ },
201
+ {
202
+ id: 'e2',
203
+ fromNode: 'api-gateway',
204
+ toNode: 'user-service',
205
+ fromSide: 'right',
206
+ toSide: 'left',
207
+ pv: { edgeType: 'http' },
208
+ },
209
+ {
210
+ id: 'e3',
211
+ fromNode: 'auth-service',
212
+ toNode: 'database',
213
+ fromSide: 'right',
214
+ toSide: 'left',
215
+ pv: { edgeType: 'query' },
216
+ },
217
+ {
218
+ id: 'e4',
219
+ fromNode: 'user-service',
220
+ toNode: 'database',
221
+ fromSide: 'right',
222
+ toSide: 'left',
223
+ pv: { edgeType: 'query' },
224
+ },
225
+ {
226
+ id: 'e5',
227
+ fromNode: 'user-service',
228
+ toNode: 'cache',
229
+ fromSide: 'right',
230
+ toSide: 'top',
231
+ pv: { edgeType: 'cache' },
232
+ },
233
+ {
234
+ id: 'e6',
235
+ fromNode: 'user-service',
236
+ toNode: 'queue',
237
+ fromSide: 'bottom',
238
+ toSide: 'top',
239
+ pv: { edgeType: 'async' },
240
+ },
241
+ ],
242
+ pv: {
243
+ version: '1.0.0',
244
+ name: 'Themed Architecture',
245
+ edgeTypes: {
246
+ http: { style: 'solid', color: colors.primary, directed: true },
247
+ query: { style: 'dashed', color: colors.secondary, directed: true },
248
+ cache: { style: 'dotted', color: colors.warning, directed: true },
249
+ async: { style: 'dashed', color: colors.accent, directed: true },
250
+ },
251
+ },
252
+ };
253
+ }
254
+
255
+ // ============================================================================
256
+ // Interactive Theme Switcher Component
257
+ // ============================================================================
258
+
259
+ const ThemeSwitcher = () => {
260
+ const [selectedTheme, setSelectedTheme] = useState<string>('terminal');
261
+ const themeConfig = themes[selectedTheme];
262
+ const canvas = createThemedCanvas(themeConfig.theme);
263
+
264
+ return (
265
+ <ThemeProvider theme={themeConfig.theme}>
266
+ <div
267
+ style={{
268
+ width: '100%',
269
+ height: '100vh',
270
+ display: 'flex',
271
+ flexDirection: 'column',
272
+ backgroundColor: themeConfig.theme.colors.background,
273
+ color: themeConfig.theme.colors.text,
274
+ fontFamily: themeConfig.theme.fonts.body,
275
+ }}
276
+ >
277
+ {/* Theme Selector Header */}
278
+ <div
279
+ style={{
280
+ padding: '16px 24px',
281
+ backgroundColor: themeConfig.theme.colors.surface,
282
+ display: 'flex',
283
+ alignItems: 'center',
284
+ gap: '16px',
285
+ borderBottom: `1px solid ${themeConfig.theme.colors.border}`,
286
+ }}
287
+ >
288
+ <label style={{ fontWeight: 600, fontSize: '14px' }}>Theme:</label>
289
+ <select
290
+ value={selectedTheme}
291
+ onChange={(e) => setSelectedTheme(e.target.value)}
292
+ style={{
293
+ padding: '8px 16px',
294
+ fontSize: '14px',
295
+ borderRadius: '6px',
296
+ border: `1px solid ${themeConfig.theme.colors.border}`,
297
+ backgroundColor: themeConfig.theme.colors.background,
298
+ color: themeConfig.theme.colors.text,
299
+ cursor: 'pointer',
300
+ minWidth: '200px',
301
+ }}
302
+ >
303
+ {Object.entries(themes).map(([key, config]) => (
304
+ <option key={key} value={key}>
305
+ {config.name}
306
+ </option>
307
+ ))}
308
+ </select>
309
+
310
+ <div style={{ marginLeft: 'auto', fontSize: '12px', opacity: 0.7 }}>
311
+ @principal-ade/industry-theme
312
+ </div>
313
+ </div>
314
+
315
+ {/* Theme Description */}
316
+ <div
317
+ style={{
318
+ padding: '12px 24px',
319
+ backgroundColor: themeConfig.theme.colors.surface,
320
+ borderBottom: `1px solid ${themeConfig.theme.colors.border}`,
321
+ fontSize: '13px',
322
+ opacity: 0.8,
323
+ }}
324
+ >
325
+ <strong>{themeConfig.name}</strong>: {themeConfig.description}
326
+ </div>
327
+
328
+ {/* Graph Renderer */}
329
+ <div style={{ flex: 1, position: 'relative' }}>
330
+ <GraphRenderer canvas={canvas} width="100%" height="100%" />
331
+ </div>
332
+
333
+ {/* Color Palette Legend */}
334
+ <div
335
+ style={{
336
+ padding: '16px 24px',
337
+ backgroundColor: themeConfig.theme.colors.surface,
338
+ borderTop: `1px solid ${themeConfig.theme.colors.border}`,
339
+ display: 'flex',
340
+ flexWrap: 'wrap',
341
+ gap: '16px',
342
+ }}
343
+ >
344
+ {['primary', 'secondary', 'accent', 'success', 'warning', 'error', 'info'].map((colorKey) => (
345
+ <div
346
+ key={colorKey}
347
+ style={{
348
+ display: 'flex',
349
+ alignItems: 'center',
350
+ gap: '8px',
351
+ fontSize: '12px',
352
+ }}
353
+ >
354
+ <div
355
+ style={{
356
+ width: '16px',
357
+ height: '16px',
358
+ borderRadius: '4px',
359
+ backgroundColor: themeConfig.theme.colors[colorKey],
360
+ border: `1px solid ${themeConfig.theme.colors.border}`,
361
+ }}
362
+ />
363
+ <span style={{ fontFamily: themeConfig.theme.fonts.monospace }}>{colorKey}</span>
364
+ </div>
365
+ ))}
366
+ </div>
367
+ </div>
368
+ </ThemeProvider>
369
+ );
370
+ };
371
+
372
+ // ============================================================================
373
+ // Stories
374
+ // ============================================================================
375
+
376
+ export const ThemeSwitcherDemo: Story = {
377
+ render: () => <ThemeSwitcher />,
378
+ parameters: {
379
+ docs: {
380
+ description: {
381
+ story: `
382
+ **Industry Theme Switcher**
383
+
384
+ This demo uses the \`@principal-ade/industry-theme\` package to apply different visual themes to the graph.
385
+
386
+ Available themes:
387
+ - **Terminal**: Dark terminal-style with monospace fonts
388
+ - **Matrix**: Green-on-black hacker aesthetic
389
+ - **Slate**: Modern dark gray with amber accents
390
+ - **Regal**: Elegant dark theme with gold accents
391
+ - **Glassmorphism**: Frosted glass effect with purple tones
392
+ - **Landing Page**: Cyan accent on dark background
393
+ - **Editor**: VS Code inspired dark theme
394
+
395
+ Each theme provides a cohesive color palette that is applied to:
396
+ - Node fill colors
397
+ - Edge colors
398
+ - Background and UI elements
399
+ `,
400
+ },
401
+ },
402
+ },
403
+ };
404
+
405
+ // Individual theme stories for direct access
406
+ export const TerminalTheme: Story = {
407
+ render: () => {
408
+ const canvas = createThemedCanvas(terminalTheme as IndustryTheme);
409
+ return (
410
+ <div style={{ backgroundColor: terminalTheme.colors.background, padding: 20 }}>
411
+ <GraphRenderer canvas={canvas} width={800} height={500} />
412
+ </div>
413
+ );
414
+ },
415
+ };
416
+
417
+ export const MatrixTheme: Story = {
418
+ render: () => {
419
+ const canvas = createThemedCanvas(matrixTheme as IndustryTheme);
420
+ return (
421
+ <div style={{ backgroundColor: matrixTheme.colors.background, padding: 20 }}>
422
+ <GraphRenderer canvas={canvas} width={800} height={500} />
423
+ </div>
424
+ );
425
+ },
426
+ };
427
+
428
+ export const SlateTheme: Story = {
429
+ render: () => {
430
+ const canvas = createThemedCanvas(slateTheme as IndustryTheme);
431
+ return (
432
+ <div style={{ backgroundColor: slateTheme.colors.background, padding: 20 }}>
433
+ <GraphRenderer canvas={canvas} width={800} height={500} />
434
+ </div>
435
+ );
436
+ },
437
+ };
438
+
439
+ export const RegalTheme: Story = {
440
+ render: () => {
441
+ const canvas = createThemedCanvas(regalTheme as IndustryTheme);
442
+ return (
443
+ <div style={{ backgroundColor: regalTheme.colors.background, padding: 20 }}>
444
+ <GraphRenderer canvas={canvas} width={800} height={500} />
445
+ </div>
446
+ );
447
+ },
448
+ };
449
+
450
+ export const GlassmorphismTheme: Story = {
451
+ render: () => {
452
+ const canvas = createThemedCanvas(glassmorphismTheme as IndustryTheme);
453
+ return (
454
+ <div style={{ backgroundColor: glassmorphismTheme.colors.background, padding: 20 }}>
455
+ <GraphRenderer canvas={canvas} width={800} height={500} />
456
+ </div>
457
+ );
458
+ },
459
+ };
460
+
461
+ export const LandingPageTheme: Story = {
462
+ render: () => {
463
+ const canvas = createThemedCanvas(landingPageTheme as IndustryTheme);
464
+ return (
465
+ <div style={{ backgroundColor: landingPageTheme.colors.background, padding: 20 }}>
466
+ <GraphRenderer canvas={canvas} width={800} height={500} />
467
+ </div>
468
+ );
469
+ },
470
+ };
471
+
472
+ export const EditorTheme: Story = {
473
+ render: () => {
474
+ const canvas = createThemedCanvas(defaultEditorTheme as IndustryTheme);
475
+ return (
476
+ <div style={{ backgroundColor: defaultEditorTheme.colors.background, padding: 20 }}>
477
+ <GraphRenderer canvas={canvas} width={800} height={500} />
478
+ </div>
479
+ );
480
+ },
481
+ };
@@ -3,6 +3,7 @@ import { useState } from 'react';
3
3
  import { GraphRenderer } from '../components/GraphRenderer';
4
4
  import type { ExtendedCanvas } from '@principal-ai/principal-view-core';
5
5
  import React from 'react';
6
+ import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
6
7
 
7
8
  const meta: Meta<typeof GraphRenderer> = {
8
9
  title: 'Multi-Config/Configuration Switcher',
@@ -11,6 +12,13 @@ const meta: Meta<typeof GraphRenderer> = {
11
12
  layout: 'fullscreen',
12
13
  },
13
14
  tags: ['autodocs'],
15
+ decorators: [
16
+ (Story) => (
17
+ <ThemeProvider theme={defaultEditorTheme}>
18
+ <Story />
19
+ </ThemeProvider>
20
+ ),
21
+ ],
14
22
  };
15
23
 
16
24
  export default meta;