@bpmnkit/editor 0.0.31 → 0.0.33
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 +2 -0
- package/dist/command-stack.d.ts +20 -5
- package/dist/command-stack.js +42 -15
- package/dist/css.d.ts +1 -1
- package/dist/css.js +40 -0
- package/dist/editor.d.ts +60 -0
- package/dist/editor.js +404 -55
- package/dist/hud.js +114 -41
- package/dist/i18n.d.ts +14 -0
- package/dist/i18n.js +11 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/modeling.d.ts +1 -0
- package/dist/modeling.js +143 -33
- package/dist/overlay.d.ts +1 -1
- package/dist/overlay.js +2 -2
- package/dist/rules.d.ts +19 -5
- package/dist/rules.js +101 -5
- package/dist/state-machine.d.ts +11 -1
- package/dist/state-machine.js +41 -9
- package/dist/types.d.ts +11 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -115,10 +115,12 @@ interface SideDock {
|
|
|
115
115
|
| [`@bpmnkit/plugins`](https://www.npmjs.com/package/@bpmnkit/plugins) | 22 composable canvas plugins |
|
|
116
116
|
| [`@bpmnkit/api`](https://www.npmjs.com/package/@bpmnkit/api) | Camunda 8 REST API TypeScript client |
|
|
117
117
|
| [`@bpmnkit/ascii`](https://www.npmjs.com/package/@bpmnkit/ascii) | Render BPMN diagrams as Unicode ASCII art |
|
|
118
|
+
| [`@bpmnkit/docspack`](https://www.npmjs.com/package/@bpmnkit/docspack) | BPMN Kit docs as an offline docspack package for AI agents |
|
|
118
119
|
| [`@bpmnkit/ui`](https://www.npmjs.com/package/@bpmnkit/ui) | Shared design tokens and UI components |
|
|
119
120
|
| [`@bpmnkit/profiles`](https://www.npmjs.com/package/@bpmnkit/profiles) | Shared auth, profile storage, and client factories for CLI & proxy |
|
|
120
121
|
| [`@bpmnkit/operate`](https://www.npmjs.com/package/@bpmnkit/operate) | Monitoring & operations frontend for Camunda clusters |
|
|
121
122
|
| [`@bpmnkit/connector-gen`](https://www.npmjs.com/package/@bpmnkit/connector-gen) | Generate connector templates from OpenAPI specs |
|
|
123
|
+
| [`@bpmnkit/connectors`](https://www.npmjs.com/package/@bpmnkit/connectors) | Camunda 8 OOTB connector catalog and deterministic template application |
|
|
122
124
|
| [`@bpmnkit/cli`](https://www.npmjs.com/package/@bpmnkit/cli) | Camunda 8 command-line interface (casen) |
|
|
123
125
|
| [`@bpmnkit/proxy`](https://www.npmjs.com/package/@bpmnkit/proxy) | Local AI bridge and Camunda API proxy server |
|
|
124
126
|
| [`@bpmnkit/patterns`](https://www.npmjs.com/package/@bpmnkit/patterns) | Domain process patterns for BPMNKit AIKit |
|
package/dist/command-stack.d.ts
CHANGED
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
import type { BpmnDefinitions } from "@bpmnkit/core";
|
|
2
2
|
/**
|
|
3
3
|
* Snapshot-based undo/redo history for the BPMN editor.
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
*
|
|
5
|
+
* Each entry stores a reference to an immutable `BpmnDefinitions`. Because
|
|
6
|
+
* `modeling.ts` operations return structurally-shared copies (only the touched
|
|
7
|
+
* elements are new objects), 100 single-element edits on a large model share
|
|
8
|
+
* almost all of their memory — the stack never deep-copies.
|
|
9
|
+
*
|
|
10
|
+
* Consecutive pushes carrying the same `key` are *coalesced*: the top entry is
|
|
11
|
+
* replaced in place rather than appended, so a burst (e.g. typing a label,
|
|
12
|
+
* dragging a colour slider) collapses to a single undo step.
|
|
6
13
|
*/
|
|
7
14
|
export declare class CommandStack {
|
|
8
|
-
private
|
|
15
|
+
private _entries;
|
|
9
16
|
private _cursor;
|
|
10
17
|
private readonly _maxSize;
|
|
11
|
-
/**
|
|
12
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Appends a new snapshot, clearing any redo states, and enforces maxSize.
|
|
20
|
+
* When `key` matches the current top entry's key (and no redo is pending),
|
|
21
|
+
* the top entry is replaced instead — coalescing a burst into one step.
|
|
22
|
+
*/
|
|
23
|
+
push(defs: BpmnDefinitions, label?: string, key?: string): void;
|
|
13
24
|
/** Returns the current snapshot, or null if the stack is empty. */
|
|
14
25
|
current(): BpmnDefinitions | null;
|
|
15
26
|
/** Moves the cursor back one step and returns that snapshot. */
|
|
@@ -18,6 +29,10 @@ export declare class CommandStack {
|
|
|
18
29
|
redo(): BpmnDefinitions | null;
|
|
19
30
|
canUndo(): boolean;
|
|
20
31
|
canRedo(): boolean;
|
|
32
|
+
/** Label of the change that `undo()` would revert, or null. */
|
|
33
|
+
undoLabel(): string | null;
|
|
34
|
+
/** Label of the change that `redo()` would re-apply, or null. */
|
|
35
|
+
redoLabel(): string | null;
|
|
21
36
|
clear(): void;
|
|
22
37
|
}
|
|
23
38
|
//# sourceMappingURL=command-stack.d.ts.map
|
package/dist/command-stack.js
CHANGED
|
@@ -1,47 +1,74 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Snapshot-based undo/redo history for the BPMN editor.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* Each entry stores a reference to an immutable `BpmnDefinitions`. Because
|
|
5
|
+
* `modeling.ts` operations return structurally-shared copies (only the touched
|
|
6
|
+
* elements are new objects), 100 single-element edits on a large model share
|
|
7
|
+
* almost all of their memory — the stack never deep-copies.
|
|
8
|
+
*
|
|
9
|
+
* Consecutive pushes carrying the same `key` are *coalesced*: the top entry is
|
|
10
|
+
* replaced in place rather than appended, so a burst (e.g. typing a label,
|
|
11
|
+
* dragging a colour slider) collapses to a single undo step.
|
|
5
12
|
*/
|
|
6
13
|
export class CommandStack {
|
|
7
|
-
|
|
14
|
+
_entries = [];
|
|
8
15
|
_cursor = -1;
|
|
9
16
|
_maxSize = 100;
|
|
10
|
-
/**
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Appends a new snapshot, clearing any redo states, and enforces maxSize.
|
|
19
|
+
* When `key` matches the current top entry's key (and no redo is pending),
|
|
20
|
+
* the top entry is replaced instead — coalescing a burst into one step.
|
|
21
|
+
*/
|
|
22
|
+
push(defs, label = "", key) {
|
|
23
|
+
const top = this._entries[this._cursor];
|
|
24
|
+
const atTop = this._cursor === this._entries.length - 1;
|
|
25
|
+
if (key !== undefined && atTop && top && top.key === key) {
|
|
26
|
+
// Coalesce: keep the same undo entry, update its resulting state.
|
|
27
|
+
top.defs = defs;
|
|
28
|
+
top.label = label || top.label;
|
|
29
|
+
return;
|
|
16
30
|
}
|
|
17
|
-
this.
|
|
31
|
+
this._entries.splice(this._cursor + 1);
|
|
32
|
+
this._entries.push({ defs, label, key });
|
|
33
|
+
if (this._entries.length > this._maxSize) {
|
|
34
|
+
this._entries.shift();
|
|
35
|
+
}
|
|
36
|
+
this._cursor = this._entries.length - 1;
|
|
18
37
|
}
|
|
19
38
|
/** Returns the current snapshot, or null if the stack is empty. */
|
|
20
39
|
current() {
|
|
21
|
-
return this.
|
|
40
|
+
return this._entries[this._cursor]?.defs ?? null;
|
|
22
41
|
}
|
|
23
42
|
/** Moves the cursor back one step and returns that snapshot. */
|
|
24
43
|
undo() {
|
|
25
44
|
if (!this.canUndo())
|
|
26
45
|
return null;
|
|
27
46
|
this._cursor--;
|
|
28
|
-
return this.
|
|
47
|
+
return this._entries[this._cursor]?.defs ?? null;
|
|
29
48
|
}
|
|
30
49
|
/** Moves the cursor forward one step and returns that snapshot. */
|
|
31
50
|
redo() {
|
|
32
51
|
if (!this.canRedo())
|
|
33
52
|
return null;
|
|
34
53
|
this._cursor++;
|
|
35
|
-
return this.
|
|
54
|
+
return this._entries[this._cursor]?.defs ?? null;
|
|
36
55
|
}
|
|
37
56
|
canUndo() {
|
|
38
57
|
return this._cursor > 0;
|
|
39
58
|
}
|
|
40
59
|
canRedo() {
|
|
41
|
-
return this._cursor < this.
|
|
60
|
+
return this._cursor < this._entries.length - 1;
|
|
61
|
+
}
|
|
62
|
+
/** Label of the change that `undo()` would revert, or null. */
|
|
63
|
+
undoLabel() {
|
|
64
|
+
return this.canUndo() ? (this._entries[this._cursor]?.label ?? "") : null;
|
|
65
|
+
}
|
|
66
|
+
/** Label of the change that `redo()` would re-apply, or null. */
|
|
67
|
+
redoLabel() {
|
|
68
|
+
return this.canRedo() ? (this._entries[this._cursor + 1]?.label ?? "") : null;
|
|
42
69
|
}
|
|
43
70
|
clear() {
|
|
44
|
-
this.
|
|
71
|
+
this._entries = [];
|
|
45
72
|
this._cursor = -1;
|
|
46
73
|
}
|
|
47
74
|
}
|
package/dist/css.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export declare const EDITOR_STYLE_ID = "bpmnkit-editor-styles-v1";
|
|
|
3
3
|
/** ID used to prevent duplicate HUD style injection. */
|
|
4
4
|
export declare const HUD_STYLE_ID = "bpmnkit-editor-hud-styles-v1";
|
|
5
5
|
/** CSS for editor-specific overlays injected once into `<head>`. */
|
|
6
|
-
export declare const EDITOR_CSS = "\n/* Selection outline */\n.bpmnkit-sel-indicator {\n fill: none;\n stroke: var(--bpmnkit-accent, #1a56db);\n stroke-width: 1.5;\n pointer-events: none;\n}\n\n/* Resize handle */\n.bpmnkit-resize-handle {\n fill: #fff;\n stroke: var(--bpmnkit-accent, #1a56db);\n stroke-width: 1.5;\n cursor: nwse-resize;\n}\n.bpmnkit-resize-handle[data-bpmnkit-handle=\"n\"],\n.bpmnkit-resize-handle[data-bpmnkit-handle=\"s\"] {\n cursor: ns-resize;\n}\n.bpmnkit-resize-handle[data-bpmnkit-handle=\"e\"],\n.bpmnkit-resize-handle[data-bpmnkit-handle=\"w\"] {\n cursor: ew-resize;\n}\n.bpmnkit-resize-handle[data-bpmnkit-handle=\"ne\"],\n.bpmnkit-resize-handle[data-bpmnkit-handle=\"sw\"] {\n cursor: nesw-resize;\n}\n.bpmnkit-resize-handle[data-bpmnkit-handle=\"nw\"],\n.bpmnkit-resize-handle[data-bpmnkit-handle=\"se\"] {\n cursor: nwse-resize;\n}\n\n/* Connection port */\n.bpmnkit-conn-port {\n fill: var(--bpmnkit-accent, #1a56db);\n stroke: none;\n cursor: crosshair;\n opacity: 0.7;\n}\n.bpmnkit-conn-port:hover {\n opacity: 1;\n}\n\n/* Rubber-band selection */\n.bpmnkit-rubber-band {\n fill: rgba(0, 102, 204, 0.05);\n stroke: var(--bpmnkit-accent, #1a56db);\n stroke-dasharray: 4 2;\n pointer-events: none;\n}\n\n/* Ghost element (create / connect preview) */\n.bpmnkit-ghost {\n opacity: 0.45;\n pointer-events: none;\n}\n\n/* Ghost connection line */\n.bpmnkit-ghost-conn {\n stroke: var(--bpmnkit-accent, #1a56db);\n stroke-width: 1.5;\n stroke-dasharray: 6 3;\n fill: none;\n pointer-events: none;\n}\n\n/* Resize preview rect */\n.bpmnkit-resize-preview {\n fill: rgba(0, 102, 204, 0.05);\n stroke: var(--bpmnkit-accent, #1a56db);\n stroke-dasharray: 4 2;\n pointer-events: none;\n}\n\n/* Alignment guide lines (snap helpers) */\n.bpmnkit-align-guide {\n stroke: var(--bpmnkit-accent-bright, #6b9df7);\n stroke-width: 1;\n stroke-dasharray: 4 2;\n pointer-events: none;\n}\n\n/* Edge transparent hit area (wide stroke for easier clicking) */\n.bpmnkit-edge-hitarea {\n fill: none;\n stroke: transparent;\n stroke-width: 12;\n cursor: pointer;\n}\n\n/* Edge hover dot (waypoint insertion indicator) */\n.bpmnkit-edge-hover-dot {\n fill: var(--bpmnkit-accent, #1a56db);\n stroke: #fff;\n stroke-width: 1.5;\n pointer-events: none;\n opacity: 0.85;\n}\n[data-theme=\"dark\"] .bpmnkit-edge-hover-dot { fill: var(--bpmnkit-accent, #6b9df7); }\n\n/* Edge waypoint angle balls (visible on edge hover) */\n.bpmnkit-edge-waypoint-ball {\n fill: var(--bpmnkit-accent, #1a56db);\n stroke: #fff;\n stroke-width: 1.5;\n cursor: move;\n}\n.bpmnkit-edge-waypoint-ball:hover { fill: var(--bpmnkit-accent, #1a56db); }\n[data-theme=\"dark\"] .bpmnkit-edge-waypoint-ball { fill: var(--bpmnkit-accent, #6b9df7); }\n\n/* Edge endpoint drag handles */\n.bpmnkit-edge-endpoint {\n fill: var(--bpmnkit-accent, #1a56db);\n stroke: #fff;\n stroke-width: 1.5;\n cursor: grab;\n}\n.bpmnkit-edge-endpoint:hover {\n fill: var(--bpmnkit-accent, #1a56db);\n}\n\n/* Ghost polyline when dragging an edge endpoint */\n.bpmnkit-endpoint-ghost {\n fill: none;\n stroke: var(--bpmnkit-accent, #1a56db);\n stroke-width: 1.5;\n stroke-dasharray: 5 3;\n pointer-events: none;\n}\n\n/* Edge split target highlight (shown while dragging a shape over an edge) */\n.bpmnkit-edge-split-highlight .bpmnkit-edge-path {\n stroke: var(--bpmnkit-success, #22c55e);\n stroke-width: 2.5;\n}\n\n/* Distance/spacing guide arrows */\n.bpmnkit-dist-guide {\n stroke: var(--bpmnkit-warn, #f97316);\n stroke-width: 1;\n fill: none;\n pointer-events: none;\n}\n\n/* Space tool split indicator line */\n.bpmnkit-space-line {\n stroke: var(--bpmnkit-warn, #f59e0b);\n stroke-width: 1.5;\n stroke-dasharray: 6 3;\n pointer-events: none;\n}\n\n/* Label editor */\n.bpmnkit-label-editor {\n position: absolute;\n min-width: 40px;\n min-height: 16px;\n padding: 1px 3px;\n background: #fff;\n border: 1px solid var(--bpmnkit-accent, #1a56db);\n border-radius: 2px;\n font-family: system-ui, -apple-system, sans-serif;\n font-size: 11px;\n text-align: center;\n outline: none;\n z-index: 10;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n/* Boundary event attach highlight */\n.bpmnkit-boundary-host {\n fill: none;\n stroke: var(--bpmnkit-accent, #1a56db);\n stroke-width: 2;\n stroke-dasharray: 6 3;\n pointer-events: none;\n opacity: 0.7;\n}\n\n/* Duplicate-ID warning banner */\n.bpmnkit-editor-warning-banner {\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 100;\n max-width: calc(100% - 32px);\n padding: 6px 12px;\n border-radius: 6px;\n background: #fef3c7;\n border: 1px solid #f59e0b;\n color: #92400e;\n font-size: 12px;\n line-height: 1.4;\n pointer-events: none;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.bpmnkit-canvas-host[data-theme=\"dark\"] .bpmnkit-editor-warning-banner {\n background: #451a03;\n border-color: #d97706;\n color: #fde68a;\n}\n";
|
|
6
|
+
export declare const EDITOR_CSS = "\n/* Visually-hidden live region for screen-reader announcements */\n.bpmnkit-sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n/* Keyboard-focus ring on the editor host \u2014 distinct from the selection outline */\n.bpmnkit-canvas-host:focus-visible {\n outline: 2px dashed var(--bpmnkit-accent-bright, #3b82f6);\n outline-offset: -2px;\n}\n\n/* Selection outline */\n.bpmnkit-sel-indicator {\n fill: none;\n stroke: var(--bpmnkit-accent, #1a56db);\n stroke-width: 1.5;\n pointer-events: none;\n}\n\n/* Resize handle */\n.bpmnkit-resize-handle {\n fill: #fff;\n stroke: var(--bpmnkit-accent, #1a56db);\n stroke-width: 1.5;\n cursor: nwse-resize;\n}\n.bpmnkit-resize-handle[data-bpmnkit-handle=\"n\"],\n.bpmnkit-resize-handle[data-bpmnkit-handle=\"s\"] {\n cursor: ns-resize;\n}\n.bpmnkit-resize-handle[data-bpmnkit-handle=\"e\"],\n.bpmnkit-resize-handle[data-bpmnkit-handle=\"w\"] {\n cursor: ew-resize;\n}\n.bpmnkit-resize-handle[data-bpmnkit-handle=\"ne\"],\n.bpmnkit-resize-handle[data-bpmnkit-handle=\"sw\"] {\n cursor: nesw-resize;\n}\n.bpmnkit-resize-handle[data-bpmnkit-handle=\"nw\"],\n.bpmnkit-resize-handle[data-bpmnkit-handle=\"se\"] {\n cursor: nwse-resize;\n}\n\n/* Connection port */\n.bpmnkit-conn-port {\n fill: var(--bpmnkit-accent, #1a56db);\n stroke: none;\n cursor: crosshair;\n opacity: 0.7;\n}\n.bpmnkit-conn-port:hover {\n opacity: 1;\n}\n\n/* Rubber-band selection */\n.bpmnkit-rubber-band {\n fill: rgba(0, 102, 204, 0.05);\n stroke: var(--bpmnkit-accent, #1a56db);\n stroke-dasharray: 4 2;\n pointer-events: none;\n}\n\n/* Ghost element (create / connect preview) */\n.bpmnkit-ghost {\n opacity: 0.45;\n pointer-events: none;\n}\n\n/* Ghost connection line */\n.bpmnkit-ghost-conn {\n stroke: var(--bpmnkit-accent, #1a56db);\n stroke-width: 1.5;\n stroke-dasharray: 6 3;\n fill: none;\n pointer-events: none;\n}\n\n/* Ghost connection over a target the rules forbid */\n.bpmnkit-ghost-conn-invalid {\n stroke: var(--bpmnkit-danger, #dc2626);\n}\n\n/* Resize preview rect */\n.bpmnkit-resize-preview {\n fill: rgba(0, 102, 204, 0.05);\n stroke: var(--bpmnkit-accent, #1a56db);\n stroke-dasharray: 4 2;\n pointer-events: none;\n}\n\n/* Alignment guide lines (snap helpers) */\n.bpmnkit-align-guide {\n stroke: var(--bpmnkit-accent-bright, #6b9df7);\n stroke-width: 1;\n stroke-dasharray: 4 2;\n pointer-events: none;\n}\n\n/* Edge transparent hit area (wide stroke for easier clicking) */\n.bpmnkit-edge-hitarea {\n fill: none;\n stroke: transparent;\n stroke-width: 12;\n cursor: pointer;\n}\n\n/* Edge hover dot (waypoint insertion indicator) */\n.bpmnkit-edge-hover-dot {\n fill: var(--bpmnkit-accent, #1a56db);\n stroke: #fff;\n stroke-width: 1.5;\n pointer-events: none;\n opacity: 0.85;\n}\n[data-theme=\"dark\"] .bpmnkit-edge-hover-dot { fill: var(--bpmnkit-accent, #6b9df7); }\n\n/* Edge waypoint angle balls (visible on edge hover) */\n.bpmnkit-edge-waypoint-ball {\n fill: var(--bpmnkit-accent, #1a56db);\n stroke: #fff;\n stroke-width: 1.5;\n cursor: move;\n}\n.bpmnkit-edge-waypoint-ball:hover { fill: var(--bpmnkit-accent, #1a56db); }\n[data-theme=\"dark\"] .bpmnkit-edge-waypoint-ball { fill: var(--bpmnkit-accent, #6b9df7); }\n\n/* Edge endpoint drag handles */\n.bpmnkit-edge-endpoint {\n fill: var(--bpmnkit-accent, #1a56db);\n stroke: #fff;\n stroke-width: 1.5;\n cursor: grab;\n}\n.bpmnkit-edge-endpoint:hover {\n fill: var(--bpmnkit-accent, #1a56db);\n}\n\n/* Ghost polyline when dragging an edge endpoint */\n.bpmnkit-endpoint-ghost {\n fill: none;\n stroke: var(--bpmnkit-accent, #1a56db);\n stroke-width: 1.5;\n stroke-dasharray: 5 3;\n pointer-events: none;\n}\n\n/* Edge split target highlight (shown while dragging a shape over an edge) */\n.bpmnkit-edge-split-highlight .bpmnkit-edge-path {\n stroke: var(--bpmnkit-success, #22c55e);\n stroke-width: 2.5;\n}\n\n/* Distance/spacing guide arrows */\n.bpmnkit-dist-guide {\n stroke: var(--bpmnkit-warn, #f97316);\n stroke-width: 1;\n fill: none;\n pointer-events: none;\n}\n\n/* Space tool split indicator line */\n.bpmnkit-space-line {\n stroke: var(--bpmnkit-warn, #f59e0b);\n stroke-width: 1.5;\n stroke-dasharray: 6 3;\n pointer-events: none;\n}\n\n/* Label editor */\n.bpmnkit-label-editor {\n position: absolute;\n min-width: 40px;\n min-height: 16px;\n padding: 1px 3px;\n background: #fff;\n border: 1px solid var(--bpmnkit-accent, #1a56db);\n border-radius: 2px;\n font-family: system-ui, -apple-system, sans-serif;\n font-size: 11px;\n text-align: center;\n outline: none;\n z-index: 10;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n/* Boundary event attach highlight */\n.bpmnkit-boundary-host {\n fill: none;\n stroke: var(--bpmnkit-accent, #1a56db);\n stroke-width: 2;\n stroke-dasharray: 6 3;\n pointer-events: none;\n opacity: 0.7;\n}\n\n/* Duplicate-ID warning banner */\n.bpmnkit-editor-warning-banner {\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 100;\n max-width: calc(100% - 32px);\n padding: 6px 12px;\n border-radius: 6px;\n background: #fef3c7;\n border: 1px solid #f59e0b;\n color: #92400e;\n font-size: 12px;\n line-height: 1.4;\n pointer-events: none;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.bpmnkit-canvas-host[data-theme=\"dark\"] .bpmnkit-editor-warning-banner {\n background: #451a03;\n border-color: #d97706;\n color: #fde68a;\n}\n\n/* Coarse pointers (touch): enlarge drag targets to a finger-friendly \u226524px.\n Resize handles are 7px rects centred on the corner; grow + recentre them.\n Endpoint / waypoint / port circles grow via the SVG geometry 'r' property. */\n@media (pointer: coarse) {\n .bpmnkit-resize-handle {\n width: 24px;\n height: 24px;\n transform: translate(-8.5px, -8.5px);\n }\n .bpmnkit-edge-endpoint,\n .bpmnkit-edge-waypoint-ball,\n .bpmnkit-conn-port {\n r: 12px;\n }\n}\n";
|
|
7
7
|
/** Injects the editor stylesheet into `<head>` if not already present. */
|
|
8
8
|
export declare function injectEditorStyles(): void;
|
|
9
9
|
/** CSS for the editor HUD — panels, buttons, dropdowns, group picker.
|
package/dist/css.js
CHANGED
|
@@ -4,6 +4,25 @@ export const EDITOR_STYLE_ID = "bpmnkit-editor-styles-v1";
|
|
|
4
4
|
export const HUD_STYLE_ID = "bpmnkit-editor-hud-styles-v1";
|
|
5
5
|
/** CSS for editor-specific overlays injected once into `<head>`. */
|
|
6
6
|
export const EDITOR_CSS = `
|
|
7
|
+
/* Visually-hidden live region for screen-reader announcements */
|
|
8
|
+
.bpmnkit-sr-only {
|
|
9
|
+
position: absolute;
|
|
10
|
+
width: 1px;
|
|
11
|
+
height: 1px;
|
|
12
|
+
padding: 0;
|
|
13
|
+
margin: -1px;
|
|
14
|
+
overflow: hidden;
|
|
15
|
+
clip: rect(0, 0, 0, 0);
|
|
16
|
+
white-space: nowrap;
|
|
17
|
+
border: 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* Keyboard-focus ring on the editor host — distinct from the selection outline */
|
|
21
|
+
.bpmnkit-canvas-host:focus-visible {
|
|
22
|
+
outline: 2px dashed var(--bpmnkit-accent-bright, #3b82f6);
|
|
23
|
+
outline-offset: -2px;
|
|
24
|
+
}
|
|
25
|
+
|
|
7
26
|
/* Selection outline */
|
|
8
27
|
.bpmnkit-sel-indicator {
|
|
9
28
|
fill: none;
|
|
@@ -70,6 +89,11 @@ export const EDITOR_CSS = `
|
|
|
70
89
|
pointer-events: none;
|
|
71
90
|
}
|
|
72
91
|
|
|
92
|
+
/* Ghost connection over a target the rules forbid */
|
|
93
|
+
.bpmnkit-ghost-conn-invalid {
|
|
94
|
+
stroke: var(--bpmnkit-danger, #dc2626);
|
|
95
|
+
}
|
|
96
|
+
|
|
73
97
|
/* Resize preview rect */
|
|
74
98
|
.bpmnkit-resize-preview {
|
|
75
99
|
fill: rgba(0, 102, 204, 0.05);
|
|
@@ -209,6 +233,22 @@ export const EDITOR_CSS = `
|
|
|
209
233
|
border-color: #d97706;
|
|
210
234
|
color: #fde68a;
|
|
211
235
|
}
|
|
236
|
+
|
|
237
|
+
/* Coarse pointers (touch): enlarge drag targets to a finger-friendly ≥24px.
|
|
238
|
+
Resize handles are 7px rects centred on the corner; grow + recentre them.
|
|
239
|
+
Endpoint / waypoint / port circles grow via the SVG geometry 'r' property. */
|
|
240
|
+
@media (pointer: coarse) {
|
|
241
|
+
.bpmnkit-resize-handle {
|
|
242
|
+
width: 24px;
|
|
243
|
+
height: 24px;
|
|
244
|
+
transform: translate(-8.5px, -8.5px);
|
|
245
|
+
}
|
|
246
|
+
.bpmnkit-edge-endpoint,
|
|
247
|
+
.bpmnkit-edge-waypoint-ball,
|
|
248
|
+
.bpmnkit-conn-port {
|
|
249
|
+
r: 12px;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
212
252
|
`;
|
|
213
253
|
/** Injects the editor stylesheet into `<head>` if not already present. */
|
|
214
254
|
export function injectEditorStyles() {
|
package/dist/editor.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { OverlayManager } from "@bpmnkit/canvas";
|
|
1
2
|
import type { Theme } from "@bpmnkit/canvas";
|
|
2
3
|
import type { BpmnDefinitions, DiColor } from "@bpmnkit/core";
|
|
4
|
+
import type { Translate } from "./i18n.js";
|
|
3
5
|
import type { CreateShapeType, EditorEvents, EditorOptions, LabelPosition, Tool } from "./types.js";
|
|
4
6
|
/**
|
|
5
7
|
* BpmnEditor — a full BPMN 2.0 diagram editor with create, move, resize,
|
|
@@ -20,6 +22,7 @@ export declare class BpmnEditor {
|
|
|
20
22
|
private readonly _viewport;
|
|
21
23
|
private readonly _keyboard;
|
|
22
24
|
private readonly _overlay;
|
|
25
|
+
private readonly _htmlOverlays;
|
|
23
26
|
private readonly _commandStack;
|
|
24
27
|
private readonly _stateMachine;
|
|
25
28
|
private readonly _labelEditor;
|
|
@@ -39,6 +42,9 @@ export declare class BpmnEditor {
|
|
|
39
42
|
private _readOnly;
|
|
40
43
|
private _isDragging;
|
|
41
44
|
private _boundaryHostId;
|
|
45
|
+
private readonly _t;
|
|
46
|
+
private readonly _liveRegion;
|
|
47
|
+
private _lastTap;
|
|
42
48
|
private _warningBanner;
|
|
43
49
|
private readonly _listeners;
|
|
44
50
|
private readonly _ro;
|
|
@@ -60,6 +66,30 @@ export declare class BpmnEditor {
|
|
|
60
66
|
setTool(tool: Tool): void;
|
|
61
67
|
setSelection(ids: string[]): void;
|
|
62
68
|
deleteSelected(): void;
|
|
69
|
+
/** Bounds of the currently-selected shapes (edges have none, and are skipped). */
|
|
70
|
+
private _selectedShapeBounds;
|
|
71
|
+
/**
|
|
72
|
+
* Aligns the selected shapes along an edge or centre-line, as a single
|
|
73
|
+
* undoable command. No-op for fewer than two selected shapes.
|
|
74
|
+
*/
|
|
75
|
+
alignSelected(edge: "left" | "center" | "right" | "top" | "middle" | "bottom"): void;
|
|
76
|
+
/**
|
|
77
|
+
* Distributes the selected shapes so the gaps between them are equal along
|
|
78
|
+
* the axis (the outermost two stay fixed), as a single undoable command.
|
|
79
|
+
* No-op for fewer than three selected shapes.
|
|
80
|
+
*/
|
|
81
|
+
distributeSelected(axis: "horizontal" | "vertical"): void;
|
|
82
|
+
/**
|
|
83
|
+
* Searches the model (recursively, including sub-process children) for
|
|
84
|
+
* elements matching `query`, ranked: a word-prefix match on the name beats a
|
|
85
|
+
* name substring, which beats an id or type match. Returns `[]` for a blank
|
|
86
|
+
* query.
|
|
87
|
+
*/
|
|
88
|
+
find(query: string): Array<{
|
|
89
|
+
id: string;
|
|
90
|
+
label: string;
|
|
91
|
+
type: string;
|
|
92
|
+
}>;
|
|
63
93
|
undo(): void;
|
|
64
94
|
redo(): void;
|
|
65
95
|
canUndo(): boolean;
|
|
@@ -71,11 +101,20 @@ export declare class BpmnEditor {
|
|
|
71
101
|
get container(): HTMLElement;
|
|
72
102
|
getTheme(): "light" | "dark" | "neon";
|
|
73
103
|
setTheme(theme: Theme): void;
|
|
104
|
+
/** HTML overlays anchored to diagram elements (badges, tooltips, panels). */
|
|
105
|
+
get overlays(): OverlayManager;
|
|
106
|
+
/**
|
|
107
|
+
* The resolved translation hook (from `options.translate`, or identity).
|
|
108
|
+
* Used by the HUD to localize its strings; also available to plugins.
|
|
109
|
+
*/
|
|
110
|
+
get translate(): Translate;
|
|
74
111
|
zoomIn(): void;
|
|
75
112
|
zoomOut(): void;
|
|
76
113
|
setZoom(scale: number): void;
|
|
77
114
|
selectAll(): void;
|
|
78
115
|
paste(): void;
|
|
116
|
+
/** Copies the current selection to the clipboard and deletes it as one undo step. */
|
|
117
|
+
cut(): void;
|
|
79
118
|
/** Pans the viewport to center on the element with the given id (preserves zoom). */
|
|
80
119
|
scrollToElement(id: string): void;
|
|
81
120
|
on<K extends keyof EditorEvents>(event: K, handler: EditorEvents[K]): () => void;
|
|
@@ -84,7 +123,16 @@ export declare class BpmnEditor {
|
|
|
84
123
|
private _setDuplicateIdWarning;
|
|
85
124
|
private _renderDefs;
|
|
86
125
|
private _executeCommand;
|
|
126
|
+
/** Label of the change `undo()` would revert (for HUD tooltips), or null. */
|
|
127
|
+
getUndoLabel(): string | null;
|
|
128
|
+
/** Label of the change `redo()` would re-apply (for HUD tooltips), or null. */
|
|
129
|
+
getRedoLabel(): string | null;
|
|
87
130
|
private _setSelection;
|
|
131
|
+
/** Human-readable name for an element (its label, else its type). */
|
|
132
|
+
private _displayName;
|
|
133
|
+
/** Pushes `message` to the aria-live region for assistive technology. */
|
|
134
|
+
private _announce;
|
|
135
|
+
private _announceSelection;
|
|
88
136
|
private _previewTranslate;
|
|
89
137
|
private _cancelTranslate;
|
|
90
138
|
private _commitTranslate;
|
|
@@ -95,8 +143,12 @@ export declare class BpmnEditor {
|
|
|
95
143
|
private _doConnect;
|
|
96
144
|
private _doCopy;
|
|
97
145
|
private _doPaste;
|
|
146
|
+
private _doCut;
|
|
98
147
|
private _startLabelEdit;
|
|
99
148
|
private _connectSourceBounds;
|
|
149
|
+
private _connectSourceId;
|
|
150
|
+
/** True when hovering a target the connect tool would reject (self, or a rule violation). */
|
|
151
|
+
private _isConnectTargetInvalid;
|
|
100
152
|
/** Returns screen-space bounds of a shape (for positioning overlays). */
|
|
101
153
|
getShapeBounds(id: string): {
|
|
102
154
|
x: number;
|
|
@@ -151,6 +203,8 @@ export declare class BpmnEditor {
|
|
|
151
203
|
private readonly _onPointerDown;
|
|
152
204
|
private readonly _onPointerMove;
|
|
153
205
|
private readonly _onPointerUp;
|
|
206
|
+
/** On coarse pointers, a double-tap on a shape starts label editing (mirrors dblclick). */
|
|
207
|
+
private _detectDoubleTap;
|
|
154
208
|
private readonly _onPointerCancel;
|
|
155
209
|
private readonly _onDblClick;
|
|
156
210
|
private readonly _onKeyDown;
|
|
@@ -160,6 +214,12 @@ export declare class BpmnEditor {
|
|
|
160
214
|
/** Snaps a diagram point to nearby shape/waypoint positions and returns guide lines. */
|
|
161
215
|
private _snapWaypoint;
|
|
162
216
|
private _applyTheme;
|
|
217
|
+
/** Finds the SVG group for a shape or edge by BPMN id. */
|
|
218
|
+
private _elementById;
|
|
219
|
+
/** Element bounding box in screen pixels relative to the host, or `null`. */
|
|
220
|
+
private _absoluteBBox;
|
|
221
|
+
/** Diagram-coordinate bounds of a shape (from DI) or edge (waypoint bbox). */
|
|
222
|
+
private _boundsById;
|
|
163
223
|
private _installPlugin;
|
|
164
224
|
private _emit;
|
|
165
225
|
}
|