orcasvn-react-diagrams 0.2.11 → 0.2.13

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 (55) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +15 -7
  3. package/ai/api-contract.json +90 -1
  4. package/ai/invariants.json +6 -2
  5. package/ai/manifest.json +1 -1
  6. package/dist/cjs/examples.js +916 -331
  7. package/dist/cjs/index.js +406 -97
  8. package/dist/cjs/types/api/createDiagramEditor.d.ts +3 -1
  9. package/dist/cjs/types/api/types.d.ts +64 -0
  10. package/dist/cjs/types/displaybox/demos/LinkPortCreationDemoTab.d.ts +3 -0
  11. package/dist/cjs/types/displaybox/demos/deletionEventsDemo.d.ts +2 -0
  12. package/dist/cjs/types/displaybox/demos/focusElementDemo.d.ts +4 -0
  13. package/dist/cjs/types/displaybox/demos/linkLabelsDemo.d.ts +4 -0
  14. package/dist/cjs/types/displaybox/types.d.ts +3 -0
  15. package/dist/cjs/types/displaybox/useDemoEditor.d.ts +3 -2
  16. package/dist/cjs/types/engine/DiagramEngine.d.ts +11 -1
  17. package/dist/cjs/types/engine/TextLayoutService.d.ts +1 -0
  18. package/dist/cjs/types/examples/index.d.ts +1 -1
  19. package/dist/cjs/types/renderer/konva/KonvaInteraction.d.ts +10 -1
  20. package/dist/esm/examples.js +916 -331
  21. package/dist/esm/examples.js.map +1 -1
  22. package/dist/esm/index.js +406 -97
  23. package/dist/esm/index.js.map +1 -1
  24. package/dist/esm/types/api/createDiagramEditor.d.ts +3 -1
  25. package/dist/esm/types/api/types.d.ts +64 -0
  26. package/dist/esm/types/displaybox/demos/LinkPortCreationDemoTab.d.ts +3 -0
  27. package/dist/esm/types/displaybox/demos/deletionEventsDemo.d.ts +2 -0
  28. package/dist/esm/types/displaybox/demos/focusElementDemo.d.ts +4 -0
  29. package/dist/esm/types/displaybox/demos/linkLabelsDemo.d.ts +4 -0
  30. package/dist/esm/types/displaybox/types.d.ts +3 -0
  31. package/dist/esm/types/displaybox/useDemoEditor.d.ts +3 -2
  32. package/dist/esm/types/engine/DiagramEngine.d.ts +11 -1
  33. package/dist/esm/types/engine/TextLayoutService.d.ts +1 -0
  34. package/dist/esm/types/examples/index.d.ts +1 -1
  35. package/dist/esm/types/renderer/konva/KonvaInteraction.d.ts +10 -1
  36. package/dist/examples.d.ts +55 -1
  37. package/dist/index.d.ts +67 -1
  38. package/docs/API_CONTRACT.md +88 -1
  39. package/docs/ARCHITECTURE.md +9 -7
  40. package/docs/CAPABILITIES.md +5 -0
  41. package/docs/COMMANDS_EVENTS.md +16 -6
  42. package/docs/DOCUMENTATION_WORKFLOW.md +5 -1
  43. package/docs/INTEGRATION_PLAYBOOK.md +8 -0
  44. package/docs/PORTING_CHECKLIST.md +4 -1
  45. package/docs/STATE_INVARIANTS.md +3 -0
  46. package/package.json +1 -1
  47. package/src/displaybox/demos/DeletionEventsDemoTab.tsx +167 -9
  48. package/src/displaybox/demos/LinkPortCreationDemoTab.tsx +98 -0
  49. package/src/displaybox/demos/deletionEventsDemo.ts +2 -2
  50. package/src/displaybox/demos/focusElementDemo.ts +91 -0
  51. package/src/displaybox/demos/index.tsx +124 -221
  52. package/src/displaybox/demos/linkLabelsDemo.ts +164 -0
  53. package/src/displaybox/demos/linkPortCreationDemo.ts +7 -7
  54. package/src/displaybox/types.ts +21 -11
  55. package/src/examples/index.ts +1 -0
