@bpmnkit/plugins 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 +153 -0
- package/dist/ai-bridge/css.d.ts +2 -0
- package/dist/ai-bridge/css.js +366 -0
- package/dist/ai-bridge/index.d.ts +44 -0
- package/dist/ai-bridge/index.js +132 -0
- package/dist/ai-bridge/panel.d.ts +27 -0
- package/dist/ai-bridge/panel.js +715 -0
- package/dist/ascii-view/css.d.ts +4 -0
- package/dist/ascii-view/css.js +83 -0
- package/dist/ascii-view/index.d.ts +25 -0
- package/dist/ascii-view/index.js +92 -0
- package/dist/command-palette/css.d.ts +4 -0
- package/dist/command-palette/css.js +157 -0
- package/dist/command-palette/index.d.ts +53 -0
- package/dist/command-palette/index.js +378 -0
- package/dist/command-palette-editor/index.d.ts +35 -0
- package/dist/command-palette-editor/index.js +60 -0
- package/dist/config-panel/css.d.ts +4 -0
- package/dist/config-panel/css.js +719 -0
- package/dist/config-panel/index.d.ts +36 -0
- package/dist/config-panel/index.js +73 -0
- package/dist/config-panel/renderer.d.ts +127 -0
- package/dist/config-panel/renderer.js +1162 -0
- package/dist/config-panel/types.d.ts +118 -0
- package/dist/config-panel/types.js +2 -0
- package/dist/config-panel-bpmn/index.d.ts +58 -0
- package/dist/config-panel-bpmn/index.js +1320 -0
- package/dist/config-panel-bpmn/template-engine.d.ts +17 -0
- package/dist/config-panel-bpmn/template-engine.js +307 -0
- package/dist/config-panel-bpmn/template-to-service-task.d.ts +30 -0
- package/dist/config-panel-bpmn/template-to-service-task.js +92 -0
- package/dist/config-panel-bpmn/template-types.d.ts +126 -0
- package/dist/config-panel-bpmn/template-types.js +6 -0
- package/dist/config-panel-bpmn/templates/generated.d.ts +3 -0
- package/dist/config-panel-bpmn/templates/generated.js +57865 -0
- package/dist/config-panel-bpmn/util.d.ts +46 -0
- package/dist/config-panel-bpmn/util.js +195 -0
- package/dist/dmn-editor/css.d.ts +3 -0
- package/dist/dmn-editor/css.js +667 -0
- package/dist/dmn-editor/dmn-editor.d.ts +34 -0
- package/dist/dmn-editor/dmn-editor.js +646 -0
- package/dist/dmn-editor/drd-canvas.d.ts +85 -0
- package/dist/dmn-editor/drd-canvas.js +1087 -0
- package/dist/dmn-editor/index.d.ts +3 -0
- package/dist/dmn-editor/index.js +2 -0
- package/dist/dmn-viewer/css.d.ts +3 -0
- package/dist/dmn-viewer/css.js +151 -0
- package/dist/dmn-viewer/dmn-viewer.d.ts +30 -0
- package/dist/dmn-viewer/dmn-viewer.js +160 -0
- package/dist/dmn-viewer/feel.d.ts +3 -0
- package/dist/dmn-viewer/feel.js +2 -0
- package/dist/dmn-viewer/index.d.ts +14 -0
- package/dist/dmn-viewer/index.js +12 -0
- package/dist/element-docs/content.d.ts +20 -0
- package/dist/element-docs/content.js +1032 -0
- package/dist/element-docs/index.d.ts +7 -0
- package/dist/element-docs/index.js +643 -0
- package/dist/feel-playground/css.d.ts +4 -0
- package/dist/feel-playground/css.js +292 -0
- package/dist/feel-playground/index.d.ts +4 -0
- package/dist/feel-playground/index.js +3 -0
- package/dist/feel-playground/playground-plugin.d.ts +14 -0
- package/dist/feel-playground/playground-plugin.js +292 -0
- package/dist/form-editor/css.d.ts +3 -0
- package/dist/form-editor/css.js +703 -0
- package/dist/form-editor/form-editor.d.ts +48 -0
- package/dist/form-editor/form-editor.js +1039 -0
- package/dist/form-editor/index.d.ts +3 -0
- package/dist/form-editor/index.js +2 -0
- package/dist/form-viewer/css.d.ts +3 -0
- package/dist/form-viewer/css.js +303 -0
- package/dist/form-viewer/form-viewer.d.ts +29 -0
- package/dist/form-viewer/form-viewer.js +376 -0
- package/dist/form-viewer/index.d.ts +12 -0
- package/dist/form-viewer/index.js +11 -0
- package/dist/history/checkpoint.d.ts +10 -0
- package/dist/history/checkpoint.js +92 -0
- package/dist/history/css.d.ts +2 -0
- package/dist/history/css.js +130 -0
- package/dist/history/history-panel.d.ts +12 -0
- package/dist/history/history-panel.js +142 -0
- package/dist/history/index.d.ts +5 -0
- package/dist/history/index.js +3 -0
- package/dist/main-menu/css.d.ts +4 -0
- package/dist/main-menu/css.js +272 -0
- package/dist/main-menu/index.d.ts +59 -0
- package/dist/main-menu/index.js +285 -0
- package/dist/minimap/css.d.ts +10 -0
- package/dist/minimap/css.js +54 -0
- package/dist/minimap/index.d.ts +38 -0
- package/dist/minimap/index.js +69 -0
- package/dist/minimap/minimap.d.ts +35 -0
- package/dist/minimap/minimap.js +166 -0
- package/dist/optimize/index.d.ts +21 -0
- package/dist/optimize/index.js +304 -0
- package/dist/process-runner/css.d.ts +2 -0
- package/dist/process-runner/css.js +467 -0
- package/dist/process-runner/index.d.ts +56 -0
- package/dist/process-runner/index.js +549 -0
- package/dist/storage/auto-save.d.ts +11 -0
- package/dist/storage/auto-save.js +44 -0
- package/dist/storage/css.d.ts +2 -0
- package/dist/storage/css.js +2 -0
- package/dist/storage/db.d.ts +99 -0
- package/dist/storage/db.js +116 -0
- package/dist/storage/dialog.d.ts +15 -0
- package/dist/storage/dialog.js +201 -0
- package/dist/storage/export.d.ts +3 -0
- package/dist/storage/export.js +137 -0
- package/dist/storage/index.d.ts +44 -0
- package/dist/storage/index.js +201 -0
- package/dist/storage/sidebar.d.ts +2 -0
- package/dist/storage/sidebar.js +2 -0
- package/dist/storage/storage-api.d.ts +76 -0
- package/dist/storage/storage-api.js +342 -0
- package/dist/storage/types.d.ts +44 -0
- package/dist/storage/types.js +2 -0
- package/dist/storage-tabs-bridge/index.d.ts +96 -0
- package/dist/storage-tabs-bridge/index.js +502 -0
- package/dist/tabs/css.d.ts +3 -0
- package/dist/tabs/css.js +642 -0
- package/dist/tabs/file-resolver.d.ts +71 -0
- package/dist/tabs/file-resolver.js +46 -0
- package/dist/tabs/index.d.ts +15 -0
- package/dist/tabs/index.js +13 -0
- package/dist/tabs/tabs-plugin.d.ts +250 -0
- package/dist/tabs/tabs-plugin.js +1119 -0
- package/dist/token-highlight/css.d.ts +2 -0
- package/dist/token-highlight/css.js +81 -0
- package/dist/token-highlight/index.d.ts +44 -0
- package/dist/token-highlight/index.js +164 -0
- package/dist/watermark/css.d.ts +10 -0
- package/dist/watermark/css.js +54 -0
- package/dist/watermark/index.d.ts +48 -0
- package/dist/watermark/index.js +64 -0
- package/dist/zoom-controls/css.d.ts +4 -0
- package/dist/zoom-controls/css.js +48 -0
- package/dist/zoom-controls/index.d.ts +36 -0
- package/dist/zoom-controls/index.js +111 -0
- package/package.json +121 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
const STYLE_ID = "bpmnkit-token-highlight-v1";
|
|
2
|
+
const CSS = `
|
|
3
|
+
@keyframes bpmnkit-token-pulse {
|
|
4
|
+
0%, 100% { filter: drop-shadow(0 0 4px rgba(245, 158, 11, 0.9)); }
|
|
5
|
+
50% { filter: drop-shadow(0 0 10px rgba(245, 158, 11, 0.25)); }
|
|
6
|
+
}
|
|
7
|
+
@keyframes bpmnkit-token-flow {
|
|
8
|
+
to { stroke-dashoffset: -12; }
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/* ── Active shapes (token is here) ─────────────────────────────────────── */
|
|
12
|
+
.bpmnkit-token-active {
|
|
13
|
+
animation: bpmnkit-token-pulse 1.4s ease-in-out infinite;
|
|
14
|
+
}
|
|
15
|
+
.bpmnkit-token-active .bpmnkit-shape-body,
|
|
16
|
+
.bpmnkit-token-active .bpmnkit-event-body,
|
|
17
|
+
.bpmnkit-token-active .bpmnkit-end-body,
|
|
18
|
+
.bpmnkit-token-active .bpmnkit-gw-body {
|
|
19
|
+
stroke: #f59e0b !important;
|
|
20
|
+
stroke-width: 2.5 !important;
|
|
21
|
+
fill: rgba(245, 158, 11, 0.12) !important;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* ── Visited shapes (token has passed through) ──────────────────────────── */
|
|
25
|
+
.bpmnkit-token-visited .bpmnkit-shape-body,
|
|
26
|
+
.bpmnkit-token-visited .bpmnkit-event-body,
|
|
27
|
+
.bpmnkit-token-visited .bpmnkit-end-body,
|
|
28
|
+
.bpmnkit-token-visited .bpmnkit-gw-body {
|
|
29
|
+
stroke: #10b981 !important;
|
|
30
|
+
stroke-width: 2 !important;
|
|
31
|
+
fill: rgba(16, 185, 129, 0.08) !important;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* ── Active edges (token is moving along this flow) ─────────────────────── */
|
|
35
|
+
.bpmnkit-token-edge-active .bpmnkit-edge-path {
|
|
36
|
+
stroke: #f59e0b !important;
|
|
37
|
+
stroke-width: 2.5 !important;
|
|
38
|
+
stroke-dasharray: 8 4;
|
|
39
|
+
animation: bpmnkit-token-flow 0.5s linear infinite;
|
|
40
|
+
}
|
|
41
|
+
.bpmnkit-token-edge-active .bpmnkit-arrow-fill {
|
|
42
|
+
fill: #f59e0b !important;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* ── Visited edges ───────────────────────────────────────────────────────── */
|
|
46
|
+
.bpmnkit-token-edge-visited .bpmnkit-edge-path {
|
|
47
|
+
stroke: #10b981 !important;
|
|
48
|
+
stroke-width: 2 !important;
|
|
49
|
+
}
|
|
50
|
+
.bpmnkit-token-edge-visited .bpmnkit-arrow-fill {
|
|
51
|
+
fill: #10b981 !important;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* ── Error shapes (gateway with no matching condition) ───────────────────── */
|
|
55
|
+
@keyframes bpmnkit-token-error-pulse {
|
|
56
|
+
0%, 100% { filter: drop-shadow(0 0 5px rgba(239, 68, 68, 0.95)); }
|
|
57
|
+
50% { filter: drop-shadow(0 0 12px rgba(239, 68, 68, 0.3)); }
|
|
58
|
+
}
|
|
59
|
+
.bpmnkit-token-error {
|
|
60
|
+
animation: bpmnkit-token-error-pulse 0.9s ease-in-out 3;
|
|
61
|
+
}
|
|
62
|
+
.bpmnkit-token-error .bpmnkit-shape-body,
|
|
63
|
+
.bpmnkit-token-error .bpmnkit-event-body,
|
|
64
|
+
.bpmnkit-token-error .bpmnkit-end-body,
|
|
65
|
+
.bpmnkit-token-error .bpmnkit-gw-body {
|
|
66
|
+
stroke: #ef4444 !important;
|
|
67
|
+
stroke-width: 2.5 !important;
|
|
68
|
+
fill: rgba(239, 68, 68, 0.12) !important;
|
|
69
|
+
}
|
|
70
|
+
`;
|
|
71
|
+
export function injectTokenHighlightStyles() {
|
|
72
|
+
if (typeof document === "undefined")
|
|
73
|
+
return;
|
|
74
|
+
if (document.getElementById(STYLE_ID) !== null)
|
|
75
|
+
return;
|
|
76
|
+
const style = document.createElement("style");
|
|
77
|
+
style.id = STYLE_ID;
|
|
78
|
+
style.textContent = CSS;
|
|
79
|
+
document.head.appendChild(style);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=css.js.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { CanvasPlugin } from "@bpmnkit/canvas";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal interface satisfied by `ProcessInstance` from `@bpmnkit/engine`.
|
|
4
|
+
* Using structural typing keeps this plugin free of an engine dependency.
|
|
5
|
+
*/
|
|
6
|
+
export interface InstanceLike {
|
|
7
|
+
onChange(callback: (event: Record<string, unknown>) => void): () => void;
|
|
8
|
+
}
|
|
9
|
+
export interface TokenHighlightApi {
|
|
10
|
+
/**
|
|
11
|
+
* Subscribe to a `ProcessInstance` and automatically update highlights as
|
|
12
|
+
* the engine emits events. Returns an unsubscribe function.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const highlight = createTokenHighlightPlugin();
|
|
17
|
+
* const canvas = new BpmnCanvas({ container, plugins: [highlight] });
|
|
18
|
+
* canvas.load(xml);
|
|
19
|
+
*
|
|
20
|
+
* const instance = engine.start("Process_1", { amount: 100 });
|
|
21
|
+
* const stop = highlight.api.trackInstance(instance);
|
|
22
|
+
* // later: stop() to detach
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
trackInstance(instance: InstanceLike): () => void;
|
|
26
|
+
/**
|
|
27
|
+
* Manually set the full list of element IDs that currently hold a token.
|
|
28
|
+
* Replaces any previously active set.
|
|
29
|
+
*/
|
|
30
|
+
setActive(elementIds: string[]): void;
|
|
31
|
+
/**
|
|
32
|
+
* Mark additional element IDs as visited (token has passed through).
|
|
33
|
+
* Additive — does not clear previously visited elements.
|
|
34
|
+
*/
|
|
35
|
+
addVisited(elementIds: string[]): void;
|
|
36
|
+
/** Mark an element as failed (e.g. exclusive gateway with no matching condition). Shown in red. */
|
|
37
|
+
setError(elementId: string): void;
|
|
38
|
+
/** Remove all token highlights from the canvas. */
|
|
39
|
+
clear(): void;
|
|
40
|
+
}
|
|
41
|
+
export declare function createTokenHighlightPlugin(): CanvasPlugin & {
|
|
42
|
+
api: TokenHighlightApi;
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { injectTokenHighlightStyles } from "./css";
|
|
2
|
+
// ── Plugin factory ─────────────────────────────────────────────────────────────
|
|
3
|
+
export function createTokenHighlightPlugin() {
|
|
4
|
+
let canvasApi = null;
|
|
5
|
+
/** Element IDs that currently hold a live token. */
|
|
6
|
+
const activeIds = new Set();
|
|
7
|
+
/** Element IDs that a token has already passed through. */
|
|
8
|
+
const visitedIds = new Set();
|
|
9
|
+
/** Element IDs that have failed (e.g. unmatched gateway condition). */
|
|
10
|
+
const errorIds = new Set();
|
|
11
|
+
/** flowId → { sourceRef, targetRef } — populated from diagram:load/change. */
|
|
12
|
+
const flowIndex = new Map();
|
|
13
|
+
const unsubs = [];
|
|
14
|
+
// ── Helpers ──────────────────────────────────────────────────────────────
|
|
15
|
+
function shapeEl(id) {
|
|
16
|
+
const el = canvasApi?.viewportEl.querySelector(`[data-bpmnkit-id="${id}"]`);
|
|
17
|
+
return el instanceof SVGGElement ? el : undefined;
|
|
18
|
+
}
|
|
19
|
+
function edgeEl(id) {
|
|
20
|
+
const el = canvasApi?.viewportEl.querySelector(`[data-bpmnkit-id="${id}"]`);
|
|
21
|
+
return el instanceof SVGGElement ? el : undefined;
|
|
22
|
+
}
|
|
23
|
+
function applyHighlights() {
|
|
24
|
+
const api = canvasApi;
|
|
25
|
+
if (api === null)
|
|
26
|
+
return;
|
|
27
|
+
// Strip all plugin classes — query the viewport so subprocess children are included
|
|
28
|
+
const vp = api.viewportEl;
|
|
29
|
+
for (const el of vp.querySelectorAll(".bpmnkit-token-active,.bpmnkit-token-visited,.bpmnkit-token-error")) {
|
|
30
|
+
el.classList.remove("bpmnkit-token-active", "bpmnkit-token-visited", "bpmnkit-token-error");
|
|
31
|
+
}
|
|
32
|
+
for (const el of vp.querySelectorAll(".bpmnkit-token-edge-active,.bpmnkit-token-edge-visited")) {
|
|
33
|
+
el.classList.remove("bpmnkit-token-edge-active", "bpmnkit-token-edge-visited");
|
|
34
|
+
}
|
|
35
|
+
// Visited shapes
|
|
36
|
+
for (const id of visitedIds) {
|
|
37
|
+
shapeEl(id)?.classList.add("bpmnkit-token-visited");
|
|
38
|
+
}
|
|
39
|
+
// Active shapes (added after visited so they override on the same element)
|
|
40
|
+
for (const id of activeIds) {
|
|
41
|
+
const el = shapeEl(id);
|
|
42
|
+
if (el !== undefined) {
|
|
43
|
+
el.classList.remove("bpmnkit-token-visited");
|
|
44
|
+
el.classList.add("bpmnkit-token-active");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Error shapes (highest priority — override active/visited)
|
|
48
|
+
for (const id of errorIds) {
|
|
49
|
+
const el = shapeEl(id);
|
|
50
|
+
if (el !== undefined) {
|
|
51
|
+
el.classList.remove("bpmnkit-token-active", "bpmnkit-token-visited");
|
|
52
|
+
el.classList.add("bpmnkit-token-error");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Edge highlights
|
|
56
|
+
// • active edge : source visited, target active (token just left source, entering target)
|
|
57
|
+
// • visited edge : source visited, target visited (token has fully traversed this edge)
|
|
58
|
+
// This correctly handles exclusive gateways: only the taken branch's target enters
|
|
59
|
+
// visited/active, so only the taken edge is highlighted.
|
|
60
|
+
for (const [flowId, { sourceRef, targetRef }] of flowIndex) {
|
|
61
|
+
const el = edgeEl(flowId);
|
|
62
|
+
if (el === undefined)
|
|
63
|
+
continue;
|
|
64
|
+
const srcVisited = visitedIds.has(sourceRef);
|
|
65
|
+
if (!srcVisited)
|
|
66
|
+
continue;
|
|
67
|
+
if (activeIds.has(targetRef)) {
|
|
68
|
+
el.classList.add("bpmnkit-token-edge-active");
|
|
69
|
+
}
|
|
70
|
+
else if (visitedIds.has(targetRef)) {
|
|
71
|
+
el.classList.add("bpmnkit-token-edge-visited");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function indexFlows(defs) {
|
|
76
|
+
flowIndex.clear();
|
|
77
|
+
for (const proc of defs.processes) {
|
|
78
|
+
for (const flow of proc.sequenceFlows) {
|
|
79
|
+
flowIndex.set(flow.id, { sourceRef: flow.sourceRef, targetRef: flow.targetRef });
|
|
80
|
+
}
|
|
81
|
+
// Sub-processes
|
|
82
|
+
for (const el of proc.flowElements) {
|
|
83
|
+
if (el.type === "subProcess" ||
|
|
84
|
+
el.type === "transaction" ||
|
|
85
|
+
el.type === "adHocSubProcess" ||
|
|
86
|
+
el.type === "eventSubProcess") {
|
|
87
|
+
for (const flow of el.sequenceFlows) {
|
|
88
|
+
flowIndex.set(flow.id, { sourceRef: flow.sourceRef, targetRef: flow.targetRef });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// ── TokenHighlightApi ─────────────────────────────────────────────────────
|
|
95
|
+
const api = {
|
|
96
|
+
trackInstance(instance) {
|
|
97
|
+
return instance.onChange((evt) => {
|
|
98
|
+
const type = evt.type;
|
|
99
|
+
const elementId = evt.elementId;
|
|
100
|
+
if (typeof type !== "string")
|
|
101
|
+
return;
|
|
102
|
+
if (type === "element:entering" && typeof elementId === "string") {
|
|
103
|
+
activeIds.add(elementId);
|
|
104
|
+
applyHighlights();
|
|
105
|
+
}
|
|
106
|
+
else if (type === "element:left" && typeof elementId === "string") {
|
|
107
|
+
activeIds.delete(elementId);
|
|
108
|
+
visitedIds.add(elementId);
|
|
109
|
+
applyHighlights();
|
|
110
|
+
}
|
|
111
|
+
else if (type === "process:completed" || type === "process:failed") {
|
|
112
|
+
activeIds.clear();
|
|
113
|
+
applyHighlights();
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
setActive(elementIds) {
|
|
118
|
+
activeIds.clear();
|
|
119
|
+
for (const id of elementIds)
|
|
120
|
+
activeIds.add(id);
|
|
121
|
+
applyHighlights();
|
|
122
|
+
},
|
|
123
|
+
addVisited(elementIds) {
|
|
124
|
+
for (const id of elementIds)
|
|
125
|
+
visitedIds.add(id);
|
|
126
|
+
applyHighlights();
|
|
127
|
+
},
|
|
128
|
+
setError(elementId) {
|
|
129
|
+
errorIds.add(elementId);
|
|
130
|
+
applyHighlights();
|
|
131
|
+
},
|
|
132
|
+
clear() {
|
|
133
|
+
activeIds.clear();
|
|
134
|
+
visitedIds.clear();
|
|
135
|
+
errorIds.clear();
|
|
136
|
+
applyHighlights();
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
// ── CanvasPlugin ──────────────────────────────────────────────────────────
|
|
140
|
+
return {
|
|
141
|
+
name: "token-highlight",
|
|
142
|
+
api,
|
|
143
|
+
install(canvasApiArg) {
|
|
144
|
+
canvasApi = canvasApiArg;
|
|
145
|
+
injectTokenHighlightStyles();
|
|
146
|
+
const onAny = canvasApiArg.on;
|
|
147
|
+
unsubs.push(canvasApiArg.on("diagram:load", (defs) => {
|
|
148
|
+
indexFlows(defs);
|
|
149
|
+
api.clear();
|
|
150
|
+
}), canvasApiArg.on("diagram:clear", () => {
|
|
151
|
+
flowIndex.clear();
|
|
152
|
+
api.clear();
|
|
153
|
+
}), onAny("diagram:change", (defs) => {
|
|
154
|
+
indexFlows(defs);
|
|
155
|
+
}));
|
|
156
|
+
},
|
|
157
|
+
uninstall() {
|
|
158
|
+
for (const off of unsubs)
|
|
159
|
+
off();
|
|
160
|
+
canvasApi = null;
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** ID used to prevent duplicate style injection. */
|
|
2
|
+
export declare const WATERMARK_STYLE_ID = "bpmnkit-watermark-styles-v1";
|
|
3
|
+
/** CSS for the watermark plugin, injected once into `<head>`. */
|
|
4
|
+
export declare const WATERMARK_CSS = "\n.bpmnkit-watermark {\n position: absolute;\n bottom: 8px;\n right: 8px;\n display: flex;\n align-items: center;\n gap: 8px;\n pointer-events: auto;\n z-index: 10;\n}\n.bpmnkit-watermark-link {\n font-size: 11px;\n color: var(--bpmnkit-overlay-text, rgba(60, 60, 60, 0.7));\n text-decoration: none;\n font-family: system-ui, sans-serif;\n opacity: 0.7;\n transition: opacity 0.15s;\n}\n.bpmnkit-watermark-link:hover {\n opacity: 1;\n text-decoration: underline;\n}\n.bpmnkit-watermark-logo {\n display: flex;\n align-items: center;\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n}\n.bpmnkit-watermark-logo > svg {\n width: 100%;\n height: 100%;\n display: block;\n}\n";
|
|
5
|
+
/**
|
|
6
|
+
* Injects the watermark stylesheet into `<head>` if not already present.
|
|
7
|
+
* Safe to call multiple times — only one `<style>` tag is ever inserted.
|
|
8
|
+
*/
|
|
9
|
+
export declare function injectWatermarkStyles(): void;
|
|
10
|
+
//# sourceMappingURL=css.d.ts.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** ID used to prevent duplicate style injection. */
|
|
2
|
+
export const WATERMARK_STYLE_ID = "bpmnkit-watermark-styles-v1";
|
|
3
|
+
/** CSS for the watermark plugin, injected once into `<head>`. */
|
|
4
|
+
export const WATERMARK_CSS = `
|
|
5
|
+
.bpmnkit-watermark {
|
|
6
|
+
position: absolute;
|
|
7
|
+
bottom: 8px;
|
|
8
|
+
right: 8px;
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
gap: 8px;
|
|
12
|
+
pointer-events: auto;
|
|
13
|
+
z-index: 10;
|
|
14
|
+
}
|
|
15
|
+
.bpmnkit-watermark-link {
|
|
16
|
+
font-size: 11px;
|
|
17
|
+
color: var(--bpmnkit-overlay-text, rgba(60, 60, 60, 0.7));
|
|
18
|
+
text-decoration: none;
|
|
19
|
+
font-family: system-ui, sans-serif;
|
|
20
|
+
opacity: 0.7;
|
|
21
|
+
transition: opacity 0.15s;
|
|
22
|
+
}
|
|
23
|
+
.bpmnkit-watermark-link:hover {
|
|
24
|
+
opacity: 1;
|
|
25
|
+
text-decoration: underline;
|
|
26
|
+
}
|
|
27
|
+
.bpmnkit-watermark-logo {
|
|
28
|
+
display: flex;
|
|
29
|
+
align-items: center;
|
|
30
|
+
width: 20px;
|
|
31
|
+
height: 20px;
|
|
32
|
+
flex-shrink: 0;
|
|
33
|
+
}
|
|
34
|
+
.bpmnkit-watermark-logo > svg {
|
|
35
|
+
width: 100%;
|
|
36
|
+
height: 100%;
|
|
37
|
+
display: block;
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
40
|
+
/**
|
|
41
|
+
* Injects the watermark stylesheet into `<head>` if not already present.
|
|
42
|
+
* Safe to call multiple times — only one `<style>` tag is ever inserted.
|
|
43
|
+
*/
|
|
44
|
+
export function injectWatermarkStyles() {
|
|
45
|
+
if (typeof document === "undefined")
|
|
46
|
+
return;
|
|
47
|
+
if (document.getElementById(WATERMARK_STYLE_ID))
|
|
48
|
+
return;
|
|
49
|
+
const style = document.createElement("style");
|
|
50
|
+
style.id = WATERMARK_STYLE_ID;
|
|
51
|
+
style.textContent = WATERMARK_CSS;
|
|
52
|
+
document.head.appendChild(style);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=css.js.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @bpmnkit/canvas-plugin-watermark — bottom-right attribution bar for `@bpmnkit/canvas`.
|
|
3
|
+
*
|
|
4
|
+
* Renders configurable links and an optional logo in the bottom-right corner.
|
|
5
|
+
* Links are left of the logo; the logo is always the rightmost element.
|
|
6
|
+
*
|
|
7
|
+
* ## Usage
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { BpmnCanvas } from "@bpmnkit/canvas";
|
|
10
|
+
* import { createWatermarkPlugin } from "@bpmnkit/canvas-plugin-watermark";
|
|
11
|
+
*
|
|
12
|
+
* const canvas = new BpmnCanvas({
|
|
13
|
+
* container,
|
|
14
|
+
* plugins: [
|
|
15
|
+
* createWatermarkPlugin({
|
|
16
|
+
* links: [{ label: "GitHub", url: "https://github.com/example/repo" }],
|
|
17
|
+
* logo: myLogoSvgString,
|
|
18
|
+
* }),
|
|
19
|
+
* ],
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @packageDocumentation
|
|
24
|
+
*/
|
|
25
|
+
import type { CanvasPlugin } from "@bpmnkit/canvas";
|
|
26
|
+
export { WATERMARK_CSS, WATERMARK_STYLE_ID, injectWatermarkStyles } from "./css.js";
|
|
27
|
+
/** A single navigable link rendered in the watermark bar. */
|
|
28
|
+
export interface WatermarkLink {
|
|
29
|
+
label: string;
|
|
30
|
+
url: string;
|
|
31
|
+
}
|
|
32
|
+
/** Options for {@link createWatermarkPlugin}. */
|
|
33
|
+
export interface WatermarkOptions {
|
|
34
|
+
/** Links to display, in order from left to right. */
|
|
35
|
+
links?: WatermarkLink[];
|
|
36
|
+
/**
|
|
37
|
+
* Square SVG markup string for the logo, rendered rightmost.
|
|
38
|
+
* Must be a self-contained `<svg>` element.
|
|
39
|
+
*/
|
|
40
|
+
logo?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Creates a watermark plugin instance.
|
|
44
|
+
*
|
|
45
|
+
* Each call returns a fresh plugin — pass one instance per canvas.
|
|
46
|
+
*/
|
|
47
|
+
export declare function createWatermarkPlugin(options?: WatermarkOptions): CanvasPlugin;
|
|
48
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @bpmnkit/canvas-plugin-watermark — bottom-right attribution bar for `@bpmnkit/canvas`.
|
|
3
|
+
*
|
|
4
|
+
* Renders configurable links and an optional logo in the bottom-right corner.
|
|
5
|
+
* Links are left of the logo; the logo is always the rightmost element.
|
|
6
|
+
*
|
|
7
|
+
* ## Usage
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { BpmnCanvas } from "@bpmnkit/canvas";
|
|
10
|
+
* import { createWatermarkPlugin } from "@bpmnkit/canvas-plugin-watermark";
|
|
11
|
+
*
|
|
12
|
+
* const canvas = new BpmnCanvas({
|
|
13
|
+
* container,
|
|
14
|
+
* plugins: [
|
|
15
|
+
* createWatermarkPlugin({
|
|
16
|
+
* links: [{ label: "GitHub", url: "https://github.com/example/repo" }],
|
|
17
|
+
* logo: myLogoSvgString,
|
|
18
|
+
* }),
|
|
19
|
+
* ],
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @packageDocumentation
|
|
24
|
+
*/
|
|
25
|
+
import { injectWatermarkStyles } from "./css.js";
|
|
26
|
+
export { WATERMARK_CSS, WATERMARK_STYLE_ID, injectWatermarkStyles } from "./css.js";
|
|
27
|
+
/**
|
|
28
|
+
* Creates a watermark plugin instance.
|
|
29
|
+
*
|
|
30
|
+
* Each call returns a fresh plugin — pass one instance per canvas.
|
|
31
|
+
*/
|
|
32
|
+
export function createWatermarkPlugin(options = {}) {
|
|
33
|
+
let host = null;
|
|
34
|
+
return {
|
|
35
|
+
name: "watermark",
|
|
36
|
+
install(api) {
|
|
37
|
+
injectWatermarkStyles();
|
|
38
|
+
host = document.createElement("div");
|
|
39
|
+
host.className = "bpmnkit-watermark";
|
|
40
|
+
host.setAttribute("aria-label", "Attribution");
|
|
41
|
+
for (const link of options.links ?? []) {
|
|
42
|
+
const a = document.createElement("a");
|
|
43
|
+
a.className = "bpmnkit-watermark-link";
|
|
44
|
+
a.href = link.url;
|
|
45
|
+
a.target = "_blank";
|
|
46
|
+
a.rel = "noopener noreferrer";
|
|
47
|
+
a.textContent = link.label;
|
|
48
|
+
host.appendChild(a);
|
|
49
|
+
}
|
|
50
|
+
if (options.logo) {
|
|
51
|
+
const logoDiv = document.createElement("div");
|
|
52
|
+
logoDiv.className = "bpmnkit-watermark-logo";
|
|
53
|
+
logoDiv.innerHTML = options.logo;
|
|
54
|
+
host.appendChild(logoDiv);
|
|
55
|
+
}
|
|
56
|
+
api.container.appendChild(host);
|
|
57
|
+
},
|
|
58
|
+
uninstall() {
|
|
59
|
+
host?.remove();
|
|
60
|
+
host = null;
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const ZOOM_CONTROLS_STYLE_ID = "bpmnkit-zoom-controls-styles-v1";
|
|
2
|
+
export declare const ZOOM_CONTROLS_CSS = "\n.bpmnkit-controls {\n position: absolute;\n bottom: 12px;\n left: 12px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.bpmnkit-control-btn {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n line-height: 1;\n font-size: 16px;\n font-family: system-ui, sans-serif;\n background: var(--bpmnkit-overlay-bg, rgba(248, 249, 250, 0.92));\n border: 1px solid var(--bpmnkit-overlay-border, rgba(0, 0, 0, 0.12));\n border-radius: 4px;\n color: var(--bpmnkit-text, #333333);\n cursor: pointer;\n transition: background 0.1s, color 0.1s;\n}\n.bpmnkit-control-btn:hover {\n background: var(--bpmnkit-highlight, var(--bpmnkit-accent, #1a56db));\n color: #fff;\n border-color: transparent;\n}\n.bpmnkit-control-btn:focus {\n outline: 2px solid var(--bpmnkit-focus, var(--bpmnkit-accent, #1a56db));\n outline-offset: 1px;\n}\n";
|
|
3
|
+
export declare function injectZoomControlsStyles(): void;
|
|
4
|
+
//# sourceMappingURL=css.d.ts.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export const ZOOM_CONTROLS_STYLE_ID = "bpmnkit-zoom-controls-styles-v1";
|
|
2
|
+
export const ZOOM_CONTROLS_CSS = `
|
|
3
|
+
.bpmnkit-controls {
|
|
4
|
+
position: absolute;
|
|
5
|
+
bottom: 12px;
|
|
6
|
+
left: 12px;
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
gap: 2px;
|
|
10
|
+
}
|
|
11
|
+
.bpmnkit-control-btn {
|
|
12
|
+
width: 28px;
|
|
13
|
+
height: 28px;
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
justify-content: center;
|
|
17
|
+
padding: 0;
|
|
18
|
+
line-height: 1;
|
|
19
|
+
font-size: 16px;
|
|
20
|
+
font-family: system-ui, sans-serif;
|
|
21
|
+
background: var(--bpmnkit-overlay-bg, rgba(248, 249, 250, 0.92));
|
|
22
|
+
border: 1px solid var(--bpmnkit-overlay-border, rgba(0, 0, 0, 0.12));
|
|
23
|
+
border-radius: 4px;
|
|
24
|
+
color: var(--bpmnkit-text, #333333);
|
|
25
|
+
cursor: pointer;
|
|
26
|
+
transition: background 0.1s, color 0.1s;
|
|
27
|
+
}
|
|
28
|
+
.bpmnkit-control-btn:hover {
|
|
29
|
+
background: var(--bpmnkit-highlight, var(--bpmnkit-accent, #1a56db));
|
|
30
|
+
color: #fff;
|
|
31
|
+
border-color: transparent;
|
|
32
|
+
}
|
|
33
|
+
.bpmnkit-control-btn:focus {
|
|
34
|
+
outline: 2px solid var(--bpmnkit-focus, var(--bpmnkit-accent, #1a56db));
|
|
35
|
+
outline-offset: 1px;
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
export function injectZoomControlsStyles() {
|
|
39
|
+
if (typeof document === "undefined")
|
|
40
|
+
return;
|
|
41
|
+
if (document.getElementById(ZOOM_CONTROLS_STYLE_ID))
|
|
42
|
+
return;
|
|
43
|
+
const style = document.createElement("style");
|
|
44
|
+
style.id = ZOOM_CONTROLS_STYLE_ID;
|
|
45
|
+
style.textContent = ZOOM_CONTROLS_CSS;
|
|
46
|
+
document.head.appendChild(style);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=css.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @bpmnkit/canvas-plugin-zoom-controls — zoom controls plugin for `@bpmnkit/canvas`.
|
|
3
|
+
*
|
|
4
|
+
* Adds +, −, and fit-diagram buttons in the bottom-left corner of the canvas.
|
|
5
|
+
*
|
|
6
|
+
* ## Usage
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { BpmnCanvas } from "@bpmnkit/canvas";
|
|
9
|
+
* import { createZoomControlsPlugin } from "@bpmnkit/canvas-plugin-zoom-controls";
|
|
10
|
+
*
|
|
11
|
+
* const canvas = new BpmnCanvas({
|
|
12
|
+
* container: document.getElementById("app")!,
|
|
13
|
+
* xml: myBpmnXml,
|
|
14
|
+
* plugins: [createZoomControlsPlugin()],
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @packageDocumentation
|
|
19
|
+
*/
|
|
20
|
+
import type { CanvasPlugin } from "@bpmnkit/canvas";
|
|
21
|
+
export { ZOOM_CONTROLS_CSS, ZOOM_CONTROLS_STYLE_ID, injectZoomControlsStyles } from "./css.js";
|
|
22
|
+
/**
|
|
23
|
+
* Creates a zoom controls plugin instance.
|
|
24
|
+
*
|
|
25
|
+
* Each call returns a fresh plugin — pass one instance per canvas.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const canvas = new BpmnCanvas({
|
|
30
|
+
* container,
|
|
31
|
+
* plugins: [createZoomControlsPlugin()],
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare function createZoomControlsPlugin(): CanvasPlugin;
|
|
36
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @bpmnkit/canvas-plugin-zoom-controls — zoom controls plugin for `@bpmnkit/canvas`.
|
|
3
|
+
*
|
|
4
|
+
* Adds +, −, and fit-diagram buttons in the bottom-left corner of the canvas.
|
|
5
|
+
*
|
|
6
|
+
* ## Usage
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { BpmnCanvas } from "@bpmnkit/canvas";
|
|
9
|
+
* import { createZoomControlsPlugin } from "@bpmnkit/canvas-plugin-zoom-controls";
|
|
10
|
+
*
|
|
11
|
+
* const canvas = new BpmnCanvas({
|
|
12
|
+
* container: document.getElementById("app")!,
|
|
13
|
+
* xml: myBpmnXml,
|
|
14
|
+
* plugins: [createZoomControlsPlugin()],
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @packageDocumentation
|
|
19
|
+
*/
|
|
20
|
+
import { injectZoomControlsStyles } from "./css.js";
|
|
21
|
+
export { ZOOM_CONTROLS_CSS, ZOOM_CONTROLS_STYLE_ID, injectZoomControlsStyles } from "./css.js";
|
|
22
|
+
const MIN_SCALE = 0.05;
|
|
23
|
+
const MAX_SCALE = 10;
|
|
24
|
+
const FIT_PADDING = 40;
|
|
25
|
+
/**
|
|
26
|
+
* Creates a zoom controls plugin instance.
|
|
27
|
+
*
|
|
28
|
+
* Each call returns a fresh plugin — pass one instance per canvas.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const canvas = new BpmnCanvas({
|
|
33
|
+
* container,
|
|
34
|
+
* plugins: [createZoomControlsPlugin()],
|
|
35
|
+
* });
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export function createZoomControlsPlugin() {
|
|
39
|
+
let controlsEl = null;
|
|
40
|
+
return {
|
|
41
|
+
name: "zoom-controls",
|
|
42
|
+
install(api) {
|
|
43
|
+
injectZoomControlsStyles();
|
|
44
|
+
function zoomAt(factor) {
|
|
45
|
+
const { tx, ty, scale } = api.getViewport();
|
|
46
|
+
const cx = api.svg.clientWidth / 2;
|
|
47
|
+
const cy = api.svg.clientHeight / 2;
|
|
48
|
+
const newScale = Math.min(Math.max(scale * factor, MIN_SCALE), MAX_SCALE);
|
|
49
|
+
const ratio = newScale / scale;
|
|
50
|
+
api.setViewport({
|
|
51
|
+
tx: cx - (cx - tx) * ratio,
|
|
52
|
+
ty: cy - (cy - ty) * ratio,
|
|
53
|
+
scale: newScale,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function fitView() {
|
|
57
|
+
const shapes = api.getShapes();
|
|
58
|
+
if (shapes.length === 0)
|
|
59
|
+
return;
|
|
60
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
61
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
62
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
63
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
64
|
+
for (const s of shapes) {
|
|
65
|
+
const b = s.shape.bounds;
|
|
66
|
+
if (b.x < minX)
|
|
67
|
+
minX = b.x;
|
|
68
|
+
if (b.y < minY)
|
|
69
|
+
minY = b.y;
|
|
70
|
+
if (b.x + b.width > maxX)
|
|
71
|
+
maxX = b.x + b.width;
|
|
72
|
+
if (b.y + b.height > maxY)
|
|
73
|
+
maxY = b.y + b.height;
|
|
74
|
+
}
|
|
75
|
+
const svgW = api.svg.clientWidth;
|
|
76
|
+
const svgH = api.svg.clientHeight;
|
|
77
|
+
const dw = maxX - minX;
|
|
78
|
+
const dh = maxY - minY;
|
|
79
|
+
const scale = Math.min((svgW - FIT_PADDING * 2) / dw, (svgH - FIT_PADDING * 2) / dh, 2);
|
|
80
|
+
api.setViewport({
|
|
81
|
+
tx: (svgW - dw * scale) / 2 - minX * scale,
|
|
82
|
+
ty: (svgH - dh * scale) / 2 - minY * scale,
|
|
83
|
+
scale,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
const controls = document.createElement("div");
|
|
87
|
+
controls.className = "bpmnkit-controls";
|
|
88
|
+
controls.setAttribute("aria-label", "Zoom controls");
|
|
89
|
+
const makeBtn = (label, title, onClick) => {
|
|
90
|
+
const btn = document.createElement("button");
|
|
91
|
+
btn.className = "bpmnkit-control-btn";
|
|
92
|
+
btn.type = "button";
|
|
93
|
+
btn.textContent = label;
|
|
94
|
+
btn.setAttribute("aria-label", title);
|
|
95
|
+
btn.title = title;
|
|
96
|
+
btn.addEventListener("click", onClick);
|
|
97
|
+
return btn;
|
|
98
|
+
};
|
|
99
|
+
controls.appendChild(makeBtn("+", "Zoom in", () => zoomAt(1.25)));
|
|
100
|
+
controls.appendChild(makeBtn("−", "Zoom out", () => zoomAt(0.8)));
|
|
101
|
+
controls.appendChild(makeBtn("⊡", "Fit diagram", fitView));
|
|
102
|
+
api.container.appendChild(controls);
|
|
103
|
+
controlsEl = controls;
|
|
104
|
+
},
|
|
105
|
+
uninstall() {
|
|
106
|
+
controlsEl?.remove();
|
|
107
|
+
controlsEl = null;
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=index.js.map
|