@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.
Files changed (140) hide show
  1. package/README.md +153 -0
  2. package/dist/ai-bridge/css.d.ts +2 -0
  3. package/dist/ai-bridge/css.js +366 -0
  4. package/dist/ai-bridge/index.d.ts +44 -0
  5. package/dist/ai-bridge/index.js +132 -0
  6. package/dist/ai-bridge/panel.d.ts +27 -0
  7. package/dist/ai-bridge/panel.js +715 -0
  8. package/dist/ascii-view/css.d.ts +4 -0
  9. package/dist/ascii-view/css.js +83 -0
  10. package/dist/ascii-view/index.d.ts +25 -0
  11. package/dist/ascii-view/index.js +92 -0
  12. package/dist/command-palette/css.d.ts +4 -0
  13. package/dist/command-palette/css.js +157 -0
  14. package/dist/command-palette/index.d.ts +53 -0
  15. package/dist/command-palette/index.js +378 -0
  16. package/dist/command-palette-editor/index.d.ts +35 -0
  17. package/dist/command-palette-editor/index.js +60 -0
  18. package/dist/config-panel/css.d.ts +4 -0
  19. package/dist/config-panel/css.js +719 -0
  20. package/dist/config-panel/index.d.ts +36 -0
  21. package/dist/config-panel/index.js +73 -0
  22. package/dist/config-panel/renderer.d.ts +127 -0
  23. package/dist/config-panel/renderer.js +1162 -0
  24. package/dist/config-panel/types.d.ts +118 -0
  25. package/dist/config-panel/types.js +2 -0
  26. package/dist/config-panel-bpmn/index.d.ts +58 -0
  27. package/dist/config-panel-bpmn/index.js +1320 -0
  28. package/dist/config-panel-bpmn/template-engine.d.ts +17 -0
  29. package/dist/config-panel-bpmn/template-engine.js +307 -0
  30. package/dist/config-panel-bpmn/template-to-service-task.d.ts +30 -0
  31. package/dist/config-panel-bpmn/template-to-service-task.js +92 -0
  32. package/dist/config-panel-bpmn/template-types.d.ts +126 -0
  33. package/dist/config-panel-bpmn/template-types.js +6 -0
  34. package/dist/config-panel-bpmn/templates/generated.d.ts +3 -0
  35. package/dist/config-panel-bpmn/templates/generated.js +57865 -0
  36. package/dist/config-panel-bpmn/util.d.ts +46 -0
  37. package/dist/config-panel-bpmn/util.js +195 -0
  38. package/dist/dmn-editor/css.d.ts +3 -0
  39. package/dist/dmn-editor/css.js +667 -0
  40. package/dist/dmn-editor/dmn-editor.d.ts +34 -0
  41. package/dist/dmn-editor/dmn-editor.js +646 -0
  42. package/dist/dmn-editor/drd-canvas.d.ts +85 -0
  43. package/dist/dmn-editor/drd-canvas.js +1087 -0
  44. package/dist/dmn-editor/index.d.ts +3 -0
  45. package/dist/dmn-editor/index.js +2 -0
  46. package/dist/dmn-viewer/css.d.ts +3 -0
  47. package/dist/dmn-viewer/css.js +151 -0
  48. package/dist/dmn-viewer/dmn-viewer.d.ts +30 -0
  49. package/dist/dmn-viewer/dmn-viewer.js +160 -0
  50. package/dist/dmn-viewer/feel.d.ts +3 -0
  51. package/dist/dmn-viewer/feel.js +2 -0
  52. package/dist/dmn-viewer/index.d.ts +14 -0
  53. package/dist/dmn-viewer/index.js +12 -0
  54. package/dist/element-docs/content.d.ts +20 -0
  55. package/dist/element-docs/content.js +1032 -0
  56. package/dist/element-docs/index.d.ts +7 -0
  57. package/dist/element-docs/index.js +643 -0
  58. package/dist/feel-playground/css.d.ts +4 -0
  59. package/dist/feel-playground/css.js +292 -0
  60. package/dist/feel-playground/index.d.ts +4 -0
  61. package/dist/feel-playground/index.js +3 -0
  62. package/dist/feel-playground/playground-plugin.d.ts +14 -0
  63. package/dist/feel-playground/playground-plugin.js +292 -0
  64. package/dist/form-editor/css.d.ts +3 -0
  65. package/dist/form-editor/css.js +703 -0
  66. package/dist/form-editor/form-editor.d.ts +48 -0
  67. package/dist/form-editor/form-editor.js +1039 -0
  68. package/dist/form-editor/index.d.ts +3 -0
  69. package/dist/form-editor/index.js +2 -0
  70. package/dist/form-viewer/css.d.ts +3 -0
  71. package/dist/form-viewer/css.js +303 -0
  72. package/dist/form-viewer/form-viewer.d.ts +29 -0
  73. package/dist/form-viewer/form-viewer.js +376 -0
  74. package/dist/form-viewer/index.d.ts +12 -0
  75. package/dist/form-viewer/index.js +11 -0
  76. package/dist/history/checkpoint.d.ts +10 -0
  77. package/dist/history/checkpoint.js +92 -0
  78. package/dist/history/css.d.ts +2 -0
  79. package/dist/history/css.js +130 -0
  80. package/dist/history/history-panel.d.ts +12 -0
  81. package/dist/history/history-panel.js +142 -0
  82. package/dist/history/index.d.ts +5 -0
  83. package/dist/history/index.js +3 -0
  84. package/dist/main-menu/css.d.ts +4 -0
  85. package/dist/main-menu/css.js +272 -0
  86. package/dist/main-menu/index.d.ts +59 -0
  87. package/dist/main-menu/index.js +285 -0
  88. package/dist/minimap/css.d.ts +10 -0
  89. package/dist/minimap/css.js +54 -0
  90. package/dist/minimap/index.d.ts +38 -0
  91. package/dist/minimap/index.js +69 -0
  92. package/dist/minimap/minimap.d.ts +35 -0
  93. package/dist/minimap/minimap.js +166 -0
  94. package/dist/optimize/index.d.ts +21 -0
  95. package/dist/optimize/index.js +304 -0
  96. package/dist/process-runner/css.d.ts +2 -0
  97. package/dist/process-runner/css.js +467 -0
  98. package/dist/process-runner/index.d.ts +56 -0
  99. package/dist/process-runner/index.js +549 -0
  100. package/dist/storage/auto-save.d.ts +11 -0
  101. package/dist/storage/auto-save.js +44 -0
  102. package/dist/storage/css.d.ts +2 -0
  103. package/dist/storage/css.js +2 -0
  104. package/dist/storage/db.d.ts +99 -0
  105. package/dist/storage/db.js +116 -0
  106. package/dist/storage/dialog.d.ts +15 -0
  107. package/dist/storage/dialog.js +201 -0
  108. package/dist/storage/export.d.ts +3 -0
  109. package/dist/storage/export.js +137 -0
  110. package/dist/storage/index.d.ts +44 -0
  111. package/dist/storage/index.js +201 -0
  112. package/dist/storage/sidebar.d.ts +2 -0
  113. package/dist/storage/sidebar.js +2 -0
  114. package/dist/storage/storage-api.d.ts +76 -0
  115. package/dist/storage/storage-api.js +342 -0
  116. package/dist/storage/types.d.ts +44 -0
  117. package/dist/storage/types.js +2 -0
  118. package/dist/storage-tabs-bridge/index.d.ts +96 -0
  119. package/dist/storage-tabs-bridge/index.js +502 -0
  120. package/dist/tabs/css.d.ts +3 -0
  121. package/dist/tabs/css.js +642 -0
  122. package/dist/tabs/file-resolver.d.ts +71 -0
  123. package/dist/tabs/file-resolver.js +46 -0
  124. package/dist/tabs/index.d.ts +15 -0
  125. package/dist/tabs/index.js +13 -0
  126. package/dist/tabs/tabs-plugin.d.ts +250 -0
  127. package/dist/tabs/tabs-plugin.js +1119 -0
  128. package/dist/token-highlight/css.d.ts +2 -0
  129. package/dist/token-highlight/css.js +81 -0
  130. package/dist/token-highlight/index.d.ts +44 -0
  131. package/dist/token-highlight/index.js +164 -0
  132. package/dist/watermark/css.d.ts +10 -0
  133. package/dist/watermark/css.js +54 -0
  134. package/dist/watermark/index.d.ts +48 -0
  135. package/dist/watermark/index.js +64 -0
  136. package/dist/zoom-controls/css.d.ts +4 -0
  137. package/dist/zoom-controls/css.js +48 -0
  138. package/dist/zoom-controls/index.d.ts +36 -0
  139. package/dist/zoom-controls/index.js +111 -0
  140. package/package.json +121 -0