@@ -0,0 +1,98 @@
1
+ import React from 'react';
2
+ import type { LinkTargetPortCreationHandler } from '../../api';
3
+ import DisplayBoxControls from '../DisplayBoxControls';
4
+ import DisplayBoxStage from '../DisplayBoxStage';
5
+ import useDemoControls from '../useDemoControls';
6
+ import useDemoEditor from '../useDemoEditor';
7
+ import useOffsetSequence from '../useOffsetSequence';
8
+ import type { DemoActionHelpers } from '../types';
9
+ import { linkPortCreationDemoConfig as demo } from './linkPortCreationDemo';
10
+
11
+ const LinkPortCreationDemo = () => {
12
+ const [useHostTargetPort, setUseHostTargetPort] = React.useState(false);
13
+
14
+ const onCreateLinkTargetPort = React.useMemo<LinkTargetPortCreationHandler | undefined>(() => {
15
+ if (!useHostTargetPort) return undefined;
16
+ return ({ defaultPort }) => ({
17
+ shapeId: 'port-dark',
18
+ size: { width: 16, height: 16 },
19
+ style: {
20
+ fill: '#f97316',
21
+ stroke: '#9a3412',
22
+ strokeWidth: 2,
23
+ name: 'port',
24
+ },
25
+ position: {
26
+ x: defaultPort.position.x,
27
+ y: 24,
28
+ },
29
+ orientToHostBorder: false,
30
+ });
31
+ }, [useHostTargetPort]);
32
+
33
+ const { containerRef, editorRef, diagramState, selection, snapEnabled, setSnapEnabled } = useDemoEditor({
34
+ createState: demo.createState,
35
+ elementShapes: demo.elementShapes,
36
+ portShapes: demo.portShapes,
37
+ router: demo.router,
38
+ snapDefault: demo.snapDefault,
39
+ linkRouteRefreshPolicy: demo.linkRouteRefreshPolicy,
40
+ linkColorPoolPolicy: demo.linkColorPoolPolicy,
41
+ onCreateLinkTargetPort,
42
+ });
43
+
44
+ const nextOffset = useOffsetSequence();
45
+ const actionHelpers: DemoActionHelpers = React.useMemo(() => ({ nextOffset }), [nextOffset]);
46
+
47
+ const controls = useDemoControls({
48
+ demo,
49
+ editorRef,
50
+ diagramState,
51
+ selection,
52
+ snapEnabled,
53
+ setSnapEnabled,
54
+ actionHelpers,
55
+ });
56
+
57
+ return (
58
+ <section>
59
+ <div style={{ marginBottom: 12 }}>
60
+ <h2 style={{ marginTop: 0, marginBottom: 4 }}>{demo.title}</h2>
61
+ <p style={{ marginTop: 0, marginBottom: 8 }}>{demo.description}</p>
62
+ <label style={{ display: 'inline-flex', alignItems: 'center', gap: 8, fontWeight: 600 }}>
63
+ <input
64
+ type="checkbox"
65
+ checked={useHostTargetPort}
66
+ onChange={(event) => setUseHostTargetPort(event.target.checked)}
67
+ />
68
+ Customize target port via onCreateLinkTargetPort
69
+ </label>
70
+ <p style={{ marginTop: 8, marginBottom: 0, color: '#5c4a2c' }}>
71
+ Default mode clones the source port. Custom mode reshapes the target-port preview and commit together;
72
+ host cancellation still belongs to <code>elementLinkConnecting</code>.
73
+ </p>
74
+ </div>
75
+ <DisplayBoxControls
76
+ actions={demo.actions}
77
+ snapEnabled={controls.snapEnabled}
78
+ selectedLinkRouting={controls.selectedLinkRouting}
79
+ canToggleLinkRouting={controls.canToggleLinkRouting}
80
+ onReload={controls.handleReload}
81
+ onZoomIn={controls.handleZoomIn}
82
+ onZoomOut={controls.handleZoomOut}
83
+ onResetViewport={controls.handleResetViewport}
84
+ onToggleSnap={controls.handleToggleSnap}
85
+ onManualRender={controls.handleManualRender}
86
+ onToggleLinkRouting={controls.handleToggleLinkRouting}
87
+ onAction={controls.handleAction}
88
+ onExportImage={controls.handleExportImage}
89
+ onClearExportPreview={controls.handleClearExportPreview}
90
+ exportPreviewDataUrl={controls.exportPreviewDataUrl}
91
+ exportError={controls.exportError}
92
+ />
93
+ <DisplayBoxStage containerRef={containerRef} stageStyle={demo.stageStyle} />
94
+ </section>
95
+ );
96
+ };
97
+
98
+ export default LinkPortCreationDemo;
@@ -2,7 +2,7 @@ import type { DiagramState } from '../../api';
2
2
  import type { DemoConfig } from '../types';
