orcasvn-react-diagrams 0.2.0 → 0.2.2

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 (133) hide show
  1. package/README.md +22 -1
  2. package/ai/api-contract.json +57 -5
  3. package/ai/invariants.json +5 -3
  4. package/ai/manifest.json +1 -1
  5. package/dist/cjs/examples.js +11775 -0
  6. package/dist/cjs/index.js +3889 -1112
  7. package/dist/cjs/types/api/createDiagramEditor.d.ts +7 -2
  8. package/dist/cjs/types/api/types.d.ts +178 -0
  9. package/dist/cjs/types/displaybox/demos/DeletionEventsDemoTab.d.ts +3 -0
  10. package/dist/cjs/types/displaybox/demos/ShapeHoverControlsDemoTab.d.ts +3 -0
  11. package/dist/cjs/types/displaybox/demos/TextLayoutDemoTab.d.ts +3 -0
  12. package/dist/cjs/types/displaybox/demos/deletionEventsDemo.d.ts +2 -0
  13. package/dist/cjs/types/displaybox/demos/rotatedCreationDemo.d.ts +2 -0
  14. package/dist/cjs/types/displaybox/demos/roundedRectRadiusDemo.d.ts +2 -0
  15. package/dist/cjs/types/displaybox/demos/shapeBorderMovementDemo.d.ts +2 -0
  16. package/dist/cjs/types/displaybox/demos/shapeHoverControlsDemo.d.ts +10 -0
  17. package/dist/cjs/types/displaybox/demos/textDemo.d.ts +4 -0
  18. package/dist/cjs/types/displaybox/useDemoEditor.d.ts +5 -2
  19. package/dist/cjs/types/engine/AutoLayoutService.d.ts +24 -0
  20. package/dist/cjs/types/engine/DiagramEngine.d.ts +32 -14
  21. package/dist/cjs/types/engine/EngineCommands.d.ts +4 -1
  22. package/dist/cjs/types/engine/LinkRoutingService.d.ts +35 -0
  23. package/dist/cjs/types/engine/MutationPipeline.d.ts +23 -0
  24. package/dist/cjs/types/engine/TextLayoutService.d.ts +40 -0
  25. package/dist/cjs/types/examples/index.d.ts +2 -0
  26. package/dist/cjs/types/measure/textStyleDefaults.d.ts +9 -0
  27. package/dist/cjs/types/models/DiagramModel.d.ts +1 -0
  28. package/dist/cjs/types/models/ElementModel.d.ts +1 -0
  29. package/dist/cjs/types/models/PortModel.d.ts +3 -0
  30. package/dist/cjs/types/models/TextModel.d.ts +8 -0
  31. package/dist/cjs/types/renderer/RenderTypes.d.ts +34 -1
  32. package/dist/cjs/types/renderer/konva/KonvaHitTester.d.ts +1 -1
  33. package/dist/cjs/types/renderer/konva/KonvaInteraction.d.ts +53 -3
  34. package/dist/cjs/types/renderer/konva/KonvaNodeFactory.d.ts +18 -1
  35. package/dist/cjs/types/renderer/konva/KonvaRenderer.d.ts +49 -2
  36. package/dist/cjs/types/shapes/BuiltInShapes.d.ts +107 -0
  37. package/dist/cjs/types/shapes/__tests__/BuiltInShapes.test.d.ts +1 -0
  38. package/dist/cjs/types/shapes/index.d.ts +1 -0
  39. package/dist/cjs/types/utils/__tests__/borderGeometry.test.d.ts +1 -0
  40. package/dist/cjs/types/utils/borderGeometry.d.ts +6 -0
  41. package/dist/cjs/types/utils/geometry.d.ts +22 -0
  42. package/dist/esm/examples.js +11767 -0
  43. package/dist/esm/examples.js.map +1 -0
  44. package/dist/esm/index.js +3890 -1113
  45. package/dist/esm/index.js.map +1 -1
  46. package/dist/esm/types/api/createDiagramEditor.d.ts +7 -2
  47. package/dist/esm/types/api/types.d.ts +178 -0
  48. package/dist/esm/types/displaybox/demos/DeletionEventsDemoTab.d.ts +3 -0
  49. package/dist/esm/types/displaybox/demos/ShapeHoverControlsDemoTab.d.ts +3 -0
  50. package/dist/esm/types/displaybox/demos/TextLayoutDemoTab.d.ts +3 -0
  51. package/dist/esm/types/displaybox/demos/deletionEventsDemo.d.ts +2 -0
  52. package/dist/esm/types/displaybox/demos/rotatedCreationDemo.d.ts +2 -0
  53. package/dist/esm/types/displaybox/demos/roundedRectRadiusDemo.d.ts +2 -0
  54. package/dist/esm/types/displaybox/demos/shapeBorderMovementDemo.d.ts +2 -0
  55. package/dist/esm/types/displaybox/demos/shapeHoverControlsDemo.d.ts +10 -0
  56. package/dist/esm/types/displaybox/demos/textDemo.d.ts +4 -0
  57. package/dist/esm/types/displaybox/useDemoEditor.d.ts +5 -2
  58. package/dist/esm/types/engine/AutoLayoutService.d.ts +24 -0
  59. package/dist/esm/types/engine/DiagramEngine.d.ts +32 -14
  60. package/dist/esm/types/engine/EngineCommands.d.ts +4 -1
  61. package/dist/esm/types/engine/LinkRoutingService.d.ts +35 -0
  62. package/dist/esm/types/engine/MutationPipeline.d.ts +23 -0
  63. package/dist/esm/types/engine/TextLayoutService.d.ts +40 -0
  64. package/dist/esm/types/examples/index.d.ts +2 -0
  65. package/dist/esm/types/measure/textStyleDefaults.d.ts +9 -0
  66. package/dist/esm/types/models/DiagramModel.d.ts +1 -0
  67. package/dist/esm/types/models/ElementModel.d.ts +1 -0
  68. package/dist/esm/types/models/PortModel.d.ts +3 -0
  69. package/dist/esm/types/models/TextModel.d.ts +8 -0
  70. package/dist/esm/types/renderer/RenderTypes.d.ts +34 -1
  71. package/dist/esm/types/renderer/konva/KonvaHitTester.d.ts +1 -1
  72. package/dist/esm/types/renderer/konva/KonvaInteraction.d.ts +53 -3
  73. package/dist/esm/types/renderer/konva/KonvaNodeFactory.d.ts +18 -1
  74. package/dist/esm/types/renderer/konva/KonvaRenderer.d.ts +49 -2
  75. package/dist/esm/types/shapes/BuiltInShapes.d.ts +107 -0
  76. package/dist/esm/types/shapes/__tests__/BuiltInShapes.test.d.ts +1 -0
  77. package/dist/esm/types/shapes/index.d.ts +1 -0
  78. package/dist/esm/types/utils/__tests__/borderGeometry.test.d.ts +1 -0
  79. package/dist/esm/types/utils/borderGeometry.d.ts +6 -0
  80. package/dist/esm/types/utils/geometry.d.ts +22 -0
  81. package/dist/examples.d.ts +532 -0
  82. package/dist/index.d.ts +233 -2
  83. package/docs/API_CONTRACT.md +59 -3
  84. package/docs/ARCHITECTURE.md +1 -0
  85. package/docs/CAPABILITIES.md +3 -1
  86. package/docs/COMMANDS_EVENTS.md +5 -0
  87. package/docs/DOCUMENTATION_WORKFLOW.md +6 -8
  88. package/docs/INTEGRATION_PLAYBOOK.md +2 -0
  89. package/docs/PORTING_CHECKLIST.md +1 -0
  90. package/docs/STATE_INVARIANTS.md +4 -0
  91. package/package.json +20 -10
  92. package/src/displaybox/demos/AutoLayoutDemoTab.tsx +501 -0
  93. package/src/displaybox/demos/DeletionEventsDemoTab.tsx +147 -0
  94. package/src/displaybox/demos/EngineEventsDemoTab.tsx +151 -0
  95. package/src/displaybox/demos/EventHandlersDemoTab.tsx +110 -0
  96. package/src/displaybox/demos/ExternalDragDropDemoTab.tsx +261 -0
  97. package/src/displaybox/demos/LinkCancelDemoTab.tsx +238 -0
  98. package/src/displaybox/demos/ObstacleRoutingDemoTab.tsx +30 -0
  99. package/src/displaybox/demos/ShapeHoverControlsDemoTab.tsx +558 -0
  100. package/src/displaybox/demos/SimpleDemo.tsx +73 -0
  101. package/src/displaybox/demos/SvgPathDemoTab.tsx +327 -0
  102. package/src/displaybox/demos/TextLayoutDemoTab.tsx +386 -0
  103. package/src/displaybox/demos/autoLayoutDemo.ts +111 -0
  104. package/src/displaybox/demos/basicDemo.ts +131 -0
  105. package/src/displaybox/demos/childConstraintsDemo.ts +65 -0
  106. package/src/displaybox/demos/customDemo.ts +59 -0
  107. package/src/displaybox/demos/deletionEventsDemo.ts +91 -0
  108. package/src/displaybox/demos/engineEventsDemo.ts +64 -0
  109. package/src/displaybox/demos/eventHandlersDemo.ts +41 -0
  110. package/src/displaybox/demos/externalDragDropDemo.ts +28 -0
  111. package/src/displaybox/demos/gridOverlayDemo.ts +50 -0
  112. package/src/displaybox/demos/index.tsx +217 -0
  113. package/src/displaybox/demos/linkBendHandlesDemo.ts +143 -0
  114. package/src/displaybox/demos/linkCancelDemo.ts +56 -0
  115. package/src/displaybox/demos/linkPortCreationDemo.ts +46 -0
  116. package/src/displaybox/demos/multiLevelTreeDemo.ts +120 -0
  117. package/src/displaybox/demos/multipleElementsDemo.ts +62 -0
  118. package/src/displaybox/demos/nestedDemo.ts +78 -0
  119. package/src/displaybox/demos/obstacleRoutingDemo.ts +176 -0
  120. package/src/displaybox/demos/portBorderDemo.ts +98 -0
  121. package/src/displaybox/demos/portConstraintsDemo.ts +175 -0
  122. package/src/displaybox/demos/rotatedCreationDemo.ts +185 -0
  123. package/src/displaybox/demos/roundedRectRadiusDemo.ts +93 -0
  124. package/src/displaybox/demos/routingDemo.ts +57 -0
  125. package/src/displaybox/demos/selectionDemo.ts +49 -0
  126. package/src/displaybox/demos/shapeBorderMovementDemo.ts +126 -0
  127. package/src/displaybox/demos/shapeGalleryDemo.ts +73 -0
  128. package/src/displaybox/demos/shapeHoverControlsDemo.ts +172 -0
  129. package/src/displaybox/demos/shared.ts +161 -0
  130. package/src/displaybox/demos/svgPathDemo.ts +71 -0
  131. package/src/displaybox/demos/textDemo.ts +62 -0
  132. package/src/displaybox/types.ts +66 -0
  133. package/src/examples/index.ts +21 -0
