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.
- package/CHANGELOG.md +27 -0
- package/README.md +15 -7
- package/ai/api-contract.json +90 -1
- package/ai/invariants.json +6 -2
- package/ai/manifest.json +1 -1
- package/dist/cjs/examples.js +916 -331
- package/dist/cjs/index.js +406 -97
- package/dist/cjs/types/api/createDiagramEditor.d.ts +3 -1
- package/dist/cjs/types/api/types.d.ts +64 -0
- package/dist/cjs/types/displaybox/demos/LinkPortCreationDemoTab.d.ts +3 -0
- package/dist/cjs/types/displaybox/demos/deletionEventsDemo.d.ts +2 -0
- package/dist/cjs/types/displaybox/demos/focusElementDemo.d.ts +4 -0
- package/dist/cjs/types/displaybox/demos/linkLabelsDemo.d.ts +4 -0
- package/dist/cjs/types/displaybox/types.d.ts +3 -0
- package/dist/cjs/types/displaybox/useDemoEditor.d.ts +3 -2
- package/dist/cjs/types/engine/DiagramEngine.d.ts +11 -1
- package/dist/cjs/types/engine/TextLayoutService.d.ts +1 -0
- package/dist/cjs/types/examples/index.d.ts +1 -1
- package/dist/cjs/types/renderer/konva/KonvaInteraction.d.ts +10 -1
- package/dist/esm/examples.js +916 -331
- package/dist/esm/examples.js.map +1 -1
- package/dist/esm/index.js +406 -97
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/api/createDiagramEditor.d.ts +3 -1
- package/dist/esm/types/api/types.d.ts +64 -0
- package/dist/esm/types/displaybox/demos/LinkPortCreationDemoTab.d.ts +3 -0
- package/dist/esm/types/displaybox/demos/deletionEventsDemo.d.ts +2 -0
- package/dist/esm/types/displaybox/demos/focusElementDemo.d.ts +4 -0
- package/dist/esm/types/displaybox/demos/linkLabelsDemo.d.ts +4 -0
- package/dist/esm/types/displaybox/types.d.ts +3 -0
- package/dist/esm/types/displaybox/useDemoEditor.d.ts +3 -2
- package/dist/esm/types/engine/DiagramEngine.d.ts +11 -1
- package/dist/esm/types/engine/TextLayoutService.d.ts +1 -0
- package/dist/esm/types/examples/index.d.ts +1 -1
- package/dist/esm/types/renderer/konva/KonvaInteraction.d.ts +10 -1
- package/dist/examples.d.ts +55 -1
- package/dist/index.d.ts +67 -1
- package/docs/API_CONTRACT.md +88 -1
- package/docs/ARCHITECTURE.md +9 -7
- package/docs/CAPABILITIES.md +5 -0
- package/docs/COMMANDS_EVENTS.md +16 -6
- package/docs/DOCUMENTATION_WORKFLOW.md +5 -1
- package/docs/INTEGRATION_PLAYBOOK.md +8 -0
- package/docs/PORTING_CHECKLIST.md +4 -1
- package/docs/STATE_INVARIANTS.md +3 -0
- package/package.json +1 -1
- package/src/displaybox/demos/DeletionEventsDemoTab.tsx +167 -9
- package/src/displaybox/demos/LinkPortCreationDemoTab.tsx +98 -0
- package/src/displaybox/demos/deletionEventsDemo.ts +2 -2
- package/src/displaybox/demos/focusElementDemo.ts +91 -0
- package/src/displaybox/demos/index.tsx +124 -221
- package/src/displaybox/demos/linkLabelsDemo.ts +164 -0
- package/src/displaybox/demos/linkPortCreationDemo.ts +7 -7
- package/src/displaybox/types.ts +21 -11
- package/src/examples/index.ts +1 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import type { DiagramEditorHandle, DiagramState, Point } from '../../api';
|
|
2
|
+
import type { DemoConfig } from '../types';
|
|
3
|
+
import { baseElementShapes, basePortShapes } from './shared';
|
|
4
|
+
|
|
5
|
+
const linkLabelDemoSourceId = 'link-label-source';
|
|
6
|
+
const linkLabelDemoTargetId = 'link-label-target';
|
|
7
|
+
const linkLabelDemoLinkId = 'link-label-link';
|
|
8
|
+
const linkLabelDemoTextId = 'link-label-text';
|
|
9
|
+
|
|
10
|
+
const resolveLinkMidpoint = (points: Point[]): Point => {
|
|
11
|
+
if (points.length === 0) return { x: 0, y: 0 };
|
|
12
|
+
if (points.length === 1) return { ...points[0] };
|
|
13
|
+
|
|
14
|
+
let total = 0;
|
|
15
|
+
for (let index = 1; index < points.length; index += 1) {
|
|
16
|
+
total += Math.hypot(points[index].x - points[index - 1].x, points[index].y - points[index - 1].y);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const halfway = total / 2;
|
|
20
|
+
let travelled = 0;
|
|
21
|
+
for (let index = 1; index < points.length; index += 1) {
|
|
22
|
+
const segment = Math.hypot(points[index].x - points[index - 1].x, points[index].y - points[index - 1].y);
|
|
23
|
+
if (travelled + segment >= halfway) {
|
|
24
|
+
const ratio = segment === 0 ? 0 : (halfway - travelled) / segment;
|
|
25
|
+
return {
|
|
26
|
+
x: points[index - 1].x + (points[index].x - points[index - 1].x) * ratio,
|
|
27
|
+
y: points[index - 1].y + (points[index].y - points[index - 1].y) * ratio,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
travelled += segment;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return { ...points[points.length - 1] };
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const nudgeLinkLabel = (editor: DiagramEditorHandle, state: DiagramState) => {
|
|
37
|
+
const link = state.links.find((item) => item.id === linkLabelDemoLinkId);
|
|
38
|
+
const label = state.texts.find((item) => item.id === linkLabelDemoTextId);
|
|
39
|
+
if (!link || !label) return;
|
|
40
|
+
const midpoint = resolveLinkMidpoint(link.points);
|
|
41
|
+
editor.moveTextTo(linkLabelDemoTextId, midpoint.x + 72, midpoint.y - 24);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const createLinkLabelsState = (): DiagramState => ({
|
|
45
|
+
elements: [
|
|
46
|
+
{
|
|
47
|
+
id: linkLabelDemoSourceId,
|
|
48
|
+
position: { x: 120, y: 180 },
|
|
49
|
+
size: { width: 220, height: 120 },
|
|
50
|
+
shapeId: 'default',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: linkLabelDemoTargetId,
|
|
54
|
+
position: { x: 500, y: 220 },
|
|
55
|
+
size: { width: 220, height: 140 },
|
|
56
|
+
shapeId: 'panel',
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
ports: [
|
|
60
|
+
{
|
|
61
|
+
id: 'link-label-source-port',
|
|
62
|
+
elementId: linkLabelDemoSourceId,
|
|
63
|
+
position: { x: 220, y: 60 },
|
|
64
|
+
shapeId: 'port-circle',
|
|
65
|
+
moveMode: 'border',
|
|
66
|
+
anchorCenter: true,
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: 'link-label-target-port',
|
|
70
|
+
elementId: linkLabelDemoTargetId,
|
|
71
|
+
position: { x: 0, y: 70 },
|
|
72
|
+
shapeId: 'port-circle',
|
|
73
|
+
moveMode: 'border',
|
|
74
|
+
anchorCenter: true,
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
links: [
|
|
78
|
+
{
|
|
79
|
+
id: linkLabelDemoLinkId,
|
|
80
|
+
sourcePortId: 'link-label-source-port',
|
|
81
|
+
targetPortId: 'link-label-target-port',
|
|
82
|
+
points: [],
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
texts: [
|
|
86
|
+
{
|
|
87
|
+
id: `${linkLabelDemoSourceId}-label`,
|
|
88
|
+
content: 'Source node',
|
|
89
|
+
position: { x: 12, y: -14 },
|
|
90
|
+
ownerId: linkLabelDemoSourceId,
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: `${linkLabelDemoTargetId}-label`,
|
|
94
|
+
content: 'Move me, reroute me',
|
|
95
|
+
position: { x: 12, y: -14 },
|
|
96
|
+
ownerId: linkLabelDemoTargetId,
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: linkLabelDemoTextId,
|
|
100
|
+
content: 'I am just owned text',
|
|
101
|
+
position: { x: 0, y: -24 },
|
|
102
|
+
ownerId: linkLabelDemoLinkId,
|
|
103
|
+
layout: {
|
|
104
|
+
boundsMode: 'fixed',
|
|
105
|
+
fixedSize: { width: 160, height: 24 },
|
|
106
|
+
wrap: 'none',
|
|
107
|
+
overflow: 'ellipsis-end',
|
|
108
|
+
},
|
|
109
|
+
style: {
|
|
110
|
+
fill: '#1f2937',
|
|
111
|
+
backgroundFill: '#fef3c7',
|
|
112
|
+
padding: 4,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
id: 'link-label-tip',
|
|
117
|
+
content: 'This label is TextData owned by the link. Drag or edit it, reroute the link, then delete the link to confirm the label follows and cascades away.',
|
|
118
|
+
position: { x: 120, y: 110 },
|
|
119
|
+
layout: {
|
|
120
|
+
boundsMode: 'fixed',
|
|
121
|
+
fixedSize: { width: 620, height: 44 },
|
|
122
|
+
wrap: 'word',
|
|
123
|
+
overflow: 'clip',
|
|
124
|
+
padding: 0,
|
|
125
|
+
},
|
|
126
|
+
style: {
|
|
127
|
+
fill: '#475569',
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
export const linkLabelsDemoConfig: DemoConfig = {
|
|
134
|
+
id: 'link-labels',
|
|
135
|
+
title: 'Link Labels',
|
|
136
|
+
description: 'Link-owned text stays anchored to the route midpoint. Drag or edit the label, reroute the link, then delete the link to watch the owned text disappear with it.',
|
|
137
|
+
createState: createLinkLabelsState,
|
|
138
|
+
elementShapes: baseElementShapes,
|
|
139
|
+
portShapes: basePortShapes,
|
|
140
|
+
defaultElementShapeId: 'default',
|
|
141
|
+
defaultPortShapeId: 'port-circle',
|
|
142
|
+
actions: [
|
|
143
|
+
{
|
|
144
|
+
id: 'link-label-offset',
|
|
145
|
+
label: 'Offset label via API',
|
|
146
|
+
run: (editor, state) => nudgeLinkLabel(editor, state),
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
id: 'link-label-reroute',
|
|
150
|
+
label: 'Move target + reroute',
|
|
151
|
+
run: (editor) => {
|
|
152
|
+
editor.moveElementTo(linkLabelDemoTargetId, 660, 320);
|
|
153
|
+
editor.rerouteAllLinks();
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
id: 'link-label-delete',
|
|
158
|
+
label: 'Delete labeled link',
|
|
159
|
+
run: (editor) => {
|
|
160
|
+
editor.removeLink(linkLabelDemoLinkId);
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
};
|
|
@@ -33,13 +33,13 @@ const createLinkPortCreationState = (): DiagramState => ({
|
|
|
33
33
|
],
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
-
export const linkPortCreationDemoConfig: DemoConfig = ({
|
|
37
|
-
id: 'link-port-creation',
|
|
38
|
-
title: 'Link Creates Port',
|
|
39
|
-
description: 'Drag from a port to an element to auto-create a target port.',
|
|
40
|
-
createState: createLinkPortCreationState,
|
|
41
|
-
elementShapes: baseElementShapes,
|
|
42
|
-
portShapes: basePortShapes,
|
|
36
|
+
export const linkPortCreationDemoConfig: DemoConfig = ({
|
|
37
|
+
id: 'link-port-creation',
|
|
38
|
+
title: 'Link Creates Port',
|
|
39
|
+
description: 'Drag from a port to an element to auto-create a target port, then compare default and host-customized target-port creation.',
|
|
40
|
+
createState: createLinkPortCreationState,
|
|
41
|
+
elementShapes: baseElementShapes,
|
|
42
|
+
portShapes: basePortShapes,
|
|
43
43
|
defaultElementShapeId: 'default',
|
|
44
44
|
defaultPortShapeId: 'port-circle',
|
|
45
45
|
actions: [],
|
package/src/displaybox/types.ts
CHANGED
|
@@ -17,10 +17,10 @@ export type DemoAction = {
|
|
|
17
17
|
) => void;
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
export type DemoConfig = {
|
|
21
|
-
id: string;
|
|
22
|
-
title: string;
|
|
23
|
-
description: string;
|
|
20
|
+
export type DemoConfig = {
|
|
21
|
+
id: string;
|
|
22
|
+
title: string;
|
|
23
|
+
description: string;
|
|
24
24
|
createState: () => DiagramState;
|
|
25
25
|
elementShapes?: SimpleShape[];
|
|
26
26
|
portShapes?: SimpleShape[];
|
|
@@ -33,13 +33,23 @@ export type DemoConfig = {
|
|
|
33
33
|
stageStyle?: CSSProperties;
|
|
34
34
|
actions: DemoAction[];
|
|
35
35
|
};
|
|
36
|
-
|
|
37
|
-
export type
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
|
|
37
|
+
export type DemoMenuGroup =
|
|
38
|
+
| 'basics'
|
|
39
|
+
| 'layoutText'
|
|
40
|
+
| 'shapes'
|
|
41
|
+
| 'portsAnchors'
|
|
42
|
+
| 'linksRouting'
|
|
43
|
+
| 'eventsIntegration';
|
|
44
|
+
|
|
45
|
+
export type DemoDefinition = {
|
|
46
|
+
id: string;
|
|
47
|
+
title: string;
|
|
48
|
+
description: string;
|
|
49
|
+
Component: React.ComponentType;
|
|
50
|
+
menuGroup: DemoMenuGroup;
|
|
51
|
+
menuOrder: number;
|
|
52
|
+
};
|
|
43
53
|
|
|
44
54
|
export type ToolboxItem = {
|
|
45
55
|
id: string;
|