@principal-ai/principal-view-react 0.6.9 → 0.6.11
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.
- package/README.md +2 -5
- package/dist/components/ConfigurationSelector.js +4 -2
- package/dist/components/ConfigurationSelector.js.map +1 -1
- package/dist/components/EdgeInfoPanel.d.ts.map +1 -1
- package/dist/components/EdgeInfoPanel.js +43 -13
- package/dist/components/EdgeInfoPanel.js.map +1 -1
- package/dist/components/GraphRenderer.d.ts.map +1 -1
- package/dist/components/GraphRenderer.js +135 -82
- package/dist/components/GraphRenderer.js.map +1 -1
- package/dist/components/NodeInfoPanel.d.ts.map +1 -1
- package/dist/components/NodeInfoPanel.js +143 -45
- package/dist/components/NodeInfoPanel.js.map +1 -1
- package/dist/edges/CustomEdge.d.ts.map +1 -1
- package/dist/edges/CustomEdge.js +2 -2
- package/dist/edges/CustomEdge.js.map +1 -1
- package/dist/edges/GenericEdge.d.ts.map +1 -1
- package/dist/edges/GenericEdge.js +2 -2
- package/dist/edges/GenericEdge.js.map +1 -1
- package/dist/hooks/usePathBasedEvents.d.ts +1 -1
- package/dist/hooks/usePathBasedEvents.d.ts.map +1 -1
- package/dist/hooks/usePathBasedEvents.js +9 -9
- package/dist/hooks/usePathBasedEvents.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/nodes/CustomNode.d.ts.map +1 -1
- package/dist/nodes/CustomNode.js +61 -44
- package/dist/nodes/CustomNode.js.map +1 -1
- package/dist/nodes/GenericNode.d.ts.map +1 -1
- package/dist/nodes/GenericNode.js.map +1 -1
- package/dist/utils/animationMapping.d.ts.map +1 -1
- package/dist/utils/animationMapping.js +12 -12
- package/dist/utils/animationMapping.js.map +1 -1
- package/dist/utils/graphConverter.d.ts.map +1 -1
- package/dist/utils/graphConverter.js +23 -17
- package/dist/utils/graphConverter.js.map +1 -1
- package/dist/utils/iconResolver.d.ts.map +1 -1
- package/dist/utils/iconResolver.js +1 -1
- package/dist/utils/iconResolver.js.map +1 -1
- package/package.json +2 -1
- package/src/components/ConfigurationSelector.tsx +5 -5
- package/src/components/EdgeInfoPanel.tsx +79 -37
- package/src/components/GraphRenderer.tsx +528 -364
- package/src/components/NodeInfoPanel.tsx +209 -86
- package/src/edges/CustomEdge.tsx +6 -4
- package/src/edges/GenericEdge.tsx +2 -6
- package/src/hooks/usePathBasedEvents.ts +54 -45
- package/src/index.ts +11 -2
- package/src/nodes/CustomNode.tsx +132 -106
- package/src/nodes/GenericNode.tsx +4 -3
- package/src/stories/AnimationWorkshop.stories.tsx +131 -12
- package/src/stories/CanvasNodeTypes.stories.tsx +898 -0
- package/src/stories/ColorPriority.stories.tsx +20 -10
- package/src/stories/EventDrivenAnimations.stories.tsx +8 -0
- package/src/stories/EventLog.stories.tsx +1 -1
- package/src/stories/GraphRenderer.stories.tsx +23 -10
- package/src/stories/IndustryThemes.stories.tsx +481 -0
- package/src/stories/MultiConfig.stories.tsx +8 -0
- package/src/stories/MultiDirectionalConnections.stories.tsx +8 -0
- package/src/stories/NodeFieldsAudit.stories.tsx +124 -37
- package/src/stories/NodeShapes.stories.tsx +73 -59
- package/src/utils/animationMapping.ts +19 -23
- package/src/utils/graphConverter.ts +35 -19
- package/src/utils/iconResolver.tsx +5 -1
|
@@ -0,0 +1,898 @@
|
|
|
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/principal-view-core';
|
|
5
|
+
import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
|
|
6
|
+
|
|
7
|
+
const meta = {
|
|
8
|
+
title: 'Audit/CanvasNodeTypes',
|
|
9
|
+
component: GraphRenderer,
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: 'centered',
|
|
12
|
+
},
|
|
13
|
+
tags: ['autodocs'],
|
|
14
|
+
decorators: [
|
|
15
|
+
(Story) => (
|
|
16
|
+
<ThemeProvider theme={defaultEditorTheme}>
|
|
17
|
+
<Story />
|
|
18
|
+
</ThemeProvider>
|
|
19
|
+
),
|
|
20
|
+
],
|
|
21
|
+
} satisfies Meta<typeof GraphRenderer>;
|
|
22
|
+
|
|
23
|
+
export default meta;
|
|
24
|
+
type Story = StoryObj<typeof meta>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Canvas showing all standard JSON Canvas node types
|
|
28
|
+
*/
|
|
29
|
+
const allNodeTypesCanvas: ExtendedCanvas = {
|
|
30
|
+
nodes: [
|
|
31
|
+
// Text Node
|
|
32
|
+
{
|
|
33
|
+
id: 'text-node',
|
|
34
|
+
type: 'text',
|
|
35
|
+
x: 100,
|
|
36
|
+
y: 100,
|
|
37
|
+
width: 180,
|
|
38
|
+
height: 100,
|
|
39
|
+
text: '# Text Node\n\nMarkdown content here',
|
|
40
|
+
color: 6, // purple
|
|
41
|
+
pv: {
|
|
42
|
+
nodeType: 'text-example',
|
|
43
|
+
shape: 'rectangle',
|
|
44
|
+
icon: 'FileText',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
// File Node
|
|
48
|
+
{
|
|
49
|
+
id: 'file-node',
|
|
50
|
+
type: 'file',
|
|
51
|
+
x: 350,
|
|
52
|
+
y: 100,
|
|
53
|
+
width: 180,
|
|
54
|
+
height: 100,
|
|
55
|
+
file: 'src/components/App.tsx',
|
|
56
|
+
color: 4, // green
|
|
57
|
+
pv: {
|
|
58
|
+
nodeType: 'file-example',
|
|
59
|
+
shape: 'rectangle',
|
|
60
|
+
icon: 'FileCode',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
// Link Node
|
|
64
|
+
{
|
|
65
|
+
id: 'link-node',
|
|
66
|
+
type: 'link',
|
|
67
|
+
x: 600,
|
|
68
|
+
y: 100,
|
|
69
|
+
width: 180,
|
|
70
|
+
height: 100,
|
|
71
|
+
url: 'https://github.com/example/repo',
|
|
72
|
+
color: 5, // cyan
|
|
73
|
+
pv: {
|
|
74
|
+
nodeType: 'link-example',
|
|
75
|
+
shape: 'rectangle',
|
|
76
|
+
icon: 'Link',
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
// Group Node (rendered as container)
|
|
80
|
+
{
|
|
81
|
+
id: 'group-node',
|
|
82
|
+
type: 'group',
|
|
83
|
+
x: 100,
|
|
84
|
+
y: 280,
|
|
85
|
+
width: 300,
|
|
86
|
+
height: 150,
|
|
87
|
+
label: 'Group Container',
|
|
88
|
+
color: 3, // yellow
|
|
89
|
+
pv: {
|
|
90
|
+
nodeType: 'group-example',
|
|
91
|
+
shape: 'rectangle',
|
|
92
|
+
icon: 'Folder',
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
// Text node inside group
|
|
96
|
+
{
|
|
97
|
+
id: 'grouped-text',
|
|
98
|
+
type: 'text',
|
|
99
|
+
x: 130,
|
|
100
|
+
y: 320,
|
|
101
|
+
width: 120,
|
|
102
|
+
height: 60,
|
|
103
|
+
text: 'Inside Group',
|
|
104
|
+
color: 6,
|
|
105
|
+
pv: {
|
|
106
|
+
nodeType: 'grouped-item',
|
|
107
|
+
shape: 'rectangle',
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
edges: [],
|
|
112
|
+
pv: {
|
|
113
|
+
version: '1.0.0',
|
|
114
|
+
name: 'Canvas Node Types',
|
|
115
|
+
description: 'All standard JSON Canvas node types',
|
|
116
|
+
edgeTypes: {},
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export const AllNodeTypes: Story = {
|
|
121
|
+
args: {
|
|
122
|
+
canvas: allNodeTypesCanvas,
|
|
123
|
+
width: 900,
|
|
124
|
+
height: 500,
|
|
125
|
+
},
|
|
126
|
+
parameters: {
|
|
127
|
+
docs: {
|
|
128
|
+
description: {
|
|
129
|
+
story: `
|
|
130
|
+
**All JSON Canvas Node Types**
|
|
131
|
+
|
|
132
|
+
This story displays the 4 standard JSON Canvas node types:
|
|
133
|
+
|
|
134
|
+
- **Text Node** - Contains markdown text content (\`text\` field)
|
|
135
|
+
- **File Node** - References a file path (\`file\` field)
|
|
136
|
+
- **Link Node** - References a URL (\`url\` field)
|
|
137
|
+
- **Group Node** - Container for grouping other nodes (\`label\` field)
|
|
138
|
+
`,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Canvas showing text nodes with different content types
|
|
146
|
+
*/
|
|
147
|
+
const textNodesCanvas: ExtendedCanvas = {
|
|
148
|
+
nodes: [
|
|
149
|
+
{
|
|
150
|
+
id: 'text-plain',
|
|
151
|
+
type: 'text',
|
|
152
|
+
x: 100,
|
|
153
|
+
y: 100,
|
|
154
|
+
width: 160,
|
|
155
|
+
height: 80,
|
|
156
|
+
text: 'Plain text content',
|
|
157
|
+
color: 6,
|
|
158
|
+
pv: {
|
|
159
|
+
nodeType: 'text-plain',
|
|
160
|
+
shape: 'rectangle',
|
|
161
|
+
icon: 'Type',
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
id: 'text-heading',
|
|
166
|
+
type: 'text',
|
|
167
|
+
x: 300,
|
|
168
|
+
y: 100,
|
|
169
|
+
width: 160,
|
|
170
|
+
height: 80,
|
|
171
|
+
text: '# Heading\n\nWith paragraph',
|
|
172
|
+
color: 6,
|
|
173
|
+
pv: {
|
|
174
|
+
nodeType: 'text-heading',
|
|
175
|
+
shape: 'rectangle',
|
|
176
|
+
icon: 'Heading',
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
id: 'text-list',
|
|
181
|
+
type: 'text',
|
|
182
|
+
x: 500,
|
|
183
|
+
y: 100,
|
|
184
|
+
width: 180,
|
|
185
|
+
height: 100,
|
|
186
|
+
text: '# Todo List\n\n- Item 1\n- Item 2\n- Item 3',
|
|
187
|
+
color: 6,
|
|
188
|
+
pv: {
|
|
189
|
+
nodeType: 'text-list',
|
|
190
|
+
shape: 'rectangle',
|
|
191
|
+
icon: 'List',
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
id: 'text-code',
|
|
196
|
+
type: 'text',
|
|
197
|
+
x: 100,
|
|
198
|
+
y: 240,
|
|
199
|
+
width: 200,
|
|
200
|
+
height: 100,
|
|
201
|
+
text: '# Code Block\n\n```js\nconst x = 1;\n```',
|
|
202
|
+
color: 6,
|
|
203
|
+
pv: {
|
|
204
|
+
nodeType: 'text-code',
|
|
205
|
+
shape: 'rectangle',
|
|
206
|
+
icon: 'Code',
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
id: 'text-long',
|
|
211
|
+
type: 'text',
|
|
212
|
+
x: 340,
|
|
213
|
+
y: 240,
|
|
214
|
+
width: 220,
|
|
215
|
+
height: 120,
|
|
216
|
+
text: '# Long Content\n\nThis is a longer text node with multiple paragraphs.\n\nIt demonstrates how text wraps within the node bounds.',
|
|
217
|
+
color: 6,
|
|
218
|
+
pv: {
|
|
219
|
+
nodeType: 'text-long',
|
|
220
|
+
shape: 'rectangle',
|
|
221
|
+
icon: 'AlignLeft',
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
],
|
|
225
|
+
edges: [],
|
|
226
|
+
pv: {
|
|
227
|
+
version: '1.0.0',
|
|
228
|
+
name: 'Text Node Variations',
|
|
229
|
+
description: 'Different text content types',
|
|
230
|
+
edgeTypes: {},
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
export const TextNodes: Story = {
|
|
235
|
+
args: {
|
|
236
|
+
canvas: textNodesCanvas,
|
|
237
|
+
width: 800,
|
|
238
|
+
height: 420,
|
|
239
|
+
},
|
|
240
|
+
parameters: {
|
|
241
|
+
docs: {
|
|
242
|
+
description: {
|
|
243
|
+
story: `
|
|
244
|
+
**Text Node Variations**
|
|
245
|
+
|
|
246
|
+
Text nodes (\`type: 'text'\`) can contain various markdown content:
|
|
247
|
+
- Plain text
|
|
248
|
+
- Headings with paragraphs
|
|
249
|
+
- Lists
|
|
250
|
+
- Code blocks
|
|
251
|
+
- Long multi-paragraph content
|
|
252
|
+
`,
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Canvas showing file nodes with different file types
|
|
260
|
+
*/
|
|
261
|
+
const fileNodesCanvas: ExtendedCanvas = {
|
|
262
|
+
nodes: [
|
|
263
|
+
{
|
|
264
|
+
id: 'file-ts',
|
|
265
|
+
type: 'file',
|
|
266
|
+
x: 100,
|
|
267
|
+
y: 100,
|
|
268
|
+
width: 180,
|
|
269
|
+
height: 80,
|
|
270
|
+
file: 'src/index.ts',
|
|
271
|
+
color: 4,
|
|
272
|
+
pv: {
|
|
273
|
+
nodeType: 'file-typescript',
|
|
274
|
+
shape: 'rectangle',
|
|
275
|
+
icon: 'FileCode',
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
id: 'file-tsx',
|
|
280
|
+
type: 'file',
|
|
281
|
+
x: 320,
|
|
282
|
+
y: 100,
|
|
283
|
+
width: 200,
|
|
284
|
+
height: 80,
|
|
285
|
+
file: 'src/components/App.tsx',
|
|
286
|
+
color: 5,
|
|
287
|
+
pv: {
|
|
288
|
+
nodeType: 'file-react',
|
|
289
|
+
shape: 'rectangle',
|
|
290
|
+
icon: 'Component',
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
id: 'file-json',
|
|
295
|
+
type: 'file',
|
|
296
|
+
x: 560,
|
|
297
|
+
y: 100,
|
|
298
|
+
width: 160,
|
|
299
|
+
height: 80,
|
|
300
|
+
file: 'package.json',
|
|
301
|
+
color: 3,
|
|
302
|
+
pv: {
|
|
303
|
+
nodeType: 'file-json',
|
|
304
|
+
shape: 'rectangle',
|
|
305
|
+
icon: 'Braces',
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
id: 'file-md',
|
|
310
|
+
type: 'file',
|
|
311
|
+
x: 100,
|
|
312
|
+
y: 220,
|
|
313
|
+
width: 160,
|
|
314
|
+
height: 80,
|
|
315
|
+
file: 'docs/README.md',
|
|
316
|
+
color: 6,
|
|
317
|
+
pv: {
|
|
318
|
+
nodeType: 'file-markdown',
|
|
319
|
+
shape: 'rectangle',
|
|
320
|
+
icon: 'BookOpen',
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
id: 'file-subpath',
|
|
325
|
+
type: 'file',
|
|
326
|
+
x: 300,
|
|
327
|
+
y: 220,
|
|
328
|
+
width: 220,
|
|
329
|
+
height: 100,
|
|
330
|
+
file: 'docs/architecture.md',
|
|
331
|
+
subpath: '#database-schema',
|
|
332
|
+
color: 6,
|
|
333
|
+
pv: {
|
|
334
|
+
nodeType: 'file-with-subpath',
|
|
335
|
+
shape: 'rectangle',
|
|
336
|
+
icon: 'Hash',
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
id: 'file-image',
|
|
341
|
+
type: 'file',
|
|
342
|
+
x: 560,
|
|
343
|
+
y: 220,
|
|
344
|
+
width: 160,
|
|
345
|
+
height: 80,
|
|
346
|
+
file: 'assets/logo.png',
|
|
347
|
+
color: 2,
|
|
348
|
+
pv: {
|
|
349
|
+
nodeType: 'file-image',
|
|
350
|
+
shape: 'rectangle',
|
|
351
|
+
icon: 'Image',
|
|
352
|
+
},
|
|
353
|
+
},
|
|
354
|
+
],
|
|
355
|
+
edges: [],
|
|
356
|
+
pv: {
|
|
357
|
+
version: '1.0.0',
|
|
358
|
+
name: 'File Node Variations',
|
|
359
|
+
description: 'Different file types and subpaths',
|
|
360
|
+
edgeTypes: {},
|
|
361
|
+
},
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
export const FileNodes: Story = {
|
|
365
|
+
args: {
|
|
366
|
+
canvas: fileNodesCanvas,
|
|
367
|
+
width: 800,
|
|
368
|
+
height: 380,
|
|
369
|
+
},
|
|
370
|
+
parameters: {
|
|
371
|
+
docs: {
|
|
372
|
+
description: {
|
|
373
|
+
story: `
|
|
374
|
+
**File Node Variations**
|
|
375
|
+
|
|
376
|
+
File nodes (\`type: 'file'\`) reference external files:
|
|
377
|
+
- TypeScript files
|
|
378
|
+
- React components (TSX)
|
|
379
|
+
- JSON config files
|
|
380
|
+
- Markdown documentation
|
|
381
|
+
- Files with subpath (heading/block link)
|
|
382
|
+
- Image assets
|
|
383
|
+
|
|
384
|
+
The \`file\` field contains the path, and optional \`subpath\` can reference a specific section.
|
|
385
|
+
`,
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
},
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Canvas showing link nodes with different URL types
|
|
393
|
+
*/
|
|
394
|
+
const linkNodesCanvas: ExtendedCanvas = {
|
|
395
|
+
nodes: [
|
|
396
|
+
{
|
|
397
|
+
id: 'link-github',
|
|
398
|
+
type: 'link',
|
|
399
|
+
x: 100,
|
|
400
|
+
y: 100,
|
|
401
|
+
width: 200,
|
|
402
|
+
height: 80,
|
|
403
|
+
url: 'https://github.com/anthropics/claude',
|
|
404
|
+
color: 0, // default/gray
|
|
405
|
+
pv: {
|
|
406
|
+
nodeType: 'link-github',
|
|
407
|
+
shape: 'rectangle',
|
|
408
|
+
icon: 'Github',
|
|
409
|
+
},
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
id: 'link-docs',
|
|
413
|
+
type: 'link',
|
|
414
|
+
x: 340,
|
|
415
|
+
y: 100,
|
|
416
|
+
width: 200,
|
|
417
|
+
height: 80,
|
|
418
|
+
url: 'https://docs.example.com/api',
|
|
419
|
+
color: 5,
|
|
420
|
+
pv: {
|
|
421
|
+
nodeType: 'link-documentation',
|
|
422
|
+
shape: 'rectangle',
|
|
423
|
+
icon: 'Book',
|
|
424
|
+
},
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
id: 'link-api',
|
|
428
|
+
type: 'link',
|
|
429
|
+
x: 580,
|
|
430
|
+
y: 100,
|
|
431
|
+
width: 180,
|
|
432
|
+
height: 80,
|
|
433
|
+
url: 'https://api.example.com/v1',
|
|
434
|
+
color: 4,
|
|
435
|
+
pv: {
|
|
436
|
+
nodeType: 'link-api',
|
|
437
|
+
shape: 'rectangle',
|
|
438
|
+
icon: 'Cloud',
|
|
439
|
+
},
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
id: 'link-jira',
|
|
443
|
+
type: 'link',
|
|
444
|
+
x: 100,
|
|
445
|
+
y: 220,
|
|
446
|
+
width: 200,
|
|
447
|
+
height: 80,
|
|
448
|
+
url: 'https://jira.example.com/browse/PROJ-123',
|
|
449
|
+
color: 5,
|
|
450
|
+
pv: {
|
|
451
|
+
nodeType: 'link-ticket',
|
|
452
|
+
shape: 'rectangle',
|
|
453
|
+
icon: 'Ticket',
|
|
454
|
+
},
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
id: 'link-figma',
|
|
458
|
+
type: 'link',
|
|
459
|
+
x: 340,
|
|
460
|
+
y: 220,
|
|
461
|
+
width: 200,
|
|
462
|
+
height: 80,
|
|
463
|
+
url: 'https://figma.com/file/abc123',
|
|
464
|
+
color: 6,
|
|
465
|
+
pv: {
|
|
466
|
+
nodeType: 'link-design',
|
|
467
|
+
shape: 'rectangle',
|
|
468
|
+
icon: 'Palette',
|
|
469
|
+
},
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
id: 'link-slack',
|
|
473
|
+
type: 'link',
|
|
474
|
+
x: 580,
|
|
475
|
+
y: 220,
|
|
476
|
+
width: 180,
|
|
477
|
+
height: 80,
|
|
478
|
+
url: 'https://slack.com/channel/dev',
|
|
479
|
+
color: 2,
|
|
480
|
+
pv: {
|
|
481
|
+
nodeType: 'link-chat',
|
|
482
|
+
shape: 'rectangle',
|
|
483
|
+
icon: 'MessageCircle',
|
|
484
|
+
},
|
|
485
|
+
},
|
|
486
|
+
],
|
|
487
|
+
edges: [],
|
|
488
|
+
pv: {
|
|
489
|
+
version: '1.0.0',
|
|
490
|
+
name: 'Link Node Variations',
|
|
491
|
+
description: 'Different URL/link types',
|
|
492
|
+
edgeTypes: {},
|
|
493
|
+
},
|
|
494
|
+
};
|
|
495
|
+
|
|
496
|
+
export const LinkNodes: Story = {
|
|
497
|
+
args: {
|
|
498
|
+
canvas: linkNodesCanvas,
|
|
499
|
+
width: 850,
|
|
500
|
+
height: 380,
|
|
501
|
+
},
|
|
502
|
+
parameters: {
|
|
503
|
+
docs: {
|
|
504
|
+
description: {
|
|
505
|
+
story: `
|
|
506
|
+
**Link Node Variations**
|
|
507
|
+
|
|
508
|
+
Link nodes (\`type: 'link'\`) reference external URLs:
|
|
509
|
+
- GitHub repositories
|
|
510
|
+
- Documentation sites
|
|
511
|
+
- API endpoints
|
|
512
|
+
- Issue trackers (Jira, Linear)
|
|
513
|
+
- Design tools (Figma)
|
|
514
|
+
- Communication tools (Slack)
|
|
515
|
+
|
|
516
|
+
The \`url\` field contains the full URL.
|
|
517
|
+
`,
|
|
518
|
+
},
|
|
519
|
+
},
|
|
520
|
+
},
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Canvas showing a realistic mixed-type diagram
|
|
525
|
+
*/
|
|
526
|
+
const mixedTypesCanvas: ExtendedCanvas = {
|
|
527
|
+
nodes: [
|
|
528
|
+
// Documentation (file)
|
|
529
|
+
{
|
|
530
|
+
id: 'docs',
|
|
531
|
+
type: 'file',
|
|
532
|
+
x: 100,
|
|
533
|
+
y: 100,
|
|
534
|
+
width: 160,
|
|
535
|
+
height: 80,
|
|
536
|
+
file: 'docs/architecture.md',
|
|
537
|
+
color: 6,
|
|
538
|
+
pv: {
|
|
539
|
+
nodeType: 'documentation',
|
|
540
|
+
shape: 'rectangle',
|
|
541
|
+
icon: 'BookOpen',
|
|
542
|
+
},
|
|
543
|
+
},
|
|
544
|
+
// Design link
|
|
545
|
+
{
|
|
546
|
+
id: 'design',
|
|
547
|
+
type: 'link',
|
|
548
|
+
x: 100,
|
|
549
|
+
y: 220,
|
|
550
|
+
width: 160,
|
|
551
|
+
height: 80,
|
|
552
|
+
url: 'https://figma.com/file/design',
|
|
553
|
+
color: 6,
|
|
554
|
+
pv: {
|
|
555
|
+
nodeType: 'design-spec',
|
|
556
|
+
shape: 'rectangle',
|
|
557
|
+
icon: 'Palette',
|
|
558
|
+
},
|
|
559
|
+
},
|
|
560
|
+
// Main component (file)
|
|
561
|
+
{
|
|
562
|
+
id: 'component',
|
|
563
|
+
type: 'file',
|
|
564
|
+
x: 350,
|
|
565
|
+
y: 160,
|
|
566
|
+
width: 180,
|
|
567
|
+
height: 80,
|
|
568
|
+
file: 'src/components/Feature.tsx',
|
|
569
|
+
color: 4,
|
|
570
|
+
pv: {
|
|
571
|
+
nodeType: 'component',
|
|
572
|
+
shape: 'rectangle',
|
|
573
|
+
icon: 'Component',
|
|
574
|
+
},
|
|
575
|
+
},
|
|
576
|
+
// Notes (text)
|
|
577
|
+
{
|
|
578
|
+
id: 'notes',
|
|
579
|
+
type: 'text',
|
|
580
|
+
x: 350,
|
|
581
|
+
y: 280,
|
|
582
|
+
width: 180,
|
|
583
|
+
height: 100,
|
|
584
|
+
text: '# Implementation Notes\n\n- Check edge cases\n- Add tests\n- Update docs',
|
|
585
|
+
color: 3,
|
|
586
|
+
pv: {
|
|
587
|
+
nodeType: 'notes',
|
|
588
|
+
shape: 'rectangle',
|
|
589
|
+
icon: 'StickyNote',
|
|
590
|
+
},
|
|
591
|
+
},
|
|
592
|
+
// API endpoint (link)
|
|
593
|
+
{
|
|
594
|
+
id: 'api',
|
|
595
|
+
type: 'link',
|
|
596
|
+
x: 600,
|
|
597
|
+
y: 100,
|
|
598
|
+
width: 160,
|
|
599
|
+
height: 80,
|
|
600
|
+
url: 'https://api.example.com/feature',
|
|
601
|
+
color: 5,
|
|
602
|
+
pv: {
|
|
603
|
+
nodeType: 'api-endpoint',
|
|
604
|
+
shape: 'rectangle',
|
|
605
|
+
icon: 'Cloud',
|
|
606
|
+
},
|
|
607
|
+
},
|
|
608
|
+
// Test file (file)
|
|
609
|
+
{
|
|
610
|
+
id: 'tests',
|
|
611
|
+
type: 'file',
|
|
612
|
+
x: 600,
|
|
613
|
+
y: 220,
|
|
614
|
+
width: 160,
|
|
615
|
+
height: 80,
|
|
616
|
+
file: 'src/components/Feature.test.tsx',
|
|
617
|
+
color: 4,
|
|
618
|
+
pv: {
|
|
619
|
+
nodeType: 'test-file',
|
|
620
|
+
shape: 'rectangle',
|
|
621
|
+
icon: 'TestTube',
|
|
622
|
+
},
|
|
623
|
+
},
|
|
624
|
+
// Issue tracker (link)
|
|
625
|
+
{
|
|
626
|
+
id: 'ticket',
|
|
627
|
+
type: 'link',
|
|
628
|
+
x: 600,
|
|
629
|
+
y: 340,
|
|
630
|
+
width: 160,
|
|
631
|
+
height: 80,
|
|
632
|
+
url: 'https://jira.example.com/PROJ-456',
|
|
633
|
+
color: 5,
|
|
634
|
+
pv: {
|
|
635
|
+
nodeType: 'ticket',
|
|
636
|
+
shape: 'rectangle',
|
|
637
|
+
icon: 'Ticket',
|
|
638
|
+
},
|
|
639
|
+
},
|
|
640
|
+
],
|
|
641
|
+
edges: [
|
|
642
|
+
{
|
|
643
|
+
id: 'docs-to-component',
|
|
644
|
+
fromNode: 'docs',
|
|
645
|
+
toNode: 'component',
|
|
646
|
+
fromSide: 'right',
|
|
647
|
+
toSide: 'left',
|
|
648
|
+
pv: { edgeType: 'reference' },
|
|
649
|
+
},
|
|
650
|
+
{
|
|
651
|
+
id: 'design-to-component',
|
|
652
|
+
fromNode: 'design',
|
|
653
|
+
toNode: 'component',
|
|
654
|
+
fromSide: 'right',
|
|
655
|
+
toSide: 'left',
|
|
656
|
+
pv: { edgeType: 'reference' },
|
|
657
|
+
},
|
|
658
|
+
{
|
|
659
|
+
id: 'component-to-api',
|
|
660
|
+
fromNode: 'component',
|
|
661
|
+
toNode: 'api',
|
|
662
|
+
fromSide: 'right',
|
|
663
|
+
toSide: 'left',
|
|
664
|
+
pv: { edgeType: 'uses' },
|
|
665
|
+
},
|
|
666
|
+
{
|
|
667
|
+
id: 'component-to-tests',
|
|
668
|
+
fromNode: 'component',
|
|
669
|
+
toNode: 'tests',
|
|
670
|
+
fromSide: 'right',
|
|
671
|
+
toSide: 'left',
|
|
672
|
+
pv: { edgeType: 'tested-by' },
|
|
673
|
+
},
|
|
674
|
+
{
|
|
675
|
+
id: 'notes-to-ticket',
|
|
676
|
+
fromNode: 'notes',
|
|
677
|
+
toNode: 'ticket',
|
|
678
|
+
fromSide: 'right',
|
|
679
|
+
toSide: 'left',
|
|
680
|
+
pv: { edgeType: 'tracks' },
|
|
681
|
+
},
|
|
682
|
+
],
|
|
683
|
+
pv: {
|
|
684
|
+
version: '1.0.0',
|
|
685
|
+
name: 'Feature Development Map',
|
|
686
|
+
description: 'Mixed node types showing a feature development context',
|
|
687
|
+
edgeTypes: {
|
|
688
|
+
reference: {
|
|
689
|
+
style: 'dashed',
|
|
690
|
+
color: '#8b5cf6',
|
|
691
|
+
directed: true,
|
|
692
|
+
},
|
|
693
|
+
uses: {
|
|
694
|
+
style: 'solid',
|
|
695
|
+
color: '#22c55e',
|
|
696
|
+
directed: true,
|
|
697
|
+
},
|
|
698
|
+
'tested-by': {
|
|
699
|
+
style: 'dotted',
|
|
700
|
+
color: '#3b82f6',
|
|
701
|
+
directed: true,
|
|
702
|
+
},
|
|
703
|
+
tracks: {
|
|
704
|
+
style: 'dashed',
|
|
705
|
+
color: '#f97316',
|
|
706
|
+
directed: true,
|
|
707
|
+
},
|
|
708
|
+
},
|
|
709
|
+
},
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
export const MixedTypes: Story = {
|
|
713
|
+
args: {
|
|
714
|
+
canvas: mixedTypesCanvas,
|
|
715
|
+
width: 850,
|
|
716
|
+
height: 500,
|
|
717
|
+
},
|
|
718
|
+
parameters: {
|
|
719
|
+
docs: {
|
|
720
|
+
description: {
|
|
721
|
+
story: `
|
|
722
|
+
**Mixed Node Types - Feature Development Map**
|
|
723
|
+
|
|
724
|
+
A realistic example showing how different node types work together:
|
|
725
|
+
- **File nodes**: Source code, tests, documentation
|
|
726
|
+
- **Link nodes**: API endpoints, design specs, issue trackers
|
|
727
|
+
- **Text nodes**: Notes and annotations
|
|
728
|
+
|
|
729
|
+
This demonstrates a typical feature development context where you'd reference:
|
|
730
|
+
- Architecture docs (file)
|
|
731
|
+
- Figma designs (link)
|
|
732
|
+
- Source components (file)
|
|
733
|
+
- API endpoints (link)
|
|
734
|
+
- Test files (file)
|
|
735
|
+
- Issue tickets (link)
|
|
736
|
+
- Implementation notes (text)
|
|
737
|
+
`,
|
|
738
|
+
},
|
|
739
|
+
},
|
|
740
|
+
},
|
|
741
|
+
};
|
|
742
|
+
|
|
743
|
+
/**
|
|
744
|
+
* Interactive comparison template
|
|
745
|
+
*/
|
|
746
|
+
const NodeTypeComparisonTemplate = () => {
|
|
747
|
+
return (
|
|
748
|
+
<div style={{ padding: 20, fontFamily: 'system-ui' }}>
|
|
749
|
+
<h2 style={{ marginBottom: 20 }}>JSON Canvas Node Types Comparison</h2>
|
|
750
|
+
|
|
751
|
+
<div
|
|
752
|
+
style={{
|
|
753
|
+
display: 'grid',
|
|
754
|
+
gridTemplateColumns: 'repeat(4, 1fr)',
|
|
755
|
+
gap: 20,
|
|
756
|
+
marginBottom: 30,
|
|
757
|
+
}}
|
|
758
|
+
>
|
|
759
|
+
<div
|
|
760
|
+
style={{
|
|
761
|
+
padding: 16,
|
|
762
|
+
backgroundColor: '#f3e8ff',
|
|
763
|
+
borderRadius: 8,
|
|
764
|
+
border: '2px solid #8b5cf6',
|
|
765
|
+
}}
|
|
766
|
+
>
|
|
767
|
+
<h4 style={{ margin: '0 0 8px 0', color: '#6b21a8' }}>Text Node</h4>
|
|
768
|
+
<code style={{ fontSize: 11, display: 'block', marginBottom: 8 }}>type: 'text'</code>
|
|
769
|
+
<div style={{ fontSize: 12, color: '#6b21a8' }}>
|
|
770
|
+
<strong>Fields:</strong>
|
|
771
|
+
<ul style={{ margin: '4px 0', paddingLeft: 16 }}>
|
|
772
|
+
<li>
|
|
773
|
+
<code>text</code> - Markdown content
|
|
774
|
+
</li>
|
|
775
|
+
</ul>
|
|
776
|
+
</div>
|
|
777
|
+
</div>
|
|
778
|
+
|
|
779
|
+
<div
|
|
780
|
+
style={{
|
|
781
|
+
padding: 16,
|
|
782
|
+
backgroundColor: '#dcfce7',
|
|
783
|
+
borderRadius: 8,
|
|
784
|
+
border: '2px solid #22c55e',
|
|
785
|
+
}}
|
|
786
|
+
>
|
|
787
|
+
<h4 style={{ margin: '0 0 8px 0', color: '#166534' }}>File Node</h4>
|
|
788
|
+
<code style={{ fontSize: 11, display: 'block', marginBottom: 8 }}>type: 'file'</code>
|
|
789
|
+
<div style={{ fontSize: 12, color: '#166534' }}>
|
|
790
|
+
<strong>Fields:</strong>
|
|
791
|
+
<ul style={{ margin: '4px 0', paddingLeft: 16 }}>
|
|
792
|
+
<li>
|
|
793
|
+
<code>file</code> - File path
|
|
794
|
+
</li>
|
|
795
|
+
<li>
|
|
796
|
+
<code>subpath?</code> - Section link
|
|
797
|
+
</li>
|
|
798
|
+
</ul>
|
|
799
|
+
</div>
|
|
800
|
+
</div>
|
|
801
|
+
|
|
802
|
+
<div
|
|
803
|
+
style={{
|
|
804
|
+
padding: 16,
|
|
805
|
+
backgroundColor: '#cffafe',
|
|
806
|
+
borderRadius: 8,
|
|
807
|
+
border: '2px solid #06b6d4',
|
|
808
|
+
}}
|
|
809
|
+
>
|
|
810
|
+
<h4 style={{ margin: '0 0 8px 0', color: '#0e7490' }}>Link Node</h4>
|
|
811
|
+
<code style={{ fontSize: 11, display: 'block', marginBottom: 8 }}>type: 'link'</code>
|
|
812
|
+
<div style={{ fontSize: 12, color: '#0e7490' }}>
|
|
813
|
+
<strong>Fields:</strong>
|
|
814
|
+
<ul style={{ margin: '4px 0', paddingLeft: 16 }}>
|
|
815
|
+
<li>
|
|
816
|
+
<code>url</code> - Full URL
|
|
817
|
+
</li>
|
|
818
|
+
</ul>
|
|
819
|
+
</div>
|
|
820
|
+
</div>
|
|
821
|
+
|
|
822
|
+
<div
|
|
823
|
+
style={{
|
|
824
|
+
padding: 16,
|
|
825
|
+
backgroundColor: '#fef9c3',
|
|
826
|
+
borderRadius: 8,
|
|
827
|
+
border: '2px solid #eab308',
|
|
828
|
+
}}
|
|
829
|
+
>
|
|
830
|
+
<h4 style={{ margin: '0 0 8px 0', color: '#a16207' }}>Group Node</h4>
|
|
831
|
+
<code style={{ fontSize: 11, display: 'block', marginBottom: 8 }}>type: 'group'</code>
|
|
832
|
+
<div style={{ fontSize: 12, color: '#a16207' }}>
|
|
833
|
+
<strong>Fields:</strong>
|
|
834
|
+
<ul style={{ margin: '4px 0', paddingLeft: 16 }}>
|
|
835
|
+
<li>
|
|
836
|
+
<code>label?</code> - Group name
|
|
837
|
+
</li>
|
|
838
|
+
<li>
|
|
839
|
+
<code>background?</code> - Image
|
|
840
|
+
</li>
|
|
841
|
+
</ul>
|
|
842
|
+
</div>
|
|
843
|
+
</div>
|
|
844
|
+
</div>
|
|
845
|
+
|
|
846
|
+
<h3 style={{ marginBottom: 16 }}>Live Example: All Node Types</h3>
|
|
847
|
+
<GraphRenderer canvas={allNodeTypesCanvas} width={900} height={500} />
|
|
848
|
+
|
|
849
|
+
<div
|
|
850
|
+
style={{
|
|
851
|
+
marginTop: 24,
|
|
852
|
+
padding: 16,
|
|
853
|
+
backgroundColor: '#f5f5f5',
|
|
854
|
+
borderRadius: 8,
|
|
855
|
+
}}
|
|
856
|
+
>
|
|
857
|
+
<h4 style={{ margin: '0 0 12px 0' }}>JSON Canvas Spec</h4>
|
|
858
|
+
<p style={{ fontSize: 13, margin: 0, lineHeight: 1.6 }}>
|
|
859
|
+
These node types follow the{' '}
|
|
860
|
+
<a
|
|
861
|
+
href="https://jsoncanvas.org/"
|
|
862
|
+
target="_blank"
|
|
863
|
+
rel="noopener noreferrer"
|
|
864
|
+
style={{ color: '#3b82f6' }}
|
|
865
|
+
>
|
|
866
|
+
JSON Canvas specification
|
|
867
|
+
</a>
|
|
868
|
+
. Each node type serves a specific purpose:
|
|
869
|
+
</p>
|
|
870
|
+
<ul style={{ fontSize: 13, lineHeight: 1.8, margin: '8px 0 0 0', paddingLeft: 20 }}>
|
|
871
|
+
<li>
|
|
872
|
+
<strong>Text</strong> - For notes, descriptions, and embedded markdown content
|
|
873
|
+
</li>
|
|
874
|
+
<li>
|
|
875
|
+
<strong>File</strong> - For referencing local files in your project
|
|
876
|
+
</li>
|
|
877
|
+
<li>
|
|
878
|
+
<strong>Link</strong> - For external resources, APIs, documentation, tools
|
|
879
|
+
</li>
|
|
880
|
+
<li>
|
|
881
|
+
<strong>Group</strong> - For visually organizing related nodes together
|
|
882
|
+
</li>
|
|
883
|
+
</ul>
|
|
884
|
+
</div>
|
|
885
|
+
</div>
|
|
886
|
+
);
|
|
887
|
+
};
|
|
888
|
+
|
|
889
|
+
export const NodeTypeComparison: Story = {
|
|
890
|
+
render: () => <NodeTypeComparisonTemplate />,
|
|
891
|
+
parameters: {
|
|
892
|
+
docs: {
|
|
893
|
+
description: {
|
|
894
|
+
story: 'Interactive comparison view showing all JSON Canvas node types with field documentation.',
|
|
895
|
+
},
|
|
896
|
+
},
|
|
897
|
+
},
|
|
898
|
+
};
|