@@ -0,0 +1,238 @@
1
+ import React, { useEffect, useMemo, useRef, useState } from 'react';
2
+ import type { ElementLinkConnectingEvent, ElementLinkEndedEvent } 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 { linkCancelDemoConfig } from './linkCancelDemo';
10
+
11
+ type LinkEndedWithMeta = ElementLinkEndedEvent & { cancelledByHost?: boolean };
12
+ type LinkConnectingSnapshot = Omit<ElementLinkConnectingEvent, 'cancel'>;
13
+
14
+ const badgeStyle: React.CSSProperties = {
15
+ display: 'inline-flex',
16
+ alignItems: 'center',
17
+ gap: 8,
18
+ padding: '6px 10px',
19
+ borderRadius: 10,
20
+ fontWeight: 600,
21
+ background: '#f3f4f6',
22
+ border: '1px solid #d0d5dd',
23
+ };
24
+
25
+ const LinkCancelDemo = () => {
26
+ const demo = linkCancelDemoConfig;
27
+ const { containerRef, editorRef, diagramState, selection, snapEnabled, setSnapEnabled } = useDemoEditor({
28
+ createState: demo.createState,
29
+ elementShapes: demo.elementShapes,
30
+ portShapes: demo.portShapes,
31
+ });
32
+
33
+ const nextOffset = useOffsetSequence();
34
+ const actionHelpers: DemoActionHelpers = useMemo(() => ({ nextOffset }), [nextOffset]);
35
+
36
+ const controls = useDemoControls({
37
+ demo,
38
+ editorRef,
39
+ diagramState,
40
+ selection,
41
+ snapEnabled,
42
+ setSnapEnabled,
43
+ actionHelpers,
44
+ });
45
+
46
+ const [lastEvent, setLastEvent] = useState<LinkEndedWithMeta | null>(null);
47
+ const [history, setHistory] = useState<LinkEndedWithMeta[]>([]);
48
+ const [hostCancels, setHostCancels] = useState<boolean>(true);
49
+ const [lastConnecting, setLastConnecting] = useState<LinkConnectingSnapshot | null>(null);
50
+ const cancelledByHostRef = useRef(false);
51
+
52
+ useEffect(() => {
53
+ const editor = editorRef.current;
54
+ if (!editor) return undefined;
55
+ setLastEvent(null);
56
+ setHistory([]);
57
+ return editor.on('elementLinkEnded', (payload) => {
58
+ const withMeta: LinkEndedWithMeta = {
59
+ ...payload,
60
+ cancelledByHost: payload.cancelled && cancelledByHostRef.current,
61
+ };
62
+ cancelledByHostRef.current = false;
63
+ setLastEvent(withMeta);
64
+ setHistory((prev) => [withMeta, ...prev].slice(0, 6));
65
+ });
66
+ }, [editorRef]);
67
+
68
+ useEffect(() => {
69
+ const editor = editorRef.current;
70
+ if (!editor) return undefined;
71
+ setLastConnecting(null);
72
+ return editor.on('elementLinkConnecting', (payload) => {
73
+ cancelledByHostRef.current = false;
74
+ if (hostCancels) {
75
+ payload.cancel();
76
+ cancelledByHostRef.current = true;
77
+ }
78
+ setLastConnecting({
79
+ sourcePortId: payload.sourcePortId,
80
+ sourceElementId: payload.sourceElementId,
81
+ targetPortId: payload.targetPortId,
82
+ targetElementId: payload.targetElementId,
83
+ cancelled: payload.cancelled,
84
+ });
85
+ });
86
+ }, [editorRef, hostCancels]);
87
+
88
+ const statusLabel = lastEvent
89
+ ? lastEvent.cancelled
90
+ ? lastEvent.cancelledByHost
91
+ ? 'Cancelled by host'
92
+ : 'Cancelled'
93
+ : 'Link created'
94
+ : 'Awaiting drag';
95
+ const statusColor = lastEvent ? (lastEvent.cancelled ? '#b42318' : '#027a48') : '#444';
96
+ const statusTone = lastEvent ? (lastEvent.cancelled ? '#fee4e2' : '#eaf6ec') : '#f3f4f6';
97
+
98
+ return (
99
+ <section>
100
+ <div style={{ marginBottom: 12 }}>
101
+ <h2 style={{ marginTop: 0, marginBottom: 4 }}>{demo.title}</h2>
102
+ <p style={{ marginTop: 0 }}>
103
+ Start a link drag from the left port and enter the right port area to complete immediately (before mouse
104
+ up). Drop on empty canvas to cancel. Use the toggle to simulate host-driven cancellation; payloads from
105
+ <code> elementLinkConnecting</code> and <code>elementLinkEnded</code> appear below.
106
+ </p>
107
+ </div>
108
+ <DisplayBoxControls
109
+ actions={demo.actions}
110
+ snapEnabled={controls.snapEnabled}
111
+ selectedLinkRouting={controls.selectedLinkRouting}
112
+ canToggleLinkRouting={controls.canToggleLinkRouting}
113
+ onReload={controls.handleReload}
114
+ onZoomIn={controls.handleZoomIn}
115
+ onZoomOut={controls.handleZoomOut}
116
+ onResetViewport={controls.handleResetViewport}
117
+ onToggleSnap={controls.handleToggleSnap}
118
+ onManualRender={controls.handleManualRender}
119
+ onToggleLinkRouting={controls.handleToggleLinkRouting}
120
+ onAction={controls.handleAction}
121
+ />
122
+ <div style={{ display: 'grid', gap: 12, marginBottom: 12 }}>
123
+ <div style={{ display: 'flex', flexWrap: 'wrap', gap: 12, alignItems: 'center' }}>
124
+ <span style={{ ...badgeStyle, background: statusTone, color: statusColor, borderColor: statusColor }}>
125
+ <span
126
+ style={{
127
+ width: 10,
128
+ height: 10,
129
+ borderRadius: '50%',
130
+ background: statusColor,
131
+ display: 'inline-block',
132
+ }}
133
+ />
134
+ {statusLabel}
135
+ </span>
136
+ <label style={{ display: 'inline-flex', alignItems: 'center', gap: 8, fontSize: 13 }}>
137
+ <input
138
+ type="checkbox"
139
+ checked={hostCancels}
140
+ onChange={(event) => setHostCancels(event.target.checked)}
141
+ />
142
+ Cancel link drops from host
143
+ </label>
144
+ {lastEvent && (
145
+ <div style={{ fontSize: 12, color: '#333' }}>
146
+ {lastEvent.cancelled
147
+ ? lastEvent.cancelledByHost
148
+ ? 'Host cancelled this drop.'
149
+ : 'Drop missed a valid port.'
150
+ : `Link ${lastEvent.linkId ?? '(generated)'} connected ${lastEvent.sourcePortId} → ${lastEvent.targetPortId}`}
151
+ </div>
152
+ )}
153
+ </div>
154
+ <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
155
+ <div>
156
+ <label style={{ display: 'block', fontWeight: 600, marginBottom: 6 }}>Latest connecting payload</label>
157
+ <textarea
158
+ readOnly
159
+ value={lastConnecting ? JSON.stringify(lastConnecting, null, 2) : ''}
160
+ placeholder="Hover a destination port to see elementLinkConnecting."
161
+ style={{
162
+ width: '100%',
163
+ minHeight: 170,
164
+ padding: '8px 10px',
165
+ borderRadius: 8,
166
+ border: '1px solid #d0d5dd',
167
+ background: '#fff',
168
+ fontFamily:
169
+ 'ui-monospace, SFMono-Regular, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',
170
+ fontSize: 12,
171
+ resize: 'vertical',
172
+ }}
173
+ />
174
+ </div>
175
+ <div>
176
+ <label style={{ display: 'block', fontWeight: 600, marginBottom: 6 }}>Latest ended payload</label>
177
+ <textarea
178
+ readOnly
179
+ value={lastEvent ? JSON.stringify(lastEvent, null, 2) : ''}
180
+ placeholder="Drag a link to see the payload."
181
+ style={{
182
+ width: '100%',
183
+ minHeight: 170,
184
+ padding: '8px 10px',
185
+ borderRadius: 8,
186
+ border: '1px solid #d0d5dd',
187
+ background: '#fff',
188
+ fontFamily:
189
+ 'ui-monospace, SFMono-Regular, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',
190
+ fontSize: 12,
191
+ resize: 'vertical',
192
+ }}
193
+ />
194
+ </div>
195
+ <div>
196
+ <label style={{ display: 'block', fontWeight: 600, marginBottom: 6 }}>Recent drags</label>
197
+ <div
198
+ style={{
199
+ display: 'grid',
200
+ gap: 8,
201
+ padding: 8,
202
+ borderRadius: 8,
203
+ border: '1px solid #e0e0e0',
204
+ background: '#fafafa',
205
+ }}
206
+ >
207
+ {history.length === 0 && <div style={{ color: '#666', fontSize: 12 }}>No drags yet.</div>}
208
+ {history.map((event, index) => (
209
+ <div
210
+ key={`${event.sourcePortId}-${event.targetPortId ?? 'none'}-${index}`}
211
+ style={{
212
+ padding: 8,
213
+ borderRadius: 6,
214
+ background: event.cancelled ? '#fff4f3' : '#f1f8f4',
215
+ border: `1px solid ${event.cancelled ? '#f2b8b5' : '#b9dfc7'}`,
216
+ fontSize: 12,
217
+ }}
218
+ >
219
+ <div style={{ fontWeight: 600, marginBottom: 4 }}>
220
+ {event.cancelled ? (event.cancelledByHost ? 'Cancelled by host' : 'Cancelled') : 'Created'} —{' '}
221
+ {new Date().toLocaleTimeString()}
222
+ </div>
223
+ <div>sourcePortId: {event.sourcePortId}</div>
224
+ <div>targetPortId: {event.targetPortId ?? '—'}</div>
225
+ <div>linkId: {event.linkId ?? '—'}</div>
226
+ {event.targetElementId && <div>targetElementId: {event.targetElementId}</div>}
227
+ </div>
228
+ ))}
229
+ </div>
230
+ </div>
231
+ </div>
232
+ </div>
233
+ <DisplayBoxStage containerRef={containerRef} />
234
+ </section>
235
+ );
236
+ };
237
+
238
+ export default LinkCancelDemo;
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import SimpleDemo from './SimpleDemo';
3
+ import { obstacleRoutingDemoConfig } from './obstacleRoutingDemo';
4
+
5
+ const ObstacleRoutingDemo = () => (
6
+ <SimpleDemo
7
+ demo={obstacleRoutingDemoConfig}
8
+ beforeStage={
9
+ <div
10
+ style={{
11
+ marginBottom: 12,
12
+ padding: '10px 12px',
13
+ borderRadius: 8,
14
+ border: '1px solid #2d2d2d',
15
+ background: '#f4f4f4',
16
+ }}
17
+ >
18
+ <strong>Expected routing behavior</strong>
19
+ <ul style={{ margin: '6px 0 0 16px' }}>
20
+ <li>Links between top nodes should route around the blocking element.</li>
21
+ <li>Sibling links inside a shared parent should ignore the parent as an obstacle.</li>
22
+ <li>Parent-child links should stay within the parent and avoid the child interior when ports are on edges.</li>
23
+ <li>Grandchild links should ignore shared ancestors (parent + grandparent containers).</li>
24
+ </ul>
25
+ </div>
26
+ }
27
+ />
28
+ );
29
+
30
+ export default ObstacleRoutingDemo;