@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
package/dist/dock.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface SideDock {
|
|
2
|
+
el: HTMLDivElement;
|
|
3
|
+
propertiesPane: HTMLDivElement;
|
|
4
|
+
historyPane: HTMLDivElement;
|
|
5
|
+
aiPane: HTMLDivElement;
|
|
6
|
+
playPane: HTMLDivElement;
|
|
7
|
+
docsPane: HTMLDivElement;
|
|
8
|
+
switchTab(tab: "properties" | "history" | "ai" | "play" | "docs"): void;
|
|
9
|
+
expand(): void;
|
|
10
|
+
collapse(): void;
|
|
11
|
+
get collapsed(): boolean;
|
|
12
|
+
get activeTab(): "properties" | "history" | "ai" | "play" | "docs";
|
|
13
|
+
/** Update the info shown in the Properties empty state. */
|
|
14
|
+
setDiagramInfo(processName: string | null, fileName: string | null): void;
|
|
15
|
+
/** Hide the empty state when a config panel is displayed. */
|
|
16
|
+
showPanel(): void;
|
|
17
|
+
/** Restore the empty state when the config panel is dismissed. */
|
|
18
|
+
hidePanel(): void;
|
|
19
|
+
/** Show or hide the entire dock (e.g. hide on welcome screen, show on tab open). */
|
|
20
|
+
setVisible(visible: boolean): void;
|
|
21
|
+
/** Register a callback invoked when the AI tab is clicked (after switching to it). */
|
|
22
|
+
setAiTabClickHandler(fn: () => void): void;
|
|
23
|
+
/** Register a callback invoked when the History tab is clicked (after switching to it). */
|
|
24
|
+
setHistoryTabClickHandler(fn: () => void): void;
|
|
25
|
+
/** Enable or disable the History tab (disable when no storage context is available). */
|
|
26
|
+
setHistoryTabEnabled(enabled: boolean): void;
|
|
27
|
+
/** Show or hide the Play tab (shown when process runner enters play mode). */
|
|
28
|
+
setPlayTabVisible(visible: boolean): void;
|
|
29
|
+
/** Register a callback invoked when the Play tab is clicked. */
|
|
30
|
+
setPlayTabClickHandler(fn: () => void): void;
|
|
31
|
+
/** Register a callback invoked when the Docs tab is clicked. */
|
|
32
|
+
setDocsTabClickHandler(fn: () => void): void;
|
|
33
|
+
}
|
|
34
|
+
export declare function createSideDock(): SideDock;
|
|
35
|
+
//# sourceMappingURL=dock.d.ts.map
|
package/dist/dock.js
ADDED
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
const DOCK_STYLE_ID = "bpmnkit-side-dock-styles-v1";
|
|
2
|
+
const STORAGE_KEY_WIDTH = "bpmnkit-side-dock-width";
|
|
3
|
+
const STORAGE_KEY_COLLAPSED = "bpmnkit-side-dock-collapsed";
|
|
4
|
+
const MIN_WIDTH = 280;
|
|
5
|
+
const MAX_WIDTH = 700;
|
|
6
|
+
const DEFAULT_WIDTH = 360;
|
|
7
|
+
const DOCK_CSS = `
|
|
8
|
+
/* ── Side Dock ──────────────────────────────────────────────────────────── */
|
|
9
|
+
.bpmnkit-side-dock__tab:disabled { opacity: 0.3; cursor: default; }
|
|
10
|
+
.bpmnkit-side-dock {
|
|
11
|
+
position: fixed; right: 0; top: 36px; bottom: 0;
|
|
12
|
+
z-index: 9999; display: flex; flex-direction: column;
|
|
13
|
+
background: rgba(18, 18, 26, 0.98);
|
|
14
|
+
border-left: 1px solid rgba(255,255,255,0.1);
|
|
15
|
+
box-shadow: -8px 0 40px rgba(0,0,0,0.6);
|
|
16
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
17
|
+
transition: width 0.22s ease;
|
|
18
|
+
}
|
|
19
|
+
/* Pill handle — sticks out from the left edge; always visible + clickable */
|
|
20
|
+
.bpmnkit-side-dock__collapse-handle {
|
|
21
|
+
position: absolute; left: -20px; top: 50%; transform: translateY(-50%);
|
|
22
|
+
width: 20px; height: 52px;
|
|
23
|
+
background: rgba(18, 18, 26, 0.98);
|
|
24
|
+
border: 1px solid rgba(255,255,255,0.1); border-right: none;
|
|
25
|
+
border-radius: 8px 0 0 8px;
|
|
26
|
+
display: flex; align-items: center; justify-content: center;
|
|
27
|
+
cursor: pointer; z-index: 1;
|
|
28
|
+
color: rgba(255,255,255,0.45); font-size: 14px; line-height: 1;
|
|
29
|
+
transition: color 0.1s, background 0.1s;
|
|
30
|
+
user-select: none;
|
|
31
|
+
}
|
|
32
|
+
.bpmnkit-side-dock__collapse-handle:hover { color: #fff; background: rgba(40,40,60,0.99); }
|
|
33
|
+
.bpmnkit-side-dock__resize-handle {
|
|
34
|
+
position: absolute; left: 0; top: 0; bottom: 0;
|
|
35
|
+
width: 5px; cursor: ew-resize; z-index: 2;
|
|
36
|
+
}
|
|
37
|
+
.bpmnkit-side-dock__resize-handle:hover { background: rgba(76,142,247,0.35); }
|
|
38
|
+
.bpmnkit-side-dock__tab-strip {
|
|
39
|
+
display: flex; align-items: center; height: 38px; flex-shrink: 0;
|
|
40
|
+
border-bottom: 1px solid rgba(255,255,255,0.08);
|
|
41
|
+
}
|
|
42
|
+
.bpmnkit-side-dock__tab {
|
|
43
|
+
padding: 0 16px; height: 100%; background: none; border: none;
|
|
44
|
+
border-bottom: 2px solid transparent; color: rgba(255,255,255,0.4);
|
|
45
|
+
cursor: pointer; font-size: 12px; font-weight: 500; white-space: nowrap;
|
|
46
|
+
transition: color 0.1s, border-color 0.1s;
|
|
47
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
48
|
+
}
|
|
49
|
+
.bpmnkit-side-dock__tab:hover { color: rgba(255,255,255,0.75); }
|
|
50
|
+
.bpmnkit-side-dock__tab.active { color: #4c8ef7; border-bottom-color: #4c8ef7; }
|
|
51
|
+
.bpmnkit-side-dock__pane {
|
|
52
|
+
flex: 1; display: flex; flex-direction: column; overflow: hidden; min-height: 0;
|
|
53
|
+
}
|
|
54
|
+
.bpmnkit-side-dock__pane--hidden { display: none; }
|
|
55
|
+
/* Empty state — info widget + hint, shown when no element is selected */
|
|
56
|
+
.bpmnkit-side-dock__empty {
|
|
57
|
+
flex: 1; display: flex; flex-direction: column;
|
|
58
|
+
overflow-y: auto; padding: 14px 16px;
|
|
59
|
+
gap: 0;
|
|
60
|
+
}
|
|
61
|
+
.bpmnkit-side-dock__info-row {
|
|
62
|
+
display: flex; flex-direction: column;
|
|
63
|
+
padding: 10px 0;
|
|
64
|
+
border-bottom: 1px solid rgba(255,255,255,0.06);
|
|
65
|
+
gap: 3px;
|
|
66
|
+
}
|
|
67
|
+
.bpmnkit-side-dock__info-label {
|
|
68
|
+
font-size: 10px; font-weight: 700; text-transform: uppercase;
|
|
69
|
+
letter-spacing: 0.08em; color: rgba(255,255,255,0.3);
|
|
70
|
+
}
|
|
71
|
+
.bpmnkit-side-dock__info-value {
|
|
72
|
+
font-size: 13px; color: rgba(255,255,255,0.75); word-break: break-word;
|
|
73
|
+
}
|
|
74
|
+
.bpmnkit-side-dock__empty-hint {
|
|
75
|
+
font-size: 12px; color: rgba(255,255,255,0.25);
|
|
76
|
+
text-align: center; padding: 20px 0;
|
|
77
|
+
}
|
|
78
|
+
/* Collapsed state — only the pill handle remains visible */
|
|
79
|
+
.bpmnkit-side-dock--collapsed .bpmnkit-side-dock__tab-strip,
|
|
80
|
+
.bpmnkit-side-dock--collapsed .bpmnkit-side-dock__pane { display: none; }
|
|
81
|
+
/* Push watermark left of the dock using a CSS variable updated by JS */
|
|
82
|
+
.bpmnkit-watermark { right: calc(var(--bpmnkit-dock-width, 0px) + 8px) !important; }
|
|
83
|
+
/* Light theme */
|
|
84
|
+
[data-bpmnkit-hud-theme="light"] .bpmnkit-side-dock {
|
|
85
|
+
background: rgba(248,248,252,0.99); border-left-color: rgba(0,0,0,0.08);
|
|
86
|
+
box-shadow: -8px 0 40px rgba(0,0,0,0.12);
|
|
87
|
+
}
|
|
88
|
+
[data-bpmnkit-hud-theme="light"] .bpmnkit-side-dock__collapse-handle {
|
|
89
|
+
background: rgba(248,248,252,0.99); border-color: rgba(0,0,0,0.08); color: rgba(0,0,0,0.4);
|
|
90
|
+
}
|
|
91
|
+
[data-bpmnkit-hud-theme="light"] .bpmnkit-side-dock__collapse-handle:hover {
|
|
92
|
+
background: rgba(235,235,242,0.99); color: rgba(0,0,0,0.9);
|
|
93
|
+
}
|
|
94
|
+
[data-bpmnkit-hud-theme="light"] .bpmnkit-side-dock__tab-strip { border-bottom-color: rgba(0,0,0,0.07); }
|
|
95
|
+
[data-bpmnkit-hud-theme="light"] .bpmnkit-side-dock__tab { color: rgba(0,0,0,0.4); }
|
|
96
|
+
[data-bpmnkit-hud-theme="light"] .bpmnkit-side-dock__tab:hover { color: rgba(0,0,0,0.7); }
|
|
97
|
+
[data-bpmnkit-hud-theme="light"] .bpmnkit-side-dock__tab.active { color: #1a56db; border-bottom-color: #1a56db; }
|
|
98
|
+
[data-bpmnkit-hud-theme="light"] .bpmnkit-side-dock__resize-handle:hover { background: rgba(26,86,219,0.2); }
|
|
99
|
+
[data-bpmnkit-hud-theme="light"] .bpmnkit-side-dock__info-label { color: rgba(0,0,0,0.3); }
|
|
100
|
+
[data-bpmnkit-hud-theme="light"] .bpmnkit-side-dock__info-value { color: rgba(0,0,0,0.75); }
|
|
101
|
+
[data-bpmnkit-hud-theme="light"] .bpmnkit-side-dock__info-row { border-bottom-color: rgba(0,0,0,0.06); }
|
|
102
|
+
[data-bpmnkit-hud-theme="light"] .bpmnkit-side-dock__empty-hint { color: rgba(0,0,0,0.25); }
|
|
103
|
+
`;
|
|
104
|
+
function injectDockStyles() {
|
|
105
|
+
if (document.getElementById(DOCK_STYLE_ID))
|
|
106
|
+
return;
|
|
107
|
+
const style = document.createElement("style");
|
|
108
|
+
style.id = DOCK_STYLE_ID;
|
|
109
|
+
style.textContent = DOCK_CSS;
|
|
110
|
+
document.head.appendChild(style);
|
|
111
|
+
}
|
|
112
|
+
export function createSideDock() {
|
|
113
|
+
injectDockStyles();
|
|
114
|
+
const el = document.createElement("div");
|
|
115
|
+
el.className = "bpmnkit-side-dock";
|
|
116
|
+
// Pill-shaped collapse handle on the left edge
|
|
117
|
+
const collapseHandle = document.createElement("div");
|
|
118
|
+
collapseHandle.className = "bpmnkit-side-dock__collapse-handle";
|
|
119
|
+
collapseHandle.setAttribute("role", "button");
|
|
120
|
+
collapseHandle.setAttribute("title", "Collapse panel");
|
|
121
|
+
collapseHandle.textContent = "›";
|
|
122
|
+
// Resize handle — 5px drag zone on the left edge
|
|
123
|
+
const resizeHandle = document.createElement("div");
|
|
124
|
+
resizeHandle.className = "bpmnkit-side-dock__resize-handle";
|
|
125
|
+
// Tab strip
|
|
126
|
+
const tabStrip = document.createElement("div");
|
|
127
|
+
tabStrip.className = "bpmnkit-side-dock__tab-strip";
|
|
128
|
+
const propertiesTab = document.createElement("button");
|
|
129
|
+
propertiesTab.className = "bpmnkit-side-dock__tab active";
|
|
130
|
+
propertiesTab.textContent = "Properties";
|
|
131
|
+
const historyTab = document.createElement("button");
|
|
132
|
+
historyTab.className = "bpmnkit-side-dock__tab";
|
|
133
|
+
historyTab.textContent = "History";
|
|
134
|
+
historyTab.disabled = true;
|
|
135
|
+
const aiTab = document.createElement("button");
|
|
136
|
+
aiTab.className = "bpmnkit-side-dock__tab";
|
|
137
|
+
aiTab.textContent = "AI";
|
|
138
|
+
const playTab = document.createElement("button");
|
|
139
|
+
playTab.className = "bpmnkit-side-dock__tab";
|
|
140
|
+
playTab.textContent = "Play";
|
|
141
|
+
playTab.style.display = "none";
|
|
142
|
+
const docsTab = document.createElement("button");
|
|
143
|
+
docsTab.className = "bpmnkit-side-dock__tab";
|
|
144
|
+
docsTab.textContent = "Docs";
|
|
145
|
+
tabStrip.appendChild(propertiesTab);
|
|
146
|
+
tabStrip.appendChild(historyTab);
|
|
147
|
+
tabStrip.appendChild(aiTab);
|
|
148
|
+
tabStrip.appendChild(playTab);
|
|
149
|
+
tabStrip.appendChild(docsTab);
|
|
150
|
+
// Properties pane — contains the info empty state
|
|
151
|
+
const propertiesPane = document.createElement("div");
|
|
152
|
+
propertiesPane.className = "bpmnkit-side-dock__pane";
|
|
153
|
+
const emptyEl = document.createElement("div");
|
|
154
|
+
emptyEl.className = "bpmnkit-side-dock__empty";
|
|
155
|
+
// Info rows (file name + process name)
|
|
156
|
+
const fileRow = document.createElement("div");
|
|
157
|
+
fileRow.className = "bpmnkit-side-dock__info-row";
|
|
158
|
+
const fileLabel = document.createElement("span");
|
|
159
|
+
fileLabel.className = "bpmnkit-side-dock__info-label";
|
|
160
|
+
fileLabel.textContent = "File";
|
|
161
|
+
const fileValue = document.createElement("span");
|
|
162
|
+
fileValue.className = "bpmnkit-side-dock__info-value";
|
|
163
|
+
fileValue.textContent = "\u2014";
|
|
164
|
+
fileRow.appendChild(fileLabel);
|
|
165
|
+
fileRow.appendChild(fileValue);
|
|
166
|
+
const processRow = document.createElement("div");
|
|
167
|
+
processRow.className = "bpmnkit-side-dock__info-row";
|
|
168
|
+
const processLabel = document.createElement("span");
|
|
169
|
+
processLabel.className = "bpmnkit-side-dock__info-label";
|
|
170
|
+
processLabel.textContent = "Process";
|
|
171
|
+
const processValue = document.createElement("span");
|
|
172
|
+
processValue.className = "bpmnkit-side-dock__info-value";
|
|
173
|
+
processValue.textContent = "\u2014";
|
|
174
|
+
processRow.appendChild(processLabel);
|
|
175
|
+
processRow.appendChild(processValue);
|
|
176
|
+
const hint = document.createElement("div");
|
|
177
|
+
hint.className = "bpmnkit-side-dock__empty-hint";
|
|
178
|
+
hint.textContent = "Select an element to edit its properties";
|
|
179
|
+
emptyEl.appendChild(fileRow);
|
|
180
|
+
emptyEl.appendChild(processRow);
|
|
181
|
+
emptyEl.appendChild(hint);
|
|
182
|
+
propertiesPane.appendChild(emptyEl);
|
|
183
|
+
// History pane
|
|
184
|
+
const historyPane = document.createElement("div");
|
|
185
|
+
historyPane.className = "bpmnkit-side-dock__pane bpmnkit-side-dock__pane--hidden";
|
|
186
|
+
// AI pane
|
|
187
|
+
const aiPane = document.createElement("div");
|
|
188
|
+
aiPane.className = "bpmnkit-side-dock__pane bpmnkit-side-dock__pane--hidden";
|
|
189
|
+
// Play pane
|
|
190
|
+
const playPane = document.createElement("div");
|
|
191
|
+
playPane.className = "bpmnkit-side-dock__pane bpmnkit-side-dock__pane--hidden";
|
|
192
|
+
// Docs pane
|
|
193
|
+
const docsPane = document.createElement("div");
|
|
194
|
+
docsPane.className = "bpmnkit-side-dock__pane bpmnkit-side-dock__pane--hidden";
|
|
195
|
+
el.appendChild(collapseHandle);
|
|
196
|
+
el.appendChild(resizeHandle);
|
|
197
|
+
el.appendChild(tabStrip);
|
|
198
|
+
el.appendChild(propertiesPane);
|
|
199
|
+
el.appendChild(historyPane);
|
|
200
|
+
el.appendChild(aiPane);
|
|
201
|
+
el.appendChild(playPane);
|
|
202
|
+
el.appendChild(docsPane);
|
|
203
|
+
// ── State ──
|
|
204
|
+
let _collapsed = false;
|
|
205
|
+
let _width = DEFAULT_WIDTH;
|
|
206
|
+
let _activeTab = "properties";
|
|
207
|
+
let _aiTabHandler = null;
|
|
208
|
+
let _historyTabHandler = null;
|
|
209
|
+
let _playTabHandler = null;
|
|
210
|
+
let _docsTabHandler = null;
|
|
211
|
+
function setDocWidth(w) {
|
|
212
|
+
el.style.width = `${w}px`;
|
|
213
|
+
document.body.style.setProperty("--bpmnkit-dock-width", `${w}px`);
|
|
214
|
+
}
|
|
215
|
+
// Restore from localStorage
|
|
216
|
+
try {
|
|
217
|
+
const savedWidth = Number(localStorage.getItem(STORAGE_KEY_WIDTH));
|
|
218
|
+
if (Number.isFinite(savedWidth) && savedWidth >= MIN_WIDTH && savedWidth <= MAX_WIDTH) {
|
|
219
|
+
_width = savedWidth;
|
|
220
|
+
}
|
|
221
|
+
_collapsed = localStorage.getItem(STORAGE_KEY_COLLAPSED) === "true";
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
// localStorage unavailable — use defaults
|
|
225
|
+
}
|
|
226
|
+
if (_collapsed) {
|
|
227
|
+
el.classList.add("bpmnkit-side-dock--collapsed");
|
|
228
|
+
setDocWidth(0);
|
|
229
|
+
collapseHandle.textContent = "‹";
|
|
230
|
+
collapseHandle.setAttribute("title", "Expand panel");
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
setDocWidth(_width);
|
|
234
|
+
}
|
|
235
|
+
// Start hidden — the bridge shows it when the first tab is activated.
|
|
236
|
+
el.style.display = "none";
|
|
237
|
+
document.body.style.setProperty("--bpmnkit-dock-width", "0px");
|
|
238
|
+
// ── Tab switching ──
|
|
239
|
+
function switchTab(tab) {
|
|
240
|
+
_activeTab = tab;
|
|
241
|
+
propertiesTab.classList.toggle("active", tab === "properties");
|
|
242
|
+
historyTab.classList.toggle("active", tab === "history");
|
|
243
|
+
aiTab.classList.toggle("active", tab === "ai");
|
|
244
|
+
playTab.classList.toggle("active", tab === "play");
|
|
245
|
+
docsTab.classList.toggle("active", tab === "docs");
|
|
246
|
+
propertiesPane.classList.toggle("bpmnkit-side-dock__pane--hidden", tab !== "properties");
|
|
247
|
+
historyPane.classList.toggle("bpmnkit-side-dock__pane--hidden", tab !== "history");
|
|
248
|
+
aiPane.classList.toggle("bpmnkit-side-dock__pane--hidden", tab !== "ai");
|
|
249
|
+
playPane.classList.toggle("bpmnkit-side-dock__pane--hidden", tab !== "play");
|
|
250
|
+
docsPane.classList.toggle("bpmnkit-side-dock__pane--hidden", tab !== "docs");
|
|
251
|
+
}
|
|
252
|
+
// ── Expand / collapse ──
|
|
253
|
+
function expand() {
|
|
254
|
+
_collapsed = false;
|
|
255
|
+
el.classList.remove("bpmnkit-side-dock--collapsed");
|
|
256
|
+
setDocWidth(_width);
|
|
257
|
+
collapseHandle.textContent = "›";
|
|
258
|
+
collapseHandle.setAttribute("title", "Collapse panel");
|
|
259
|
+
try {
|
|
260
|
+
localStorage.setItem(STORAGE_KEY_COLLAPSED, "false");
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
// ignore
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
function collapse() {
|
|
267
|
+
_collapsed = true;
|
|
268
|
+
el.classList.add("bpmnkit-side-dock--collapsed");
|
|
269
|
+
setDocWidth(0);
|
|
270
|
+
collapseHandle.textContent = "‹";
|
|
271
|
+
collapseHandle.setAttribute("title", "Expand panel");
|
|
272
|
+
try {
|
|
273
|
+
localStorage.setItem(STORAGE_KEY_COLLAPSED, "true");
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
// ignore
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
// ── Empty state / panel visibility ──
|
|
280
|
+
function showPanel() {
|
|
281
|
+
emptyEl.style.display = "none";
|
|
282
|
+
}
|
|
283
|
+
function hidePanel() {
|
|
284
|
+
emptyEl.style.display = "";
|
|
285
|
+
}
|
|
286
|
+
function setDiagramInfo(processName, fileName) {
|
|
287
|
+
fileValue.textContent = fileName ?? "\u2014";
|
|
288
|
+
processValue.textContent = processName ?? "\u2014";
|
|
289
|
+
}
|
|
290
|
+
function setAiTabClickHandler(fn) {
|
|
291
|
+
_aiTabHandler = fn;
|
|
292
|
+
}
|
|
293
|
+
function setHistoryTabClickHandler(fn) {
|
|
294
|
+
_historyTabHandler = fn;
|
|
295
|
+
}
|
|
296
|
+
function setHistoryTabEnabled(enabled) {
|
|
297
|
+
historyTab.disabled = !enabled;
|
|
298
|
+
// If history tab is active and gets disabled, fall back to properties
|
|
299
|
+
if (!enabled && historyTab.classList.contains("active")) {
|
|
300
|
+
switchTab("properties");
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
function setPlayTabVisible(visible) {
|
|
304
|
+
playTab.style.display = visible ? "" : "none";
|
|
305
|
+
// If play tab is hidden while active, fall back to properties
|
|
306
|
+
if (!visible && playTab.classList.contains("active")) {
|
|
307
|
+
switchTab("properties");
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
function setPlayTabClickHandler(fn) {
|
|
311
|
+
_playTabHandler = fn;
|
|
312
|
+
}
|
|
313
|
+
function setDocsTabClickHandler(fn) {
|
|
314
|
+
_docsTabHandler = fn;
|
|
315
|
+
}
|
|
316
|
+
function setVisible(visible) {
|
|
317
|
+
if (visible) {
|
|
318
|
+
el.style.display = "";
|
|
319
|
+
setDocWidth(_collapsed ? 0 : _width);
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
el.style.display = "none";
|
|
323
|
+
document.body.style.setProperty("--bpmnkit-dock-width", "0px");
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
// ── Event wiring ──
|
|
327
|
+
propertiesTab.addEventListener("click", () => switchTab("properties"));
|
|
328
|
+
historyTab.addEventListener("click", () => {
|
|
329
|
+
switchTab("history");
|
|
330
|
+
_historyTabHandler?.();
|
|
331
|
+
});
|
|
332
|
+
aiTab.addEventListener("click", () => {
|
|
333
|
+
switchTab("ai");
|
|
334
|
+
_aiTabHandler?.();
|
|
335
|
+
});
|
|
336
|
+
playTab.addEventListener("click", () => {
|
|
337
|
+
switchTab("play");
|
|
338
|
+
_playTabHandler?.();
|
|
339
|
+
});
|
|
340
|
+
docsTab.addEventListener("click", () => {
|
|
341
|
+
switchTab("docs");
|
|
342
|
+
_docsTabHandler?.();
|
|
343
|
+
});
|
|
344
|
+
collapseHandle.addEventListener("click", () => {
|
|
345
|
+
if (_collapsed)
|
|
346
|
+
expand();
|
|
347
|
+
else
|
|
348
|
+
collapse();
|
|
349
|
+
});
|
|
350
|
+
resizeHandle.addEventListener("mousedown", (e) => {
|
|
351
|
+
if (_collapsed)
|
|
352
|
+
return;
|
|
353
|
+
e.preventDefault();
|
|
354
|
+
// Disable CSS transition during drag for instant feedback
|
|
355
|
+
el.style.transition = "none";
|
|
356
|
+
const startX = e.clientX;
|
|
357
|
+
const startWidth = _width;
|
|
358
|
+
const onMove = (ev) => {
|
|
359
|
+
const dx = startX - ev.clientX;
|
|
360
|
+
_width = Math.max(MIN_WIDTH, Math.min(MAX_WIDTH, startWidth + dx));
|
|
361
|
+
setDocWidth(_width);
|
|
362
|
+
try {
|
|
363
|
+
localStorage.setItem(STORAGE_KEY_WIDTH, String(_width));
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
// ignore
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
const onUp = () => {
|
|
370
|
+
// Re-enable CSS transition after drag
|
|
371
|
+
el.style.transition = "";
|
|
372
|
+
document.removeEventListener("mousemove", onMove);
|
|
373
|
+
document.removeEventListener("mouseup", onUp);
|
|
374
|
+
};
|
|
375
|
+
document.addEventListener("mousemove", onMove);
|
|
376
|
+
document.addEventListener("mouseup", onUp);
|
|
377
|
+
});
|
|
378
|
+
return {
|
|
379
|
+
el,
|
|
380
|
+
propertiesPane,
|
|
381
|
+
historyPane,
|
|
382
|
+
aiPane,
|
|
383
|
+
playPane,
|
|
384
|
+
docsPane,
|
|
385
|
+
switchTab,
|
|
386
|
+
expand,
|
|
387
|
+
collapse,
|
|
388
|
+
showPanel,
|
|
389
|
+
hidePanel,
|
|
390
|
+
setDiagramInfo,
|
|
391
|
+
setVisible,
|
|
392
|
+
setAiTabClickHandler,
|
|
393
|
+
setHistoryTabClickHandler,
|
|
394
|
+
setHistoryTabEnabled,
|
|
395
|
+
setPlayTabVisible,
|
|
396
|
+
setPlayTabClickHandler,
|
|
397
|
+
setDocsTabClickHandler,
|
|
398
|
+
get collapsed() {
|
|
399
|
+
return _collapsed;
|
|
400
|
+
},
|
|
401
|
+
get activeTab() {
|
|
402
|
+
return _activeTab;
|
|
403
|
+
},
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
//# sourceMappingURL=dock.js.map
|
package/dist/editor.d.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import type { Theme } from "@bpmnkit/canvas";
|
|
2
|
+
import type { BpmnDefinitions, DiColor } from "@bpmnkit/core";
|
|
3
|
+
import type { CreateShapeType, EditorEvents, EditorOptions, LabelPosition, Tool } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* BpmnEditor — a full BPMN 2.0 diagram editor with create, move, resize,
|
|
6
|
+
* connect, delete, label-edit, undo/redo, and copy/paste.
|
|
7
|
+
*/
|
|
8
|
+
export declare class BpmnEditor {
|
|
9
|
+
private readonly _id;
|
|
10
|
+
private readonly _host;
|
|
11
|
+
private readonly _svg;
|
|
12
|
+
private readonly _viewportG;
|
|
13
|
+
private readonly _containersG;
|
|
14
|
+
private readonly _edgesG;
|
|
15
|
+
private readonly _shapesG;
|
|
16
|
+
private readonly _labelsG;
|
|
17
|
+
private readonly _overlayG;
|
|
18
|
+
private _gridPattern;
|
|
19
|
+
private _markerId;
|
|
20
|
+
private readonly _viewport;
|
|
21
|
+
private readonly _keyboard;
|
|
22
|
+
private readonly _overlay;
|
|
23
|
+
private readonly _commandStack;
|
|
24
|
+
private readonly _stateMachine;
|
|
25
|
+
private readonly _labelEditor;
|
|
26
|
+
private readonly _plugins;
|
|
27
|
+
private _shapes;
|
|
28
|
+
private _edges;
|
|
29
|
+
private _defs;
|
|
30
|
+
private _selectedIds;
|
|
31
|
+
private _theme;
|
|
32
|
+
private _fit;
|
|
33
|
+
private _clipboard;
|
|
34
|
+
private _snapDelta;
|
|
35
|
+
private _selectedEdgeId;
|
|
36
|
+
private _edgeDropTarget;
|
|
37
|
+
private _ghostSnapCenter;
|
|
38
|
+
private _createEdgeDropTarget;
|
|
39
|
+
private _readOnly;
|
|
40
|
+
private _isDragging;
|
|
41
|
+
private _boundaryHostId;
|
|
42
|
+
private _warningBanner;
|
|
43
|
+
private readonly _listeners;
|
|
44
|
+
private readonly _ro;
|
|
45
|
+
constructor(options: EditorOptions);
|
|
46
|
+
load(xml: string): void;
|
|
47
|
+
/**
|
|
48
|
+
* Apply auto-layout to the current diagram.
|
|
49
|
+
* Replaces all DI positions with freshly computed layout.
|
|
50
|
+
* The operation is undoable.
|
|
51
|
+
*/
|
|
52
|
+
autoLayout(): void;
|
|
53
|
+
loadDefinitions(defs: BpmnDefinitions): void;
|
|
54
|
+
exportXml(): string;
|
|
55
|
+
/**
|
|
56
|
+
* Enables or disables read-only mode. In read-only mode the viewport
|
|
57
|
+
* (pan + zoom) still works but all editing actions are blocked.
|
|
58
|
+
*/
|
|
59
|
+
setReadOnly(enabled: boolean): void;
|
|
60
|
+
setTool(tool: Tool): void;
|
|
61
|
+
setSelection(ids: string[]): void;
|
|
62
|
+
deleteSelected(): void;
|
|
63
|
+
undo(): void;
|
|
64
|
+
redo(): void;
|
|
65
|
+
canUndo(): boolean;
|
|
66
|
+
canRedo(): boolean;
|
|
67
|
+
getDefinitions(): BpmnDefinitions | null;
|
|
68
|
+
applyChange(fn: (defs: BpmnDefinitions) => BpmnDefinitions): void;
|
|
69
|
+
fitView(padding?: number): void;
|
|
70
|
+
/** The host element that receives the `data-theme` attribute. */
|
|
71
|
+
get container(): HTMLElement;
|
|
72
|
+
getTheme(): "light" | "dark";
|
|
73
|
+
setTheme(theme: Theme): void;
|
|
74
|
+
zoomIn(): void;
|
|
75
|
+
zoomOut(): void;
|
|
76
|
+
setZoom(scale: number): void;
|
|
77
|
+
selectAll(): void;
|
|
78
|
+
paste(): void;
|
|
79
|
+
/** Pans the viewport to center on the element with the given id (preserves zoom). */
|
|
80
|
+
scrollToElement(id: string): void;
|
|
81
|
+
on<K extends keyof EditorEvents>(event: K, handler: EditorEvents[K]): () => void;
|
|
82
|
+
destroy(): void;
|
|
83
|
+
private _getDuplicateIds;
|
|
84
|
+
private _setDuplicateIdWarning;
|
|
85
|
+
private _renderDefs;
|
|
86
|
+
private _executeCommand;
|
|
87
|
+
private _setSelection;
|
|
88
|
+
private _previewTranslate;
|
|
89
|
+
private _cancelTranslate;
|
|
90
|
+
private _commitTranslate;
|
|
91
|
+
private _previewSpace;
|
|
92
|
+
private _commitSpace;
|
|
93
|
+
private _cancelSpace;
|
|
94
|
+
private _doCreate;
|
|
95
|
+
private _doConnect;
|
|
96
|
+
private _doCopy;
|
|
97
|
+
private _doPaste;
|
|
98
|
+
private _startLabelEdit;
|
|
99
|
+
private _connectSourceBounds;
|
|
100
|
+
/** Returns screen-space bounds of a shape (for positioning overlays). */
|
|
101
|
+
getShapeBounds(id: string): {
|
|
102
|
+
x: number;
|
|
103
|
+
y: number;
|
|
104
|
+
width: number;
|
|
105
|
+
height: number;
|
|
106
|
+
} | null;
|
|
107
|
+
/** Returns the BPMN element type for a given id, or null if not found. */
|
|
108
|
+
getElementType(id: string): string | null;
|
|
109
|
+
/**
|
|
110
|
+
* Creates a new element of the given type connected to the source shape,
|
|
111
|
+
* using smart placement (right → bottom → top, avoids overlaps).
|
|
112
|
+
* Returns the new element's id.
|
|
113
|
+
*/
|
|
114
|
+
addConnectedElement(sourceId: string, type: CreateShapeType): string | null;
|
|
115
|
+
private _smartPlaceBounds;
|
|
116
|
+
private _overlapsAny;
|
|
117
|
+
/**
|
|
118
|
+
* Sets the external label position for an event or gateway shape.
|
|
119
|
+
*/
|
|
120
|
+
setLabelPosition(shapeId: string, position: LabelPosition): void;
|
|
121
|
+
/** Starts inline label editing for the element with the given id. */
|
|
122
|
+
editLabel(id: string): void;
|
|
123
|
+
/** Copies then pastes the current selection with a small offset. */
|
|
124
|
+
duplicate(): void;
|
|
125
|
+
/**
|
|
126
|
+
* Enters connection-drawing mode with the given shape as source.
|
|
127
|
+
* The user then moves the mouse and clicks a target shape to complete the connection.
|
|
128
|
+
*/
|
|
129
|
+
startConnectionFrom(sourceId: string): void;
|
|
130
|
+
/** Creates a text annotation linked to the given source shape via an association. */
|
|
131
|
+
createAnnotationFor(sourceId: string): void;
|
|
132
|
+
/** Updates the color of a shape in the diagram. Pass `{}` to clear colors. */
|
|
133
|
+
updateColor(id: string, color: DiColor): void;
|
|
134
|
+
private _setEdgeSelected;
|
|
135
|
+
/** Changes a flow element's type (e.g. exclusiveGateway → parallelGateway). */
|
|
136
|
+
changeElementType(id: string, newType: CreateShapeType): void;
|
|
137
|
+
private _findEdgeDropTarget;
|
|
138
|
+
private _setEdgeDropHighlight;
|
|
139
|
+
private _previewEndpointMove;
|
|
140
|
+
private _commitEndpointMove;
|
|
141
|
+
private _isResizable;
|
|
142
|
+
private _getResizableIds;
|
|
143
|
+
private _computeSnap;
|
|
144
|
+
private _computeAlignGuides;
|
|
145
|
+
private _computeSpacingSnap;
|
|
146
|
+
private _computeCreateSnap;
|
|
147
|
+
private _computeCreateGuides;
|
|
148
|
+
private _findCreateEdgeDrop;
|
|
149
|
+
private _setBoundaryHost;
|
|
150
|
+
private _setCreateEdgeDropHighlight;
|
|
151
|
+
private readonly _onPointerDown;
|
|
152
|
+
private readonly _onPointerMove;
|
|
153
|
+
private readonly _onPointerUp;
|
|
154
|
+
private readonly _onDblClick;
|
|
155
|
+
private readonly _onKeyDown;
|
|
156
|
+
private _hitTest;
|
|
157
|
+
/** Returns the nearest edge segment across all edges for the given diagram point. */
|
|
158
|
+
private _nearestEdgeSegment;
|
|
159
|
+
/** Snaps a diagram point to nearby shape/waypoint positions and returns guide lines. */
|
|
160
|
+
private _snapWaypoint;
|
|
161
|
+
private _applyTheme;
|
|
162
|
+
private _installPlugin;
|
|
163
|
+
private _emit;
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=editor.d.ts.map
|