@@ -0,0 +1,285 @@
1
+ /**
2
+ * @bpmnkit/canvas-plugin-main-menu — main menu plugin for `@bpmnkit/canvas`.
3
+ *
4
+ * Adds a panel in the top-right corner of the canvas with an optional title
5
+ * and a menu button. The menu lets users switch between light, dark, and
6
+ * automatic (OS-preference) color themes. Supports drill-down navigation,
7
+ * dynamic items, and a programmatic API for title/items injection.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+ import { injectMainMenuStyles } from "./css.js";
12
+ export { MAIN_MENU_CSS, MAIN_MENU_STYLE_ID, injectMainMenuStyles } from "./css.js";
13
+ const DOTS_ICON = '<svg viewBox="0 0 16 16" fill="currentColor"><circle cx="3.5" cy="8" r="1.3"/><circle cx="8" cy="8" r="1.3"/><circle cx="12.5" cy="8" r="1.3"/></svg>';
14
+ const CHECK_ICON = '<svg viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="1.5,6 4.5,9 10.5,3"/></svg>';
15
+ const MOON_ICON = '<svg viewBox="0 0 16 16" fill="currentColor"><path d="M13 9.5a6 6 0 1 1-7.5-7.5 7 7 0 0 0 7.5 7.5z"/></svg>';
16
+ const SUN_ICON = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="8" cy="8" r="2.8"/><line x1="8" y1="1.5" x2="8" y2="3"/><line x1="8" y1="13" x2="8" y2="14.5"/><line x1="1.5" y1="8" x2="3" y2="8"/><line x1="13" y1="8" x2="14.5" y2="8"/><line x1="3.3" y1="3.3" x2="4.4" y2="4.4"/><line x1="11.6" y1="11.6" x2="12.7" y2="12.7"/><line x1="3.3" y1="12.7" x2="4.4" y2="11.6"/><line x1="11.6" y1="4.4" x2="12.7" y2="3.3"/></svg>';
17
+ const AUTO_ICON = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="8" cy="8" r="5.5"/><path d="M8 8V3.5"/><path d="M8 8l3.2 2"/></svg>';
18
+ const BACK_ICON = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><polyline points="10,3 5,8 10,13"/></svg>';
19
+ const ARROW_ICON = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><polyline points="6,3 11,8 6,13"/></svg>';
20
+ const THEMES = [
21
+ { value: "dark", label: "Dark", icon: MOON_ICON },
22
+ { value: "light", label: "Light", icon: SUN_ICON },
23
+ { value: "auto", label: "System", icon: AUTO_ICON },
24
+ ];
25
+ /**
26
+ * Creates a main menu plugin instance.
27
+ *
28
+ * Each call returns a fresh plugin — pass one instance per canvas.
29
+ */
30
+ export function createMainMenuPlugin(options = {}) {
31
+ let dropdownEl = null;
32
+ let panelEl = null;
33
+ let titleEl = null;
34
+ let isOpen = false;
35
+ let navStack = [];
36
+ let dynamicItemsFn = null;
37
+ let currentTheme = "light";
38
+ let _setTheme = () => { };
39
+ const offPointerDown = { fn: (_e) => { } };
40
+ const api = {
41
+ setTitle(text) {
42
+ if (titleEl)
43
+ titleEl.textContent = text;
44
+ },
45
+ setDynamicItems(fn) {
46
+ dynamicItemsFn = fn;
47
+ },
48
+ };
49
+ function buildRootItems() {
50
+ const dynamic = dynamicItemsFn ? dynamicItemsFn() : [];
51
+ const staticItems = options.menuItems ?? [];
52
+ const themeSection = [
53
+ { type: "separator" },
54
+ {
55
+ type: "drill",
56
+ label: "Theme",
57
+ items: () => THEMES.map((t) => ({
58
+ label: t.label,
59
+ icon: t.icon,
60
+ onClick: () => {
61
+ currentTheme = t.value;
62
+ _setTheme(t.value);
63
+ closeDropdown();
64
+ },
65
+ })),
66
+ },
67
+ ];
68
+ const beforeTheme = [...dynamic, ...staticItems];
69
+ return [...beforeTheme, ...themeSection];
70
+ }
71
+ function resolveItems(items) {
72
+ return typeof items === "function" ? items() : items;
73
+ }
74
+ function closeDropdown() {
75
+ dropdownEl?.classList.remove("open");
76
+ isOpen = false;
77
+ }
78
+ function buildLevelContent(dropdown) {
79
+ const slot = document.createElement("div");
80
+ slot.className = "bpmnkit-menu-level";
81
+ const level = navStack[navStack.length - 1];
82
+ if (!level)
83
+ return slot;
84
+ if (navStack.length > 1) {
85
+ const backRow = document.createElement("div");
86
+ backRow.className = "bpmnkit-menu-back-row";
87
+ const backBtn = document.createElement("button");
88
+ backBtn.className = "bpmnkit-menu-back-btn";
89
+ backBtn.type = "button";
90
+ backBtn.innerHTML = BACK_ICON;
91
+ backBtn.addEventListener("click", () => {
92
+ navStack.pop();
93
+ renderLevel(dropdown, "back");
94
+ });
95
+ const levelTitle = document.createElement("span");
96
+ levelTitle.className = "bpmnkit-menu-level-title";
97
+ levelTitle.textContent = level.title ?? "";
98
+ backRow.append(backBtn, levelTitle);
99
+ slot.appendChild(backRow);
100
+ const sep = document.createElement("div");
101
+ sep.className = "bpmnkit-menu-drop-sep";
102
+ slot.appendChild(sep);
103
+ }
104
+ for (const item of level.items) {
105
+ slot.appendChild(buildItemEl(item, dropdown));
106
+ }
107
+ return slot;
108
+ }
109
+ function renderLevel(dropdown, direction) {
110
+ const newSlot = buildLevelContent(dropdown);
111
+ if (direction === "initial") {
112
+ dropdown.textContent = "";
113
+ dropdown.appendChild(newSlot);
114
+ return;
115
+ }
116
+ const oldSlot = dropdown.querySelector(".bpmnkit-menu-level");
117
+ // Freeze width so the dropdown doesn't shrink/grow during animation
118
+ dropdown.style.minWidth = `${dropdown.offsetWidth}px`;
119
+ // Exit: absolutely positioned so it doesn't affect layout
120
+ if (oldSlot) {
121
+ oldSlot.style.cssText = "position:absolute;inset:0;pointer-events:none;z-index:0;";
122
+ oldSlot.classList.add(direction === "forward" ? "bpmnkit-menu-level--out-left" : "bpmnkit-menu-level--out-right");
123
+ }
124
+ // Enter: on top, drives height
125
+ newSlot.classList.add(direction === "forward" ? "bpmnkit-menu-level--in-right" : "bpmnkit-menu-level--in-left");
126
+ dropdown.appendChild(newSlot);
127
+ setTimeout(() => {
128
+ oldSlot?.remove();
129
+ newSlot.classList.remove("bpmnkit-menu-level--in-right", "bpmnkit-menu-level--in-left");
130
+ dropdown.style.minWidth = "";
131
+ }, 200);
132
+ }
133
+ function buildItemEl(item, dropdown) {
134
+ if ("type" in item && item.type === "separator") {
135
+ const sep = document.createElement("div");
136
+ sep.className = "bpmnkit-menu-drop-sep";
137
+ return sep;
138
+ }
139
+ if ("type" in item && item.type === "info") {
140
+ const row = document.createElement("div");
141
+ row.className = "bpmnkit-menu-info-row";
142
+ const textSpan = document.createElement("span");
143
+ textSpan.className = "bpmnkit-menu-info-text";
144
+ textSpan.textContent = item.text;
145
+ row.appendChild(textSpan);
146
+ if (item.actionLabel && item.onAction) {
147
+ const actionBtn = document.createElement("button");
148
+ actionBtn.className = "bpmnkit-menu-info-action";
149
+ actionBtn.type = "button";
150
+ actionBtn.textContent = item.actionLabel;
151
+ const onAction = item.onAction;
152
+ actionBtn.addEventListener("click", () => {
153
+ closeDropdown();
154
+ onAction();
155
+ });
156
+ row.appendChild(actionBtn);
157
+ }
158
+ return row;
159
+ }
160
+ if ("type" in item && item.type === "drill") {
161
+ const btn = document.createElement("button");
162
+ btn.className = "bpmnkit-menu-item";
163
+ btn.type = "button";
164
+ const checkSpan = document.createElement("span");
165
+ checkSpan.className = "bpmnkit-menu-item-check";
166
+ btn.appendChild(checkSpan);
167
+ const iconSpan = document.createElement("span");
168
+ iconSpan.className = "bpmnkit-menu-item-icon";
169
+ if (item.icon)
170
+ iconSpan.innerHTML = item.icon;
171
+ btn.appendChild(iconSpan);
172
+ const labelSpan = document.createElement("span");
173
+ labelSpan.className = "bpmnkit-menu-item-label";
174
+ labelSpan.textContent = item.label;
175
+ btn.appendChild(labelSpan);
176
+ const arrowSpan = document.createElement("span");
177
+ arrowSpan.className = "bpmnkit-menu-item-arrow";
178
+ arrowSpan.innerHTML = ARROW_ICON;
179
+ btn.appendChild(arrowSpan);
180
+ const drillItems = item.items;
181
+ btn.addEventListener("click", () => {
182
+ navStack.push({ title: item.label, items: resolveItems(drillItems) });
183
+ renderLevel(dropdown, "forward");
184
+ });
185
+ return btn;
186
+ }
187
+ // MenuAction
188
+ const action = item;
189
+ const btn = document.createElement("button");
190
+ btn.className = "bpmnkit-menu-item";
191
+ btn.type = "button";
192
+ const checkSpan = document.createElement("span");
193
+ checkSpan.className = "bpmnkit-menu-item-check";
194
+ // Show check mark for active theme when inside a drill level
195
+ const themeMatch = THEMES.find((t) => t.label === action.label);
196
+ if (themeMatch && themeMatch.value === currentTheme) {
197
+ checkSpan.innerHTML = CHECK_ICON;
198
+ }
199
+ btn.appendChild(checkSpan);
200
+ const iconSpan = document.createElement("span");
201
+ iconSpan.className = "bpmnkit-menu-item-icon";
202
+ if (action.icon)
203
+ iconSpan.innerHTML = action.icon;
204
+ btn.appendChild(iconSpan);
205
+ const labelSpan = document.createElement("span");
206
+ labelSpan.className = "bpmnkit-menu-item-label";
207
+ labelSpan.textContent = action.label;
208
+ btn.appendChild(labelSpan);
209
+ btn.addEventListener("click", () => {
210
+ closeDropdown();
211
+ action.onClick();
212
+ });
213
+ return btn;
214
+ }
215
+ return {
216
+ name: "main-menu",
217
+ api,
218
+ install(canvasApi) {
219
+ injectMainMenuStyles();
220
+ currentTheme = canvasApi.getTheme();
221
+ _setTheme = (t) => canvasApi.setTheme(t);
222
+ // ── Panel ────────────────────────────────────────────────────
223
+ const panel = document.createElement("div");
224
+ panel.className = "bpmnkit-main-menu-panel";
225
+ if (options.title) {
226
+ const title = document.createElement("span");
227
+ title.className = "bpmnkit-main-menu-title";
228
+ title.textContent = options.title;
229
+ panel.appendChild(title);
230
+ titleEl = title;
231
+ const sep = document.createElement("div");
232
+ sep.className = "bpmnkit-main-menu-sep";
233
+ panel.appendChild(sep);
234
+ }
235
+ const menuBtn = document.createElement("button");
236
+ menuBtn.className = "bpmnkit-menu-btn";
237
+ menuBtn.type = "button";
238
+ menuBtn.setAttribute("aria-label", "Main menu");
239
+ menuBtn.title = "Main menu";
240
+ menuBtn.innerHTML = DOTS_ICON;
241
+ panel.appendChild(menuBtn);
242
+ canvasApi.container.appendChild(panel);
243
+ panelEl = panel;
244
+ // ── Dropdown ─────────────────────────────────────────────────
245
+ const dropdown = document.createElement("div");
246
+ dropdown.className = "bpmnkit-menu-dropdown";
247
+ document.body.appendChild(dropdown);
248
+ dropdownEl = dropdown;
249
+ menuBtn.addEventListener("pointerdown", (e) => {
250
+ e.stopPropagation();
251
+ });
252
+ menuBtn.addEventListener("click", () => {
253
+ if (isOpen) {
254
+ closeDropdown();
255
+ }
256
+ else {
257
+ navStack = [{ items: buildRootItems() }];
258
+ renderLevel(dropdown, "initial");
259
+ const rect = menuBtn.getBoundingClientRect();
260
+ dropdown.style.top = `${rect.bottom + 6}px`;
261
+ dropdown.style.right = `${window.innerWidth - rect.right}px`;
262
+ dropdown.style.left = "auto";
263
+ dropdown.classList.add("open");
264
+ isOpen = true;
265
+ }
266
+ });
267
+ offPointerDown.fn = (e) => {
268
+ if (isOpen && !dropdown.contains(e.target)) {
269
+ closeDropdown();
270
+ }
271
+ };
272
+ document.addEventListener("pointerdown", offPointerDown.fn);
273
+ },
274
+ uninstall() {
275
+ document.removeEventListener("pointerdown", offPointerDown.fn);
276
+ dropdownEl?.remove();
277
+ dropdownEl = null;
278
+ panelEl?.remove();
279
+ panelEl = null;
280
+ titleEl = null;
281
+ isOpen = false;
282
+ },
283
+ };
284
+ }
285
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,10 @@
1
+ /** ID used to prevent duplicate style injection. */
2
+ export declare const MINIMAP_STYLE_ID = "bpmnkit-minimap-styles-v1";
3
+ /** CSS for the minimap plugin, injected once into `<head>`. */
4
+ export declare const MINIMAP_CSS = "\n.bpmnkit-minimap {\n position: absolute;\n bottom: 12px;\n right: 12px;\n width: 160px;\n height: 100px;\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: 6px;\n overflow: hidden;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);\n cursor: crosshair;\n}\n.bpmnkit-minimap > svg {\n display: block;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.bpmnkit-minimap-shape {\n fill: var(--bpmnkit-shape-stroke, #404040);\n opacity: 0.45;\n}\n.bpmnkit-minimap-edge {\n stroke: var(--bpmnkit-shape-stroke, #404040);\n stroke-width: 0.5;\n fill: none;\n opacity: 0.35;\n}\n.bpmnkit-minimap-viewport {\n fill: var(--bpmnkit-viewport-fill, var(--bpmnkit-accent-subtle, rgba(26,86,219,0.12)));\n stroke: var(--bpmnkit-viewport-stroke, var(--bpmnkit-accent, #1a56db));\n stroke-width: 1;\n}\n";
5
+ /**
6
+ * Injects the minimap 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 injectMinimapStyles(): void;
10
+ //# sourceMappingURL=css.d.ts.map
@@ -0,0 +1,54 @@
1
+ /** ID used to prevent duplicate style injection. */
2
+ export const MINIMAP_STYLE_ID = "bpmnkit-minimap-styles-v1";
3
+ /** CSS for the minimap plugin, injected once into `<head>`. */
4
+ export const MINIMAP_CSS = `
5
+ .bpmnkit-minimap {
6
+ position: absolute;
7
+ bottom: 12px;
8
+ right: 12px;
9
+ width: 160px;
10
+ height: 100px;
11
+ background: var(--bpmnkit-overlay-bg, rgba(248, 249, 250, 0.92));
12
+ border: 1px solid var(--bpmnkit-overlay-border, rgba(0, 0, 0, 0.12));
13
+ border-radius: 6px;
14
+ overflow: hidden;
15
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
16
+ cursor: crosshair;
17
+ }
18
+ .bpmnkit-minimap > svg {
19
+ display: block;
20
+ width: 100%;
21
+ height: 100%;
22
+ pointer-events: none;
23
+ }
24
+ .bpmnkit-minimap-shape {
25
+ fill: var(--bpmnkit-shape-stroke, #404040);
26
+ opacity: 0.45;
27
+ }
28
+ .bpmnkit-minimap-edge {
29
+ stroke: var(--bpmnkit-shape-stroke, #404040);
30
+ stroke-width: 0.5;
31
+ fill: none;
32
+ opacity: 0.35;
33
+ }
34
+ .bpmnkit-minimap-viewport {
35
+ fill: var(--bpmnkit-viewport-fill, var(--bpmnkit-accent-subtle, rgba(26,86,219,0.12)));
36
+ stroke: var(--bpmnkit-viewport-stroke, var(--bpmnkit-accent, #1a56db));
37
+ stroke-width: 1;
38
+ }
39
+ `;
40
+ /**
41
+ * Injects the minimap stylesheet into `<head>` if not already present.
42
+ * Safe to call multiple times — only one `<style>` tag is ever inserted.
43
+ */
44
+ export function injectMinimapStyles() {
45
+ if (typeof document === "undefined")
46
+ return;
47
+ if (document.getElementById(MINIMAP_STYLE_ID))
48
+ return;
49
+ const style = document.createElement("style");
50
+ style.id = MINIMAP_STYLE_ID;
51
+ style.textContent = MINIMAP_CSS;
52
+ document.head.appendChild(style);
53
+ }
54
+ //# sourceMappingURL=css.js.map
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @bpmnkit/canvas-plugin-minimap — minimap navigation plugin for `@bpmnkit/canvas`.
3
+ *
4
+ * Adds a 160×100 overview panel in the bottom-right corner of the canvas.
5
+ * Clicking the minimap pans the main viewport to that position.
6
+ *
7
+ * ## Usage
8
+ * ```typescript
9
+ * import { BpmnCanvas } from "@bpmnkit/canvas";
10
+ * import { createMinimapPlugin } from "@bpmnkit/canvas-plugin-minimap";
11
+ *
12
+ * const canvas = new BpmnCanvas({
13
+ * container: document.getElementById("app")!,
14
+ * xml: myBpmnXml,
15
+ * plugins: [createMinimapPlugin()],
16
+ * });
17
+ * ```
18
+ *
19
+ * @packageDocumentation
20
+ */
21
+ import type { CanvasPlugin } from "@bpmnkit/canvas";
22
+ export { Minimap } from "./minimap.js";
23
+ export { MINIMAP_CSS, MINIMAP_STYLE_ID, injectMinimapStyles } from "./css.js";
24
+ /**
25
+ * Creates a minimap plugin instance.
26
+ *
27
+ * Each call returns a fresh plugin — pass one instance per canvas.
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * const canvas = new BpmnCanvas({
32
+ * container,
33
+ * plugins: [createMinimapPlugin()],
34
+ * });
35
+ * ```
36
+ */
37
+ export declare function createMinimapPlugin(): CanvasPlugin;
38
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,69 @@
1
+ /**
2
+ * @bpmnkit/canvas-plugin-minimap — minimap navigation plugin for `@bpmnkit/canvas`.
3
+ *
4
+ * Adds a 160×100 overview panel in the bottom-right corner of the canvas.
5
+ * Clicking the minimap pans the main viewport to that position.
6
+ *
7
+ * ## Usage
8
+ * ```typescript
9
+ * import { BpmnCanvas } from "@bpmnkit/canvas";
10
+ * import { createMinimapPlugin } from "@bpmnkit/canvas-plugin-minimap";
11
+ *
12
+ * const canvas = new BpmnCanvas({
13
+ * container: document.getElementById("app")!,
14
+ * xml: myBpmnXml,
15
+ * plugins: [createMinimapPlugin()],
16
+ * });
17
+ * ```
18
+ *
19
+ * @packageDocumentation
20
+ */
21
+ import { injectMinimapStyles } from "./css.js";
22
+ import { Minimap } from "./minimap.js";
23
+ export { Minimap } from "./minimap.js";
24
+ export { MINIMAP_CSS, MINIMAP_STYLE_ID, injectMinimapStyles } from "./css.js";
25
+ /**
26
+ * Creates a minimap 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: [createMinimapPlugin()],
35
+ * });
36
+ * ```
37
+ */
38
+ export function createMinimapPlugin() {
39
+ let minimap = null;
40
+ const unsubs = [];
41
+ return {
42
+ name: "minimap",
43
+ install(api) {
44
+ injectMinimapStyles();
45
+ minimap = new Minimap(api.container, (diagX, diagY) => {
46
+ const { scale } = api.getViewport();
47
+ api.setViewport({
48
+ tx: api.svg.clientWidth / 2 - diagX * scale,
49
+ ty: api.svg.clientHeight / 2 - diagY * scale,
50
+ });
51
+ });
52
+ unsubs.push(api.on("diagram:load", (defs) => {
53
+ minimap?.update(defs);
54
+ }), api.on("viewport:change", (state) => {
55
+ minimap?.syncViewport(state, api.svg.clientWidth, api.svg.clientHeight);
56
+ }), api.on("diagram:clear", () => {
57
+ minimap?.clear();
58
+ }));
59
+ },
60
+ uninstall() {
61
+ for (const off of unsubs)
62
+ off();
63
+ unsubs.length = 0;
64
+ minimap?.destroy();
65
+ minimap = null;
66
+ },
67
+ };
68
+ }
69
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,35 @@
1
+ import type { ViewportState } from "@bpmnkit/canvas";
2
+ import type { BpmnDefinitions } from "@bpmnkit/core";
3
+ /**
4
+ * A scaled-down overview of the BPMN diagram that shows the current viewport
5
+ * position as a highlighted rectangle.
6
+ *
7
+ * Clicking the minimap pans the canvas to that position.
8
+ */
9
+ export declare class Minimap {
10
+ /** Invoked when the user clicks the minimap to request a viewport pan. */
11
+ private readonly _onNavigate;
12
+ private readonly _host;
13
+ private readonly _svg;
14
+ private readonly _shapesG;
15
+ private readonly _edgesG;
16
+ private readonly _viewportRect;
17
+ private _scale;
18
+ private _offsetX;
19
+ private _offsetY;
20
+ private readonly _mmW;
21
+ private readonly _mmH;
22
+ constructor(container: HTMLElement,
23
+ /** Invoked when the user clicks the minimap to request a viewport pan. */
24
+ _onNavigate: (diagX: number, diagY: number) => void);
25
+ /** Updates the minimap with shapes and edges from a newly loaded diagram. */
26
+ update(defs: BpmnDefinitions): void;
27
+ /** Clears the minimap content. */
28
+ clear(): void;
29
+ /** Syncs the viewport indicator rectangle with the current pan/zoom state. */
30
+ syncViewport(state: ViewportState, svgWidth: number, svgHeight: number): void;
31
+ /** Removes the minimap from the DOM. */
32
+ destroy(): void;
33
+ private readonly _onClick;
34
+ }
35
+ //# sourceMappingURL=minimap.d.ts.map
@@ -0,0 +1,166 @@
1
+ const NS = "http://www.w3.org/2000/svg";
2
+ function svgEl(tag) {
3
+ return document.createElementNS(NS, tag);
4
+ }
5
+ function attr(el, attrs) {
6
+ for (const [k, v] of Object.entries(attrs))
7
+ el.setAttribute(k, String(v));
8
+ }
9
+ /**
10
+ * A scaled-down overview of the BPMN diagram that shows the current viewport
11
+ * position as a highlighted rectangle.
12
+ *
13
+ * Clicking the minimap pans the canvas to that position.
14
+ */
15
+ export class Minimap {
16
+ _onNavigate;
17
+ _host;
18
+ _svg;
19
+ _shapesG;
20
+ _edgesG;
21
+ _viewportRect;
22
+ // Minimap-space transform from diagram-space coordinates
23
+ _scale = 1;
24
+ _offsetX = 0;
25
+ _offsetY = 0;
26
+ // Minimap pixel dimensions
27
+ _mmW = 160;
28
+ _mmH = 100;
29
+ constructor(container,
30
+ /** Invoked when the user clicks the minimap to request a viewport pan. */
31
+ _onNavigate) {
32
+ this._onNavigate = _onNavigate;
33
+ this._host = document.createElement("div");
34
+ this._host.className = "bpmnkit-minimap";
35
+ this._host.setAttribute("aria-hidden", "true");
36
+ this._svg = document.createElementNS(NS, "svg");
37
+ attr(this._svg, {
38
+ viewBox: `0 0 ${this._mmW} ${this._mmH}`,
39
+ preserveAspectRatio: "none",
40
+ });
41
+ this._host.appendChild(this._svg);
42
+ this._edgesG = svgEl("g");
43
+ this._shapesG = svgEl("g");
44
+ this._viewportRect = svgEl("rect");
45
+ attr(this._viewportRect, { class: "bpmnkit-minimap-viewport", rx: 1 });
46
+ this._svg.appendChild(this._edgesG);
47
+ this._svg.appendChild(this._shapesG);
48
+ this._svg.appendChild(this._viewportRect);
49
+ container.appendChild(this._host);
50
+ this._host.addEventListener("click", this._onClick);
51
+ }
52
+ /** Updates the minimap with shapes and edges from a newly loaded diagram. */
53
+ update(defs) {
54
+ this._edgesG.innerHTML = "";
55
+ this._shapesG.innerHTML = "";
56
+ const plane = defs.diagrams[0]?.plane;
57
+ if (!plane)
58
+ return;
59
+ // Compute diagram bounding box
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 plane.shapes) {
65
+ minX = Math.min(minX, s.bounds.x);
66
+ minY = Math.min(minY, s.bounds.y);
67
+ maxX = Math.max(maxX, s.bounds.x + s.bounds.width);
68
+ maxY = Math.max(maxY, s.bounds.y + s.bounds.height);
69
+ }
70
+ for (const e of plane.edges) {
71
+ for (const wp of e.waypoints) {
72
+ minX = Math.min(minX, wp.x);
73
+ minY = Math.min(minY, wp.y);
74
+ maxX = Math.max(maxX, wp.x);
75
+ maxY = Math.max(maxY, wp.y);
76
+ }
77
+ }
78
+ if (!Number.isFinite(minX))
79
+ return;
80
+ const padding = 8;
81
+ const dW = maxX - minX;
82
+ const dH = maxY - minY;
83
+ const scaleX = (this._mmW - padding * 2) / dW;
84
+ const scaleY = (this._mmH - padding * 2) / dH;
85
+ this._scale = Math.min(scaleX, scaleY);
86
+ this._offsetX = padding + (this._mmW - padding * 2 - dW * this._scale) / 2 - minX * this._scale;
87
+ this._offsetY = padding + (this._mmH - padding * 2 - dH * this._scale) / 2 - minY * this._scale;
88
+ // Render simplified shapes (just rects/circles)
89
+ for (const s of plane.shapes) {
90
+ const x = s.bounds.x * this._scale + this._offsetX;
91
+ const y = s.bounds.y * this._scale + this._offsetY;
92
+ const w = s.bounds.width * this._scale;
93
+ const h = s.bounds.height * this._scale;
94
+ // Approximate shape type from size: very small square → event or gateway
95
+ const isSmall = w < 10;
96
+ if (isSmall) {
97
+ const circle = svgEl("circle");
98
+ attr(circle, {
99
+ cx: x + w / 2,
100
+ cy: y + h / 2,
101
+ r: Math.max(w / 2, 2),
102
+ class: "bpmnkit-minimap-shape",
103
+ });
104
+ this._shapesG.appendChild(circle);
105
+ }
106
+ else {
107
+ const rect = svgEl("rect");
108
+ attr(rect, {
109
+ x,
110
+ y,
111
+ width: Math.max(w, 1),
112
+ height: Math.max(h, 1),
113
+ rx: 1,
114
+ class: "bpmnkit-minimap-shape",
115
+ });
116
+ this._shapesG.appendChild(rect);
117
+ }
118
+ }
119
+ // Render simplified edges
120
+ for (const e of plane.edges) {
121
+ if (e.waypoints.length < 2)
122
+ continue;
123
+ const pts = e.waypoints
124
+ .map((wp) => `${wp.x * this._scale + this._offsetX},${wp.y * this._scale + this._offsetY}`)
125
+ .join(" ");
126
+ const poly = svgEl("polyline");
127
+ attr(poly, { points: pts, class: "bpmnkit-minimap-edge" });
128
+ this._edgesG.appendChild(poly);
129
+ }
130
+ }
131
+ /** Clears the minimap content. */
132
+ clear() {
133
+ this._edgesG.innerHTML = "";
134
+ this._shapesG.innerHTML = "";
135
+ attr(this._viewportRect, { x: 0, y: 0, width: 0, height: 0 });
136
+ }
137
+ /** Syncs the viewport indicator rectangle with the current pan/zoom state. */
138
+ syncViewport(state, svgWidth, svgHeight) {
139
+ // Visible diagram area in diagram coordinates
140
+ const left = -state.tx / state.scale;
141
+ const top = -state.ty / state.scale;
142
+ const visW = svgWidth / state.scale;
143
+ const visH = svgHeight / state.scale;
144
+ // Map to minimap coordinates
145
+ const mx = left * this._scale + this._offsetX;
146
+ const my = top * this._scale + this._offsetY;
147
+ const mw = visW * this._scale;
148
+ const mh = visH * this._scale;
149
+ attr(this._viewportRect, { x: mx, y: my, width: Math.max(mw, 2), height: Math.max(mh, 2) });
150
+ }
151
+ /** Removes the minimap from the DOM. */
152
+ destroy() {
153
+ this._host.removeEventListener("click", this._onClick);
154
+ this._host.remove();
155
+ }
156
+ _onClick = (e) => {
157
+ const rect = this._host.getBoundingClientRect();
158
+ const mmX = e.clientX - rect.left;
159
+ const mmY = e.clientY - rect.top;
160
+ // Convert minimap coordinates to diagram coordinates
161
+ const diagX = (mmX - this._offsetX) / this._scale;
162
+ const diagY = (mmY - this._offsetY) / this._scale;
163
+ this._onNavigate(diagX, diagY);
164
+ };
165
+ }
166
+ //# sourceMappingURL=minimap.js.map