3
3
  import { baseElementShapes, basePortShapes } from './shared';
4
4
 
5
- const createDeletionEventsState = (): DiagramState => ({
5
+ export const createDeletionEventsState = (): DiagramState => ({
6
6
  elements: [
7
7
  {
8
8
  id: 'delete-source',
@@ -81,7 +81,7 @@ const createDeletionEventsState = (): DiagramState => ({
81
81
  export const deletionEventsDemoConfig: DemoConfig = {
82
82
  id: 'deletion-events',
83
83
  title: 'Deletion Events',
84
- description: 'Inspect elementDeleted, portDeleted, linkDeleted, and textDeleted payloads for direct and cascade removals.',
84
+ description: 'Inspect cancellable delete lifecycle events, post-delete payloads, and element double click in one integration-focused scenario.',
85
85
  createState: createDeletionEventsState,
86
86
  elementShapes: baseElementShapes,
87
87
  portShapes: basePortShapes,
@@ -0,0 +1,91 @@
1
+ import type { DiagramState } from '../../api';
2
+ import type { DemoAction, DemoConfig } from '../types';
3
+ import { baseElementShapes, basePortShapes } from './shared';
4
+
5
+ export const createFocusElementState = (): DiagramState => ({
6
+ elements: [
7
+ {
8
+ id: 'focus-left',
9
+ position: { x: 40, y: 80 },
10
+ size: { width: 140, height: 90 },
11
+ shapeId: 'default',
12
+ style: { fill: '#e0f2fe', stroke: '#0369a1', strokeWidth: 2 },
13
+ },
14
+ {
15
+ id: 'focus-right',
16
+ position: { x: 820, y: 120 },
17
+ size: { width: 180, height: 110 },
18
+ shapeId: 'panel',
19
+ style: { fill: '#fef3c7', stroke: '#b45309', strokeWidth: 2 },
20
+ },
21
+ {
22
+ id: 'focus-parent',
23
+ position: { x: 520, y: 420 },
24
+ size: { width: 220, height: 160 },
25
+ shapeId: 'default',
26
+ style: { fill: '#ecfccb', stroke: '#4d7c0f', strokeWidth: 2 },
27
+ },
28
+ {
29
+ id: 'focus-child',
30
+ parentId: 'focus-parent',
31
+ position: { x: 110, y: 60 },
32
+ size: { width: 70, height: 50 },
33
+ shapeId: 'default',
34
+ anchorCenter: true,
35
+ style: { fill: '#dcfce7', stroke: '#15803d', strokeWidth: 2 },
36
+ },
37
+ ],
38
+ ports: [],
39
+ links: [],
40
+ texts: [
41
+ {
42
+ id: 'focus-copy',
43
+ content: 'Compare explicit element focus against zoom-to-fit.',
44
+ position: { x: 40, y: 26 },
45
+ },
46
+ ],
47
+ });
48
+
49
+ const focusLeftAction: DemoAction = {
50
+ id: 'focus-left-default',
51
+ label: 'Focus Left (Keep Zoom)',
52
+ run: (editor) => {
53
+ editor.focusElement('focus-left');
54
+ },
55
+ };
56
+
57
+ const focusRightZoomAction: DemoAction = {
58
+ id: 'focus-right-zoom',
59
+ label: 'Focus Right (Zoom 2.2)',
60
+ run: (editor) => {
61
+ editor.focusElement('focus-right', { zoom: 2.2 });
62
+ },
63
+ };
64
+
65
+ const focusChildZoomAction: DemoAction = {
66
+ id: 'focus-child-zoom',
67
+ label: 'Focus Nested Child (Zoom 1.8)',
68
+ run: (editor) => {
69
+ editor.focusElement('focus-child', { zoom: 1.8 });
70
+ },
71
+ };
72
+
73
+ const fitAllAction: DemoAction = {
74
+ id: 'focus-fit-all',
75
+ label: 'Zoom-To-Fit For Comparison',
76
+ run: (editor) => {
77
+ editor.zoomToFitElements({ padding: 40 });
78
+ },
79
+ };
80
+
81
+ export const focusElementDemoConfig: DemoConfig = {
82
+ id: 'focus-element',
83
+ title: 'Focus Element',
84
+ description: 'Centers one explicit element, optionally with a chosen zoom, unlike zoom-to-fit which frames the whole scene.',
85
+ createState: createFocusElementState,
86
+ elementShapes: baseElementShapes,
87
+ portShapes: basePortShapes,
88
+ defaultElementShapeId: 'default',
89
+ defaultPortShapeId: 'port-circle',
90
+ actions: [focusLeftAction, focusRightZoomAction, focusChildZoomAction, fitAllAction],
91
+ };
@@ -1,5 +1,5 @@
1
- import React from 'react';
2
- import type { DemoConfig, DemoDefinition } from '../types';
1
+ import React from 'react';
2
+ import type { DemoConfig, DemoDefinition, DemoMenuGroup } from '../types';
3
3
  import { basicDemoConfig } from './basicDemo';
4
4
  import { linkPortCreationDemoConfig } from './linkPortCreationDemo';
5
5
  import { nestedDemoConfig } from './nestedDemo';
@@ -24,8 +24,9 @@ import { portPositionLimitsDemoConfig } from './portPositionLimitsDemo';
24
24
  import { portBorderDemoConfig } from './portBorderDemo';
25
25
  import { childConstraintsDemoConfig } from './childConstraintsDemo';
26
26
  import { labelStyleDemoConfig } from './labelStyleDemo';
27
- import { linkColorPoolDemoConfig } from './linkColorPoolDemo';
28
- import { gridOverlayDemoConfig } from './gridOverlayDemo';
27
+ import { linkColorPoolDemoConfig } from './linkColorPoolDemo';
28
+ import { linkLabelsDemoConfig } from './linkLabelsDemo';
29
+ import { gridOverlayDemoConfig } from './gridOverlayDemo';
29
30
  import { routingDemoConfig } from './routingDemo';
30
31
  import { obstacleRoutingDemoConfig } from './obstacleRoutingDemo';
31
32
  import { linkBendHandlesDemoConfig } from './linkBendHandlesDemo';
@@ -35,8 +36,9 @@ import { shapeHoverControlsDemoConfig } from './shapeHoverControlsDemo';
35
36
  import { vertexControlLinkSessionDemoConfig } from './vertexControlLinkSessionDemo';
36
37
  import EventHandlersDemo from './EventHandlersDemoTab';
37
38
  import EngineEventsDemo from './EngineEventsDemoTab';
38
- import LinkCancelDemo from './LinkCancelDemoTab';
39
- import AutoLayoutDemo from './AutoLayoutDemoTab';
39
+ import LinkCancelDemo from './LinkCancelDemoTab';
40
+ import LinkPortCreationDemo from './LinkPortCreationDemoTab';
41
+ import AutoLayoutDemo from './AutoLayoutDemoTab';
40
42
  import ExternalDragDropDemo from './ExternalDragDropDemoTab';
41
43
  import SvgPathDemo from './SvgPathDemoTab';
42
44
  import TextLayoutDemo from './TextLayoutDemoTab';
@@ -51,6 +53,7 @@ import AsymmetricPortMultiAnchorDemo from './AsymmetricPortMultiAnchorDemoTab';
51
53
  import VertexControlLinkSessionDemo from './VertexControlLinkSessionDemoTab';
52
54
  import { offsetAnchorAvoidanceDemoConfig } from './offsetAnchorAvoidanceDemo';
53
55
  import { zoomToFitElementsDemoConfig } from './zoomToFitElementsDemo';
56
+ import { focusElementDemoConfig } from './focusElementDemo';
54
57
 
55
58
  export {
56
59
  baseElementShapes,
@@ -61,218 +64,118 @@ export {
61
64
  defaultSvgPathSize,
62
65
  externalToolboxItems,
63
66
  } from './shared';
64
-
65
- const wrapSimpleDemo = (demo: DemoConfig) => () => <SimpleDemo demo={demo} />;
66
-
67
- export const demoTabs: DemoDefinition[] = [
68
- {
69
- id: basicDemoConfig.id,
70
- title: basicDemoConfig.title,
71
- description: basicDemoConfig.description,
72
- Component: wrapSimpleDemo(basicDemoConfig),
73
- },
74
- {
75
- id: linkPortCreationDemoConfig.id,
76
- title: linkPortCreationDemoConfig.title,
77
- description: linkPortCreationDemoConfig.description,
78
- Component: wrapSimpleDemo(linkPortCreationDemoConfig),
79
- },
80
- {
81
- id: nestedDemoConfig.id,
82
- title: nestedDemoConfig.title,
83
- description: nestedDemoConfig.description,
84
- Component: wrapSimpleDemo(nestedDemoConfig),
85
- },
86
- {
87
- id: customDemoConfig.id,
88
- title: customDemoConfig.title,
89
- description: customDemoConfig.description,
90
- Component: wrapSimpleDemo(customDemoConfig),
91
- },
92
- {
93
- id: textDemoConfig.id,
94
- title: textDemoConfig.title,
95
- description: textDemoConfig.description,
96
- Component: TextLayoutDemo,
97
- },
98
- {
99
- id: selectionDemoConfig.id,
100
- title: selectionDemoConfig.title,
101
- description: selectionDemoConfig.description,
102
- Component: wrapSimpleDemo(selectionDemoConfig),
103
- },
104
- {
105
- id: elementVisibilitySelectionDemoConfig.id,
106
- title: elementVisibilitySelectionDemoConfig.title,
107
- description: elementVisibilitySelectionDemoConfig.description,
108
- Component: wrapSimpleDemo(elementVisibilitySelectionDemoConfig),
109
- },
110
- {
111
- id: eventHandlersDemoConfig.id,
112
- title: eventHandlersDemoConfig.title,
113
- description: eventHandlersDemoConfig.description,
114
- Component: EventHandlersDemo,
115
- },
116
- {
117
- id: engineEventsDemoConfig.id,
118
- title: engineEventsDemoConfig.title,
119
- description: engineEventsDemoConfig.description,
120
- Component: EngineEventsDemo,
121
- },
122
- {
123
- id: deletionEventsDemoConfig.id,
124
- title: deletionEventsDemoConfig.title,
125
- description: deletionEventsDemoConfig.description,
126
- Component: DeletionEventsDemo,
127
- },
128
- {
129
- id: autoLayoutDemoConfig.id,
130
- title: autoLayoutDemoConfig.title,
131
- description: autoLayoutDemoConfig.description,
132
- Component: AutoLayoutDemo,
133
- },
134
- {
135
- id: linkCancelDemoConfig.id,
136
- title: linkCancelDemoConfig.title,
137
- description: linkCancelDemoConfig.description,
138
- Component: LinkCancelDemo,
139
- },
140
- {
141
- id: externalDragDropDemoConfig.id,
142
- title: externalDragDropDemoConfig.title,
143
- description: externalDragDropDemoConfig.description,
144
- Component: ExternalDragDropDemo,
145
- },
146
- {
147
- id: shapeGalleryDemoConfig.id,
148
- title: shapeGalleryDemoConfig.title,
149
- description: shapeGalleryDemoConfig.description,
150
- Component: wrapSimpleDemo(shapeGalleryDemoConfig),
151
- },
152
- {
153
- id: roundedRectRadiusDemoConfig.id,
154
- title: roundedRectRadiusDemoConfig.title,
155
- description: roundedRectRadiusDemoConfig.description,
156
- Component: wrapSimpleDemo(roundedRectRadiusDemoConfig),
157
- },
158
- {
159
- id: rotatedCreationDemoConfig.id,
160
- title: rotatedCreationDemoConfig.title,
161
- description: rotatedCreationDemoConfig.description,
162
- Component: wrapSimpleDemo(rotatedCreationDemoConfig),
163
- },
164
- {
165
- id: svgPathDemoConfig.id,
166
- title: svgPathDemoConfig.title,
167
- description: svgPathDemoConfig.description,
168
- Component: SvgPathDemo,
169
- },
170
- {
171
- id: asymmetricPortMultiAnchorDemoConfig.id,
172
- title: asymmetricPortMultiAnchorDemoConfig.title,
173
- description: asymmetricPortMultiAnchorDemoConfig.description,
174
- Component: AsymmetricPortMultiAnchorDemo,
175
- },
176
- {
177
- id: multiLevelTreeDemoConfig.id,
178
- title: multiLevelTreeDemoConfig.title,
179
- description: multiLevelTreeDemoConfig.description,
180
- Component: wrapSimpleDemo(multiLevelTreeDemoConfig),
181
- },
182
- {
183
- id: multipleElementsDemoConfig.id,
184
- title: multipleElementsDemoConfig.title,
185
- description: multipleElementsDemoConfig.description,
186
- Component: wrapSimpleDemo(multipleElementsDemoConfig),
187
- },
188
- {
189
- id: portConstraintsDemoConfig.id,
190
- title: portConstraintsDemoConfig.title,
191
- description: portConstraintsDemoConfig.description,
192
- Component: wrapSimpleDemo(portConstraintsDemoConfig),
193
- },
194
- {
195
- id: portPositionLimitsDemoConfig.id,
196
- title: portPositionLimitsDemoConfig.title,
197
- description: portPositionLimitsDemoConfig.description,
198
- Component: wrapSimpleDemo(portPositionLimitsDemoConfig),
199
- },
200
- {
201
- id: labelStyleDemoConfig.id,
202
- title: labelStyleDemoConfig.title,
203
- description: labelStyleDemoConfig.description,
204
- Component: wrapSimpleDemo(labelStyleDemoConfig),
205
- },
206
- {
207
- id: linkColorPoolDemoConfig.id,
208
- title: linkColorPoolDemoConfig.title,
209
- description: linkColorPoolDemoConfig.description,
210
- Component: LinkColorPoolDemo,
211
- },
212
- {
213
- id: portBorderDemoConfig.id,
214
- title: portBorderDemoConfig.title,
215
- description: portBorderDemoConfig.description,
216
- Component: wrapSimpleDemo(portBorderDemoConfig),
217
- },
218
- {
219
- id: shapeBorderMovementDemoConfig.id,
220
- title: shapeBorderMovementDemoConfig.title,
221
- description: shapeBorderMovementDemoConfig.description,
222
- Component: wrapSimpleDemo(shapeBorderMovementDemoConfig),
223
- },
224
- {
225
- id: shapeHoverControlsDemoConfig.id,
226
- title: shapeHoverControlsDemoConfig.title,
227
- description: shapeHoverControlsDemoConfig.description,
228
- Component: ShapeHoverControlsDemo,
229
- },
230
- {
231
- id: vertexControlLinkSessionDemoConfig.id,
232
- title: vertexControlLinkSessionDemoConfig.title,
233
- description: vertexControlLinkSessionDemoConfig.description,
234
- Component: VertexControlLinkSessionDemo,
235
- },
236
- {
237
- id: childConstraintsDemoConfig.id,
238
- title: childConstraintsDemoConfig.title,
239
- description: childConstraintsDemoConfig.description,
240
- Component: wrapSimpleDemo(childConstraintsDemoConfig),
241
- },
242
- {
243
- id: gridOverlayDemoConfig.id,
244
- title: gridOverlayDemoConfig.title,
245
- description: gridOverlayDemoConfig.description,
246
- Component: wrapSimpleDemo(gridOverlayDemoConfig),
247
- },
248
- {
249
- id: routingDemoConfig.id,
250
- title: routingDemoConfig.title,
251
- description: routingDemoConfig.description,
252
- Component: wrapSimpleDemo(routingDemoConfig),
253
- },
254
- {
255
- id: obstacleRoutingDemoConfig.id,
256
- title: obstacleRoutingDemoConfig.title,
257
- description: obstacleRoutingDemoConfig.description,
258
- Component: ObstacleRoutingDemo,
259
- },
260
- {
261
- id: offsetAnchorAvoidanceDemoConfig.id,
262
- title: offsetAnchorAvoidanceDemoConfig.title,
263
- description: offsetAnchorAvoidanceDemoConfig.description,
264
- Component: OffsetAnchorAvoidanceDemo,
265
- },
266
- {
267
- id: zoomToFitElementsDemoConfig.id,
268
- title: zoomToFitElementsDemoConfig.title,
269
- description: zoomToFitElementsDemoConfig.description,
270
- Component: ZoomToFitElementsDemo,
271
- },
272
- {
273
- id: linkBendHandlesDemoConfig.id,
274
- title: linkBendHandlesDemoConfig.title,
275
- description: linkBendHandlesDemoConfig.description,
276
- Component: wrapSimpleDemo(linkBendHandlesDemoConfig),
277
- },
278
- ];
67
+
68
+ const wrapSimpleDemo = (demo: DemoConfig) => () => <SimpleDemo demo={demo} />;
69
+
70
+ type DemoRegistration = {
71
+ demo: DemoConfig;
72
+ Component: React.ComponentType;
73
+ menuGroup: DemoMenuGroup;
74
+ menuOrder: number;
75
+ };
76
+
77
+ const menuGroupOrder: Record<DemoMenuGroup, number> = {
78
+ basics: 1,
79
+ layoutText: 2,
80
+ shapes: 3,
81
+ portsAnchors: 4,
82
+ linksRouting: 5,
83
+ eventsIntegration: 6,
84
+ };
85
+
86
+ const registerDemo = (
87
+ demo: DemoConfig,
88
+ Component: React.ComponentType,
89
+ menuGroup: DemoMenuGroup,
90
+ menuOrder: number,
91
+ ): DemoRegistration => ({
92
+ demo,
93
+ Component,
94
+ menuGroup,
95
+ menuOrder,
96
+ });
97
+
98
+ const toDemoDefinition = ({
99
+ demo,
100
+ Component,
101
+ menuGroup,
102
+ menuOrder,
103
+ }: DemoRegistration): DemoDefinition => ({
104
+ id: demo.id,
105
+ title: demo.title,
106
+ description: demo.description,
107
+ Component,
108
+ menuGroup,
109
+ menuOrder,
110
+ });
111
+
112
+ const compareDemoDefinitions = (left: DemoDefinition, right: DemoDefinition) =>
113
+ menuGroupOrder[left.menuGroup] - menuGroupOrder[right.menuGroup]
114
+ || left.menuOrder - right.menuOrder
115
+ || left.title.localeCompare(right.title);
116
+
117
+ const basics = [
118
+ registerDemo(basicDemoConfig, wrapSimpleDemo(basicDemoConfig), 'basics', 1),
119
+ registerDemo(multipleElementsDemoConfig, wrapSimpleDemo(multipleElementsDemoConfig), 'basics', 2),
120
+ registerDemo(nestedDemoConfig, wrapSimpleDemo(nestedDemoConfig), 'basics', 3),
121
+ registerDemo(selectionDemoConfig, wrapSimpleDemo(selectionDemoConfig), 'basics', 4),
122
+ registerDemo(elementVisibilitySelectionDemoConfig, wrapSimpleDemo(elementVisibilitySelectionDemoConfig), 'basics', 5),
123
+ registerDemo(zoomToFitElementsDemoConfig, ZoomToFitElementsDemo, 'basics', 6),
124
+ registerDemo(focusElementDemoConfig, wrapSimpleDemo(focusElementDemoConfig), 'basics', 7),
125
+ ];
126
+
127
+ const layoutAndText = [
128
+ registerDemo(textDemoConfig, TextLayoutDemo, 'layoutText', 1),
129
+ registerDemo(labelStyleDemoConfig, wrapSimpleDemo(labelStyleDemoConfig), 'layoutText', 2),
130
+ registerDemo(autoLayoutDemoConfig, AutoLayoutDemo, 'layoutText', 3),
131
+ registerDemo(multiLevelTreeDemoConfig, wrapSimpleDemo(multiLevelTreeDemoConfig), 'layoutText', 4),
132
+ registerDemo(childConstraintsDemoConfig, wrapSimpleDemo(childConstraintsDemoConfig), 'layoutText', 5),
133
+ registerDemo(gridOverlayDemoConfig, wrapSimpleDemo(gridOverlayDemoConfig), 'layoutText', 6),
134
+ ];
135
+
136
+ const shapes = [
137
+ registerDemo(customDemoConfig, wrapSimpleDemo(customDemoConfig), 'shapes', 1),
138
+ registerDemo(shapeGalleryDemoConfig, wrapSimpleDemo(shapeGalleryDemoConfig), 'shapes', 2),
139
+ registerDemo(roundedRectRadiusDemoConfig, wrapSimpleDemo(roundedRectRadiusDemoConfig), 'shapes', 3),
140
+ registerDemo(rotatedCreationDemoConfig, wrapSimpleDemo(rotatedCreationDemoConfig), 'shapes', 4),
141
+ registerDemo(svgPathDemoConfig, SvgPathDemo, 'shapes', 5),
142
+ registerDemo(shapeBorderMovementDemoConfig, wrapSimpleDemo(shapeBorderMovementDemoConfig), 'shapes', 6),
143
+ registerDemo(shapeHoverControlsDemoConfig, ShapeHoverControlsDemo, 'shapes', 7),
144
+ ];
145
+
146
+ const portsAndAnchors = [
147
+ registerDemo(linkPortCreationDemoConfig, LinkPortCreationDemo, 'portsAnchors', 1),
148
+ registerDemo(portConstraintsDemoConfig, wrapSimpleDemo(portConstraintsDemoConfig), 'portsAnchors', 2),
149
+ registerDemo(portPositionLimitsDemoConfig, wrapSimpleDemo(portPositionLimitsDemoConfig), 'portsAnchors', 3),
150
+ registerDemo(portBorderDemoConfig, wrapSimpleDemo(portBorderDemoConfig), 'portsAnchors', 4),
151
+ registerDemo(asymmetricPortMultiAnchorDemoConfig, AsymmetricPortMultiAnchorDemo, 'portsAnchors', 5),
152
+ ];
153
+
154
+ const linksAndRouting = [
155
+ registerDemo(linkCancelDemoConfig, LinkCancelDemo, 'linksRouting', 1),
156
+ registerDemo(linkBendHandlesDemoConfig, wrapSimpleDemo(linkBendHandlesDemoConfig), 'linksRouting', 2),
157
+ registerDemo(linkLabelsDemoConfig, wrapSimpleDemo(linkLabelsDemoConfig), 'linksRouting', 3),
158
+ registerDemo(linkColorPoolDemoConfig, LinkColorPoolDemo, 'linksRouting', 4),
159
+ registerDemo(routingDemoConfig, wrapSimpleDemo(routingDemoConfig), 'linksRouting', 5),
160
+ registerDemo(obstacleRoutingDemoConfig, ObstacleRoutingDemo, 'linksRouting', 6),
161
+ registerDemo(offsetAnchorAvoidanceDemoConfig, OffsetAnchorAvoidanceDemo, 'linksRouting', 7),
162
+ registerDemo(vertexControlLinkSessionDemoConfig, VertexControlLinkSessionDemo, 'linksRouting', 8),
163
+ ];
164
+
165
+ const eventsAndIntegration = [
166
+ registerDemo(eventHandlersDemoConfig, EventHandlersDemo, 'eventsIntegration', 1),
167
+ registerDemo(engineEventsDemoConfig, EngineEventsDemo, 'eventsIntegration', 2),
168
+ registerDemo(deletionEventsDemoConfig, DeletionEventsDemo, 'eventsIntegration', 3),
169
+ registerDemo(externalDragDropDemoConfig, ExternalDragDropDemo, 'eventsIntegration', 4),
170
+ ];
171
+
172
+ export const demoTabs: DemoDefinition[] = [
173
+ ...basics,
174
+ ...layoutAndText,
175
+ ...shapes,
176
+ ...portsAndAnchors,
177
+ ...linksAndRouting,
178
+ ...eventsAndIntegration,
179
+ ]
180
+ .map(toDemoDefinition)
181
+ .sort(compareDemoDefinitions);