@bpmnkit/editor 0.0.8
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 +121 -0
- package/dist/command-stack.d.ts +23 -0
- package/dist/command-stack.js +48 -0
- package/dist/css.d.ts +15 -0
- package/dist/css.js +722 -0
- package/dist/dock.d.ts +35 -0
- package/dist/dock.js +406 -0
- package/dist/editor.d.ts +165 -0
- package/dist/editor.js +1977 -0
- package/dist/element-groups.d.ts +14 -0
- package/dist/element-groups.js +195 -0
- package/dist/geometry.d.ts +89 -0
- package/dist/geometry.js +450 -0
- package/dist/hud.d.ts +85 -0
- package/dist/hud.js +1631 -0
- package/dist/icons.d.ts +61 -0
- package/dist/icons.js +75 -0
- package/dist/id.d.ts +2 -0
- package/dist/id.js +4 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +6 -0
- package/dist/label-editor.d.ts +23 -0
- package/dist/label-editor.js +94 -0
- package/dist/modal.d.ts +6 -0
- package/dist/modal.js +141 -0
- package/dist/modeling.d.ts +91 -0
- package/dist/modeling.js +1473 -0
- package/dist/overlay.d.ts +59 -0
- package/dist/overlay.js +455 -0
- package/dist/rules.d.ts +10 -0
- package/dist/rules.js +17 -0
- package/dist/state-machine.d.ts +174 -0
- package/dist/state-machine.js +588 -0
- package/dist/types.d.ts +61 -0
- package/dist/types.js +17 -0
- package/package.json +31 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { RenderedShape } from "@bpmnkit/canvas";
|
|
2
|
+
import type { BpmnBounds, BpmnWaypoint } from "@bpmnkit/core";
|
|
3
|
+
import type { CreateShapeType, DiagPoint } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Renders editor overlays (selection handles, connection ports, rubber-band,
|
|
6
|
+
* resize preview, ghost shapes) inside a dedicated SVG group that lives in
|
|
7
|
+
* the viewport's coordinate space.
|
|
8
|
+
*/
|
|
9
|
+
export declare class OverlayRenderer {
|
|
10
|
+
private readonly _g;
|
|
11
|
+
private readonly _markerId;
|
|
12
|
+
private readonly _selectionG;
|
|
13
|
+
private readonly _portsG;
|
|
14
|
+
private readonly _rubberG;
|
|
15
|
+
private readonly _resizePreviewG;
|
|
16
|
+
private readonly _ghostConnG;
|
|
17
|
+
private readonly _boundaryHostG;
|
|
18
|
+
private readonly _ghostCreateG;
|
|
19
|
+
private readonly _alignG;
|
|
20
|
+
private readonly _distG;
|
|
21
|
+
private readonly _edgeEndpointsG;
|
|
22
|
+
private readonly _endpointGhostG;
|
|
23
|
+
private readonly _spaceG;
|
|
24
|
+
private readonly _edgeHoverDotG;
|
|
25
|
+
private readonly _edgeWaypointsG;
|
|
26
|
+
constructor(overlayGroup: SVGGElement, markerId: string);
|
|
27
|
+
setSelection(ids: string[], shapes: RenderedShape[], resizableIds?: ReadonlySet<string>): void;
|
|
28
|
+
/** Hide the selection indicator group while dragging; restore it after. */
|
|
29
|
+
setDragging(isDragging: boolean): void;
|
|
30
|
+
setHovered(_id: string | null, _shapes: RenderedShape[]): void;
|
|
31
|
+
setAlignmentGuides(guides: Array<{
|
|
32
|
+
x1: number;
|
|
33
|
+
y1: number;
|
|
34
|
+
x2: number;
|
|
35
|
+
y2: number;
|
|
36
|
+
}>): void;
|
|
37
|
+
setDistanceGuides(guides: Array<{
|
|
38
|
+
x1: number;
|
|
39
|
+
y1: number;
|
|
40
|
+
x2: number;
|
|
41
|
+
y2: number;
|
|
42
|
+
}>): void;
|
|
43
|
+
setRubberBand(origin: DiagPoint | null, current?: DiagPoint): void;
|
|
44
|
+
setResizePreview(bounds: BpmnBounds | null): void;
|
|
45
|
+
setGhostConnection(waypoints: BpmnWaypoint[] | null): void;
|
|
46
|
+
setEdgeEndpoints(waypoints: BpmnWaypoint[] | null, edgeId: string): void;
|
|
47
|
+
setEndpointDragGhost(waypoints: BpmnWaypoint[] | null): void;
|
|
48
|
+
setSpacePreview(axis: "h" | "v" | null, splitValue?: number): void;
|
|
49
|
+
setGhostCreate(type: CreateShapeType | null, diag?: DiagPoint): void;
|
|
50
|
+
setEdgeHoverDot(pt: DiagPoint | null): void;
|
|
51
|
+
setEdgeWaypointBalls(waypoints: BpmnWaypoint[] | null, edgeId: string | null): void;
|
|
52
|
+
setBoundaryHostHighlight(shapeBounds: {
|
|
53
|
+
x: number;
|
|
54
|
+
y: number;
|
|
55
|
+
width: number;
|
|
56
|
+
height: number;
|
|
57
|
+
} | null): void;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=overlay.d.ts.map
|
package/dist/overlay.js
ADDED
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
import { handlePositions } from "./geometry.js";
|
|
2
|
+
const NS = "http://www.w3.org/2000/svg";
|
|
3
|
+
function svgEl(tag) {
|
|
4
|
+
return document.createElementNS(NS, tag);
|
|
5
|
+
}
|
|
6
|
+
function attr(el, attrs) {
|
|
7
|
+
for (const [k, v] of Object.entries(attrs))
|
|
8
|
+
el.setAttribute(k, String(v));
|
|
9
|
+
}
|
|
10
|
+
const HANDLE_SIZE = 7;
|
|
11
|
+
const ALL_HANDLES = ["nw", "n", "ne", "e", "se", "s", "sw", "w"];
|
|
12
|
+
/**
|
|
13
|
+
* Renders editor overlays (selection handles, connection ports, rubber-band,
|
|
14
|
+
* resize preview, ghost shapes) inside a dedicated SVG group that lives in
|
|
15
|
+
* the viewport's coordinate space.
|
|
16
|
+
*/
|
|
17
|
+
export class OverlayRenderer {
|
|
18
|
+
_g;
|
|
19
|
+
_markerId;
|
|
20
|
+
// Sub-groups for each overlay layer
|
|
21
|
+
_selectionG;
|
|
22
|
+
_portsG;
|
|
23
|
+
_rubberG;
|
|
24
|
+
_resizePreviewG;
|
|
25
|
+
_ghostConnG;
|
|
26
|
+
_boundaryHostG;
|
|
27
|
+
_ghostCreateG;
|
|
28
|
+
_alignG;
|
|
29
|
+
_distG;
|
|
30
|
+
_edgeEndpointsG;
|
|
31
|
+
_endpointGhostG;
|
|
32
|
+
_spaceG;
|
|
33
|
+
_edgeHoverDotG;
|
|
34
|
+
_edgeWaypointsG;
|
|
35
|
+
constructor(overlayGroup, markerId) {
|
|
36
|
+
this._g = overlayGroup;
|
|
37
|
+
this._markerId = markerId;
|
|
38
|
+
this._selectionG = svgEl("g");
|
|
39
|
+
this._portsG = svgEl("g");
|
|
40
|
+
this._rubberG = svgEl("g");
|
|
41
|
+
this._resizePreviewG = svgEl("g");
|
|
42
|
+
this._ghostConnG = svgEl("g");
|
|
43
|
+
this._boundaryHostG = svgEl("g");
|
|
44
|
+
this._ghostCreateG = svgEl("g");
|
|
45
|
+
this._alignG = svgEl("g");
|
|
46
|
+
this._distG = svgEl("g");
|
|
47
|
+
this._endpointGhostG = svgEl("g");
|
|
48
|
+
this._edgeEndpointsG = svgEl("g");
|
|
49
|
+
this._spaceG = svgEl("g");
|
|
50
|
+
this._edgeHoverDotG = svgEl("g");
|
|
51
|
+
this._edgeWaypointsG = svgEl("g");
|
|
52
|
+
this._g.appendChild(this._spaceG);
|
|
53
|
+
this._g.appendChild(this._boundaryHostG);
|
|
54
|
+
this._g.appendChild(this._ghostCreateG);
|
|
55
|
+
this._g.appendChild(this._ghostConnG);
|
|
56
|
+
this._g.appendChild(this._endpointGhostG);
|
|
57
|
+
this._g.appendChild(this._rubberG);
|
|
58
|
+
this._g.appendChild(this._resizePreviewG);
|
|
59
|
+
this._g.appendChild(this._alignG);
|
|
60
|
+
this._g.appendChild(this._distG);
|
|
61
|
+
this._g.appendChild(this._selectionG);
|
|
62
|
+
this._g.appendChild(this._portsG);
|
|
63
|
+
this._g.appendChild(this._edgeWaypointsG);
|
|
64
|
+
this._g.appendChild(this._edgeEndpointsG);
|
|
65
|
+
this._g.appendChild(this._edgeHoverDotG);
|
|
66
|
+
}
|
|
67
|
+
// ── Selection + handles ───────────────────────────────────────────
|
|
68
|
+
setSelection(ids, shapes, resizableIds) {
|
|
69
|
+
this._selectionG.innerHTML = "";
|
|
70
|
+
const selected = shapes.filter((s) => ids.includes(s.id));
|
|
71
|
+
if (selected.length === 0)
|
|
72
|
+
return;
|
|
73
|
+
const isSingle = selected.length === 1;
|
|
74
|
+
for (const shape of selected) {
|
|
75
|
+
const { x, y, width, height } = shape.shape.bounds;
|
|
76
|
+
// Selection outline
|
|
77
|
+
const outline = svgEl("rect");
|
|
78
|
+
attr(outline, {
|
|
79
|
+
class: "bpmnkit-sel-indicator",
|
|
80
|
+
x: x - 2,
|
|
81
|
+
y: y - 2,
|
|
82
|
+
width: width + 4,
|
|
83
|
+
height: height + 4,
|
|
84
|
+
rx: 2,
|
|
85
|
+
"data-bpmnkit-id": shape.id,
|
|
86
|
+
});
|
|
87
|
+
this._selectionG.appendChild(outline);
|
|
88
|
+
// Resize handles only for single selection of resizable elements
|
|
89
|
+
if (isSingle && resizableIds?.has(shape.id)) {
|
|
90
|
+
const positions = handlePositions(shape.shape.bounds);
|
|
91
|
+
for (const dir of ALL_HANDLES) {
|
|
92
|
+
const pos = positions[dir];
|
|
93
|
+
const handle = svgEl("rect");
|
|
94
|
+
attr(handle, {
|
|
95
|
+
class: "bpmnkit-resize-handle",
|
|
96
|
+
"data-bpmnkit-handle": dir,
|
|
97
|
+
"data-bpmnkit-id": shape.id,
|
|
98
|
+
x: pos.x - HANDLE_SIZE / 2,
|
|
99
|
+
y: pos.y - HANDLE_SIZE / 2,
|
|
100
|
+
width: HANDLE_SIZE,
|
|
101
|
+
height: HANDLE_SIZE,
|
|
102
|
+
});
|
|
103
|
+
this._selectionG.appendChild(handle);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** Hide the selection indicator group while dragging; restore it after. */
|
|
109
|
+
setDragging(isDragging) {
|
|
110
|
+
this._selectionG.style.display = isDragging ? "none" : "";
|
|
111
|
+
}
|
|
112
|
+
// ── Hover ports ───────────────────────────────────────────────────
|
|
113
|
+
setHovered(_id, _shapes) {
|
|
114
|
+
// Port balls removed — connections are initiated via the contextual toolbar
|
|
115
|
+
this._portsG.innerHTML = "";
|
|
116
|
+
}
|
|
117
|
+
// ── Alignment guides ──────────────────────────────────────────────
|
|
118
|
+
setAlignmentGuides(guides) {
|
|
119
|
+
this._alignG.innerHTML = "";
|
|
120
|
+
for (const guide of guides) {
|
|
121
|
+
const line = svgEl("line");
|
|
122
|
+
attr(line, {
|
|
123
|
+
class: "bpmnkit-align-guide",
|
|
124
|
+
x1: guide.x1,
|
|
125
|
+
y1: guide.y1,
|
|
126
|
+
x2: guide.x2,
|
|
127
|
+
y2: guide.y2,
|
|
128
|
+
});
|
|
129
|
+
this._alignG.appendChild(line);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// ── Distance guides ───────────────────────────────────────────────
|
|
133
|
+
setDistanceGuides(guides) {
|
|
134
|
+
this._distG.innerHTML = "";
|
|
135
|
+
const TICK = 4;
|
|
136
|
+
for (const g of guides) {
|
|
137
|
+
const isH = Math.abs(g.y2 - g.y1) < 0.5;
|
|
138
|
+
const main = svgEl("line");
|
|
139
|
+
attr(main, { class: "bpmnkit-dist-guide", x1: g.x1, y1: g.y1, x2: g.x2, y2: g.y2 });
|
|
140
|
+
this._distG.appendChild(main);
|
|
141
|
+
const t1 = svgEl("line");
|
|
142
|
+
const t2 = svgEl("line");
|
|
143
|
+
if (isH) {
|
|
144
|
+
attr(t1, {
|
|
145
|
+
class: "bpmnkit-dist-guide",
|
|
146
|
+
x1: g.x1,
|
|
147
|
+
y1: g.y1 - TICK,
|
|
148
|
+
x2: g.x1,
|
|
149
|
+
y2: g.y1 + TICK,
|
|
150
|
+
});
|
|
151
|
+
attr(t2, {
|
|
152
|
+
class: "bpmnkit-dist-guide",
|
|
153
|
+
x1: g.x2,
|
|
154
|
+
y1: g.y2 - TICK,
|
|
155
|
+
x2: g.x2,
|
|
156
|
+
y2: g.y2 + TICK,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
attr(t1, {
|
|
161
|
+
class: "bpmnkit-dist-guide",
|
|
162
|
+
x1: g.x1 - TICK,
|
|
163
|
+
y1: g.y1,
|
|
164
|
+
x2: g.x1 + TICK,
|
|
165
|
+
y2: g.y1,
|
|
166
|
+
});
|
|
167
|
+
attr(t2, {
|
|
168
|
+
class: "bpmnkit-dist-guide",
|
|
169
|
+
x1: g.x2 - TICK,
|
|
170
|
+
y1: g.y2,
|
|
171
|
+
x2: g.x2 + TICK,
|
|
172
|
+
y2: g.y2,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
this._distG.appendChild(t1);
|
|
176
|
+
this._distG.appendChild(t2);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// ── Rubber-band ────────────────────────────────────────────────────
|
|
180
|
+
setRubberBand(origin, current) {
|
|
181
|
+
this._rubberG.innerHTML = "";
|
|
182
|
+
if (!origin || !current)
|
|
183
|
+
return;
|
|
184
|
+
const x = Math.min(origin.x, current.x);
|
|
185
|
+
const y = Math.min(origin.y, current.y);
|
|
186
|
+
const width = Math.abs(current.x - origin.x);
|
|
187
|
+
const height = Math.abs(current.y - origin.y);
|
|
188
|
+
const rect = svgEl("rect");
|
|
189
|
+
attr(rect, { class: "bpmnkit-rubber-band", x, y, width, height });
|
|
190
|
+
this._rubberG.appendChild(rect);
|
|
191
|
+
}
|
|
192
|
+
// ── Resize preview ─────────────────────────────────────────────────
|
|
193
|
+
setResizePreview(bounds) {
|
|
194
|
+
this._resizePreviewG.innerHTML = "";
|
|
195
|
+
if (!bounds)
|
|
196
|
+
return;
|
|
197
|
+
const rect = svgEl("rect");
|
|
198
|
+
attr(rect, {
|
|
199
|
+
class: "bpmnkit-resize-preview",
|
|
200
|
+
x: bounds.x,
|
|
201
|
+
y: bounds.y,
|
|
202
|
+
width: bounds.width,
|
|
203
|
+
height: bounds.height,
|
|
204
|
+
});
|
|
205
|
+
this._resizePreviewG.appendChild(rect);
|
|
206
|
+
}
|
|
207
|
+
// ── Ghost connection ───────────────────────────────────────────────
|
|
208
|
+
setGhostConnection(waypoints) {
|
|
209
|
+
this._ghostConnG.innerHTML = "";
|
|
210
|
+
if (!waypoints || waypoints.length < 2)
|
|
211
|
+
return;
|
|
212
|
+
const points = waypoints.map((wp) => `${wp.x},${wp.y}`).join(" ");
|
|
213
|
+
const poly = svgEl("polyline");
|
|
214
|
+
attr(poly, {
|
|
215
|
+
class: "bpmnkit-ghost-conn",
|
|
216
|
+
points,
|
|
217
|
+
"marker-end": `url(#${this._markerId})`,
|
|
218
|
+
});
|
|
219
|
+
this._ghostConnG.appendChild(poly);
|
|
220
|
+
}
|
|
221
|
+
// ── Edge endpoint balls ────────────────────────────────────────────
|
|
222
|
+
setEdgeEndpoints(waypoints, edgeId) {
|
|
223
|
+
this._edgeEndpointsG.innerHTML = "";
|
|
224
|
+
if (!waypoints || waypoints.length < 2)
|
|
225
|
+
return;
|
|
226
|
+
const first = waypoints[0];
|
|
227
|
+
const last = waypoints[waypoints.length - 1];
|
|
228
|
+
if (!first || !last)
|
|
229
|
+
return;
|
|
230
|
+
for (const [pt, isStart] of [
|
|
231
|
+
[first, true],
|
|
232
|
+
[last, false],
|
|
233
|
+
]) {
|
|
234
|
+
const circle = svgEl("circle");
|
|
235
|
+
attr(circle, {
|
|
236
|
+
class: "bpmnkit-edge-endpoint",
|
|
237
|
+
"data-bpmnkit-endpoint": isStart ? "start" : "end",
|
|
238
|
+
"data-bpmnkit-id": edgeId,
|
|
239
|
+
cx: pt.x,
|
|
240
|
+
cy: pt.y,
|
|
241
|
+
r: 5,
|
|
242
|
+
});
|
|
243
|
+
this._edgeEndpointsG.appendChild(circle);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// ── Endpoint drag ghost ────────────────────────────────────────────
|
|
247
|
+
setEndpointDragGhost(waypoints) {
|
|
248
|
+
this._endpointGhostG.innerHTML = "";
|
|
249
|
+
if (!waypoints || waypoints.length < 2)
|
|
250
|
+
return;
|
|
251
|
+
const points = waypoints.map((wp) => `${wp.x},${wp.y}`).join(" ");
|
|
252
|
+
const poly = svgEl("polyline");
|
|
253
|
+
attr(poly, { class: "bpmnkit-endpoint-ghost", points });
|
|
254
|
+
this._endpointGhostG.appendChild(poly);
|
|
255
|
+
}
|
|
256
|
+
// ── Space tool split line ──────────────────────────────────────────
|
|
257
|
+
setSpacePreview(axis, splitValue) {
|
|
258
|
+
this._spaceG.innerHTML = "";
|
|
259
|
+
if (!axis || splitValue === undefined)
|
|
260
|
+
return;
|
|
261
|
+
const EXTENT = 10000;
|
|
262
|
+
const line = svgEl("line");
|
|
263
|
+
if (axis === "h") {
|
|
264
|
+
attr(line, {
|
|
265
|
+
class: "bpmnkit-space-line",
|
|
266
|
+
x1: splitValue,
|
|
267
|
+
y1: -EXTENT,
|
|
268
|
+
x2: splitValue,
|
|
269
|
+
y2: EXTENT,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
attr(line, {
|
|
274
|
+
class: "bpmnkit-space-line",
|
|
275
|
+
x1: -EXTENT,
|
|
276
|
+
y1: splitValue,
|
|
277
|
+
x2: EXTENT,
|
|
278
|
+
y2: splitValue,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
this._spaceG.appendChild(line);
|
|
282
|
+
}
|
|
283
|
+
// ── Ghost create shape ─────────────────────────────────────────────
|
|
284
|
+
setGhostCreate(type, diag) {
|
|
285
|
+
this._ghostCreateG.innerHTML = "";
|
|
286
|
+
if (!type || !diag)
|
|
287
|
+
return;
|
|
288
|
+
const bounds = defaultBoundsForType(type, diag.x, diag.y);
|
|
289
|
+
const { x, y, width, height } = bounds;
|
|
290
|
+
const g = svgEl("g");
|
|
291
|
+
attr(g, { class: "bpmnkit-ghost", transform: `translate(${x} ${y})` });
|
|
292
|
+
const isStartEvent = type === "startEvent" ||
|
|
293
|
+
type === "messageStartEvent" ||
|
|
294
|
+
type === "timerStartEvent" ||
|
|
295
|
+
type === "conditionalStartEvent" ||
|
|
296
|
+
type === "signalStartEvent";
|
|
297
|
+
const isEndEvent = type === "endEvent" ||
|
|
298
|
+
type === "messageEndEvent" ||
|
|
299
|
+
type === "escalationEndEvent" ||
|
|
300
|
+
type === "errorEndEvent" ||
|
|
301
|
+
type === "compensationEndEvent" ||
|
|
302
|
+
type === "signalEndEvent" ||
|
|
303
|
+
type === "terminateEndEvent";
|
|
304
|
+
const isIntermediateEvent = type === "intermediateThrowEvent" ||
|
|
305
|
+
type === "intermediateCatchEvent" ||
|
|
306
|
+
type === "messageCatchEvent" ||
|
|
307
|
+
type === "messageThrowEvent" ||
|
|
308
|
+
type === "timerCatchEvent" ||
|
|
309
|
+
type === "escalationThrowEvent" ||
|
|
310
|
+
type === "conditionalCatchEvent" ||
|
|
311
|
+
type === "linkCatchEvent" ||
|
|
312
|
+
type === "linkThrowEvent" ||
|
|
313
|
+
type === "compensationThrowEvent" ||
|
|
314
|
+
type === "signalCatchEvent" ||
|
|
315
|
+
type === "signalThrowEvent";
|
|
316
|
+
const isGateway = type === "exclusiveGateway" ||
|
|
317
|
+
type === "parallelGateway" ||
|
|
318
|
+
type === "inclusiveGateway" ||
|
|
319
|
+
type === "eventBasedGateway" ||
|
|
320
|
+
type === "complexGateway";
|
|
321
|
+
const isAnnotation = type === "textAnnotation";
|
|
322
|
+
if (isStartEvent || isEndEvent || isIntermediateEvent) {
|
|
323
|
+
const cx = width / 2;
|
|
324
|
+
const cy = height / 2;
|
|
325
|
+
const r = Math.min(cx, cy) - 1;
|
|
326
|
+
const circle = svgEl("circle");
|
|
327
|
+
attr(circle, {
|
|
328
|
+
cx,
|
|
329
|
+
cy,
|
|
330
|
+
r,
|
|
331
|
+
class: isEndEvent ? "bpmnkit-end-body" : "bpmnkit-event-body",
|
|
332
|
+
});
|
|
333
|
+
g.appendChild(circle);
|
|
334
|
+
if (isIntermediateEvent) {
|
|
335
|
+
const inner = svgEl("circle");
|
|
336
|
+
attr(inner, { cx, cy, r: r - 3, class: "bpmnkit-event-inner" });
|
|
337
|
+
g.appendChild(inner);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
else if (isGateway) {
|
|
341
|
+
const cx = width / 2;
|
|
342
|
+
const cy = height / 2;
|
|
343
|
+
const diamond = svgEl("polygon");
|
|
344
|
+
attr(diamond, {
|
|
345
|
+
points: `${cx},0 ${width},${cy} ${cx},${height} 0,${cy}`,
|
|
346
|
+
class: "bpmnkit-gw-body",
|
|
347
|
+
});
|
|
348
|
+
g.appendChild(diamond);
|
|
349
|
+
}
|
|
350
|
+
else if (isAnnotation) {
|
|
351
|
+
const path = svgEl("path");
|
|
352
|
+
attr(path, {
|
|
353
|
+
d: `M ${width * 0.4} 0 L 0 0 L 0 ${height} L ${width * 0.4} ${height}`,
|
|
354
|
+
class: "bpmnkit-shape-body",
|
|
355
|
+
fill: "none",
|
|
356
|
+
});
|
|
357
|
+
g.appendChild(path);
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
const rect = svgEl("rect");
|
|
361
|
+
attr(rect, { x: 0, y: 0, width, height, rx: 10, class: "bpmnkit-shape-body" });
|
|
362
|
+
g.appendChild(rect);
|
|
363
|
+
}
|
|
364
|
+
this._ghostCreateG.appendChild(g);
|
|
365
|
+
}
|
|
366
|
+
// ── Edge hover dot ─────────────────────────────────────────────────
|
|
367
|
+
setEdgeHoverDot(pt) {
|
|
368
|
+
this._edgeHoverDotG.innerHTML = "";
|
|
369
|
+
if (!pt)
|
|
370
|
+
return;
|
|
371
|
+
const circle = svgEl("circle");
|
|
372
|
+
attr(circle, { class: "bpmnkit-edge-hover-dot", cx: pt.x, cy: pt.y, r: 4 });
|
|
373
|
+
this._edgeHoverDotG.appendChild(circle);
|
|
374
|
+
}
|
|
375
|
+
// ── Edge waypoint balls ────────────────────────────────────────────
|
|
376
|
+
setEdgeWaypointBalls(waypoints, edgeId) {
|
|
377
|
+
this._edgeWaypointsG.innerHTML = "";
|
|
378
|
+
if (!waypoints || !edgeId || waypoints.length < 3)
|
|
379
|
+
return;
|
|
380
|
+
for (let i = 1; i < waypoints.length - 1; i++) {
|
|
381
|
+
const wp = waypoints[i];
|
|
382
|
+
if (!wp)
|
|
383
|
+
continue;
|
|
384
|
+
const circle = svgEl("circle");
|
|
385
|
+
attr(circle, {
|
|
386
|
+
class: "bpmnkit-edge-waypoint-ball",
|
|
387
|
+
"data-bpmnkit-waypoint": "",
|
|
388
|
+
"data-bpmnkit-waypoint-idx": i,
|
|
389
|
+
"data-bpmnkit-id": edgeId,
|
|
390
|
+
cx: wp.x,
|
|
391
|
+
cy: wp.y,
|
|
392
|
+
r: 5,
|
|
393
|
+
});
|
|
394
|
+
this._edgeWaypointsG.appendChild(circle);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
// ── Boundary host highlight ────────────────────────────────────────
|
|
398
|
+
setBoundaryHostHighlight(shapeBounds) {
|
|
399
|
+
this._boundaryHostG.innerHTML = "";
|
|
400
|
+
if (!shapeBounds)
|
|
401
|
+
return;
|
|
402
|
+
const rect = svgEl("rect");
|
|
403
|
+
attr(rect, {
|
|
404
|
+
class: "bpmnkit-boundary-host",
|
|
405
|
+
x: shapeBounds.x - 3,
|
|
406
|
+
y: shapeBounds.y - 3,
|
|
407
|
+
width: shapeBounds.width + 6,
|
|
408
|
+
height: shapeBounds.height + 6,
|
|
409
|
+
rx: 12,
|
|
410
|
+
});
|
|
411
|
+
this._boundaryHostG.appendChild(rect);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
415
|
+
function defaultBoundsForType(type, cx, cy) {
|
|
416
|
+
const isEvent = type === "startEvent" ||
|
|
417
|
+
type === "messageStartEvent" ||
|
|
418
|
+
type === "timerStartEvent" ||
|
|
419
|
+
type === "conditionalStartEvent" ||
|
|
420
|
+
type === "signalStartEvent" ||
|
|
421
|
+
type === "endEvent" ||
|
|
422
|
+
type === "messageEndEvent" ||
|
|
423
|
+
type === "escalationEndEvent" ||
|
|
424
|
+
type === "errorEndEvent" ||
|
|
425
|
+
type === "compensationEndEvent" ||
|
|
426
|
+
type === "signalEndEvent" ||
|
|
427
|
+
type === "terminateEndEvent" ||
|
|
428
|
+
type === "intermediateThrowEvent" ||
|
|
429
|
+
type === "intermediateCatchEvent" ||
|
|
430
|
+
type === "messageCatchEvent" ||
|
|
431
|
+
type === "messageThrowEvent" ||
|
|
432
|
+
type === "timerCatchEvent" ||
|
|
433
|
+
type === "escalationThrowEvent" ||
|
|
434
|
+
type === "conditionalCatchEvent" ||
|
|
435
|
+
type === "linkCatchEvent" ||
|
|
436
|
+
type === "linkThrowEvent" ||
|
|
437
|
+
type === "compensationThrowEvent" ||
|
|
438
|
+
type === "signalCatchEvent" ||
|
|
439
|
+
type === "signalThrowEvent";
|
|
440
|
+
if (isEvent)
|
|
441
|
+
return { x: cx - 18, y: cy - 18, width: 36, height: 36 };
|
|
442
|
+
const isGateway = type === "exclusiveGateway" ||
|
|
443
|
+
type === "parallelGateway" ||
|
|
444
|
+
type === "inclusiveGateway" ||
|
|
445
|
+
type === "eventBasedGateway" ||
|
|
446
|
+
type === "complexGateway";
|
|
447
|
+
if (isGateway)
|
|
448
|
+
return { x: cx - 25, y: cy - 25, width: 50, height: 50 };
|
|
449
|
+
if (type === "subProcess" || type === "transaction")
|
|
450
|
+
return { x: cx - 100, y: cy - 60, width: 200, height: 120 };
|
|
451
|
+
if (type === "textAnnotation")
|
|
452
|
+
return { x: cx - 50, y: cy - 25, width: 100, height: 50 };
|
|
453
|
+
return { x: cx - 50, y: cy - 40, width: 100, height: 80 };
|
|
454
|
+
}
|
|
455
|
+
//# sourceMappingURL=overlay.js.map
|
package/dist/rules.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { BpmnElementType } from "@bpmnkit/core";
|
|
2
|
+
/**
|
|
3
|
+
* Returns true if a sequence flow from `sourceType` to `targetType` is valid.
|
|
4
|
+
*
|
|
5
|
+
* - endEvent cannot be a source
|
|
6
|
+
* - startEvent cannot be a target
|
|
7
|
+
* - boundaryEvent can only be a source
|
|
8
|
+
*/
|
|
9
|
+
export declare function canConnect(sourceType: BpmnElementType, targetType: BpmnElementType): boolean;
|
|
10
|
+
//# sourceMappingURL=rules.d.ts.map
|
package/dist/rules.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true if a sequence flow from `sourceType` to `targetType` is valid.
|
|
3
|
+
*
|
|
4
|
+
* - endEvent cannot be a source
|
|
5
|
+
* - startEvent cannot be a target
|
|
6
|
+
* - boundaryEvent can only be a source
|
|
7
|
+
*/
|
|
8
|
+
export function canConnect(sourceType, targetType) {
|
|
9
|
+
if (sourceType === "endEvent")
|
|
10
|
+
return false;
|
|
11
|
+
if (targetType === "startEvent")
|
|
12
|
+
return false;
|
|
13
|
+
if (targetType === "boundaryEvent")
|
|
14
|
+
return false;
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=rules.js.map
|