@formicoidea/labre-framework-bpmn 0.23.1 → 0.23.2

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 (41) hide show
  1. package/package.json +6 -15
  2. package/{dist/consts.js → src/consts.ts} +57 -48
  3. package/{dist/descriptor.js → src/descriptor.ts} +1 -1
  4. package/src/effects.ts +14 -0
  5. package/src/element-renderer.ts +93 -0
  6. package/src/element-view.ts +116 -0
  7. package/src/index.ts +1 -0
  8. package/src/node/node-renderer.ts +65 -0
  9. package/src/node/node-view.ts +34 -0
  10. package/src/templates/index.ts +156 -0
  11. package/src/toolbar/bpmn-menu.ts +224 -0
  12. package/{dist/toolbar/bpmn-senior-button.js → src/toolbar/bpmn-senior-button.ts} +102 -97
  13. package/src/toolbar/config.ts +74 -0
  14. package/{dist/toolbar/icons.js → src/toolbar/icons.ts} +43 -37
  15. package/{dist/toolbar/senior-tool.js → src/toolbar/senior-tool.ts} +11 -11
  16. package/src/view.ts +37 -0
  17. package/dist/consts.d.ts +0 -42
  18. package/dist/descriptor.d.ts +0 -7
  19. package/dist/effects.d.ts +0 -10
  20. package/dist/effects.js +0 -7
  21. package/dist/element-renderer.d.ts +0 -13
  22. package/dist/element-renderer.js +0 -58
  23. package/dist/element-view.d.ts +0 -22
  24. package/dist/element-view.js +0 -103
  25. package/dist/index.d.ts +0 -2
  26. package/dist/index.js +0 -2
  27. package/dist/node/node-renderer.d.ts +0 -16
  28. package/dist/node/node-renderer.js +0 -43
  29. package/dist/node/node-view.d.ts +0 -17
  30. package/dist/node/node-view.js +0 -28
  31. package/dist/templates/index.d.ts +0 -3
  32. package/dist/templates/index.js +0 -114
  33. package/dist/toolbar/bpmn-menu.d.ts +0 -27
  34. package/dist/toolbar/bpmn-menu.js +0 -179
  35. package/dist/toolbar/bpmn-senior-button.d.ts +0 -16
  36. package/dist/toolbar/config.d.ts +0 -14
  37. package/dist/toolbar/config.js +0 -55
  38. package/dist/toolbar/icons.d.ts +0 -16
  39. package/dist/toolbar/senior-tool.d.ts +0 -2
  40. package/dist/view.d.ts +0 -7
  41. package/dist/view.js +0 -34
@@ -0,0 +1,224 @@
1
+ import { DefaultTool } from '@formicoidea/labre-core/blocks/surface';
2
+ import { ConnectorTool } from '@formicoidea/labre-core/gfx/connector';
3
+ import { EmptyTool } from '@formicoidea/labre-core/gfx/pointer';
4
+ import {
5
+ ConnectorMode,
6
+ FontFamily,
7
+ PointStyle,
8
+ ShapeStyle,
9
+ StrokeStyle,
10
+ } from '@formicoidea/labre-core/model';
11
+ import {
12
+ EditPropsStore,
13
+ TelemetryProvider,
14
+ } from '@formicoidea/labre-core/shared/services';
15
+ import { EdgelessToolbarToolMixin } from '@formicoidea/labre-core/widgets/edgeless-toolbar';
16
+ import { Bound } from '@formicoidea/labre-core/global/gfx';
17
+ import { css, html, LitElement } from 'lit';
18
+
19
+ import {
20
+ EVENT_END,
21
+ EVENT_START,
22
+ END_WIDTH,
23
+ INNER_FONT_SIZE,
24
+ NEUTRAL_STROKE,
25
+ NODE_FILL,
26
+ NODE_LABEL,
27
+ NODE_SIZE,
28
+ NODE_STROKE_WIDTH,
29
+ SEQUENCE_STROKE,
30
+ SEQUENCE_WIDTH,
31
+ START_WIDTH,
32
+ TASK_RADIUS,
33
+ } from '../consts';
34
+ import {
35
+ bpmnEndIcon,
36
+ bpmnGatewayIcon,
37
+ bpmnPoolIcon,
38
+ bpmnSequenceIcon,
39
+ bpmnStartIcon,
40
+ bpmnTaskIcon,
41
+ } from './icons';
42
+
43
+ type NodeKind = 'startEvent' | 'endEvent' | 'task' | 'gatewayExclusive';
44
+
45
+ /** Per-kind native shape + accent presets (style C). */
46
+ const NODE_PRESETS: Record<
47
+ NodeKind,
48
+ { shapeType: 'ellipse' | 'rect' | 'diamond'; stroke: string; width: number }
49
+ > = {
50
+ startEvent: { shapeType: 'ellipse', stroke: EVENT_START, width: START_WIDTH },
51
+ endEvent: { shapeType: 'ellipse', stroke: EVENT_END, width: END_WIDTH },
52
+ task: { shapeType: 'rect', stroke: NEUTRAL_STROKE, width: NODE_STROKE_WIDTH },
53
+ gatewayExclusive: {
54
+ shapeType: 'diamond',
55
+ stroke: NEUTRAL_STROKE,
56
+ width: NODE_STROKE_WIDTH,
57
+ },
58
+ };
59
+
60
+ /**
61
+ * The popover above the toolbar for the BPMN toolbox. Items create the flow
62
+ * objects (native shapes, so they stay editable), the pool background, and arm
63
+ * the native connector tool for sequence flows. Mirrors the EDGY menu.
64
+ */
65
+ export class EdgelessBpmnMenu extends EdgelessToolbarToolMixin(LitElement) {
66
+ static override styles = css`
67
+ :host {
68
+ position: absolute;
69
+ display: flex;
70
+ z-index: -1;
71
+ }
72
+ .menu-content {
73
+ display: flex;
74
+ align-items: center;
75
+ justify-content: center;
76
+ }
77
+ .button-group-container {
78
+ display: flex;
79
+ align-items: center;
80
+ gap: 14px;
81
+ fill: var(--affine-icon-color);
82
+ }
83
+ .button-group-container svg {
84
+ width: 24px;
85
+ height: 24px;
86
+ }
87
+ `;
88
+
89
+ override type = EmptyTool;
90
+
91
+ /** Create a flow-object node (native shape) centred on the viewport. */
92
+ private _createNode(kind: NodeKind) {
93
+ const surface = this.gfx.surface;
94
+ if (!surface) return;
95
+
96
+ const { w, h } = NODE_SIZE[kind];
97
+ const { centerX: cx, centerY: cy } = this.gfx.viewport;
98
+ const preset = NODE_PRESETS[kind];
99
+
100
+ const id = surface.addElement({
101
+ type: 'bpmnNode',
102
+ kind,
103
+ shapeType: preset.shapeType,
104
+ filled: true,
105
+ fillColor: NODE_FILL,
106
+ strokeColor: preset.stroke,
107
+ strokeWidth: preset.width,
108
+ shapeStyle: ShapeStyle.General,
109
+ roughness: 0,
110
+ radius: kind === 'task' ? TASK_RADIUS : 0,
111
+ text: NODE_LABEL[kind] || undefined,
112
+ color: NEUTRAL_STROKE,
113
+ fontFamily: FontFamily.Inter,
114
+ fontSize: INNER_FONT_SIZE,
115
+ textAlign: 'center',
116
+ xywh: new Bound(cx - w / 2, cy - h / 2, w, h).serialize(),
117
+ });
118
+ this._track('FrameworkElementAdded', `node:${kind}`);
119
+ this._finish(id);
120
+ }
121
+
122
+ /** Create a pool (background container) centred on the viewport. */
123
+ private _createPool() {
124
+ const surface = this.gfx.surface;
125
+ if (!surface) return;
126
+
127
+ const w = 560;
128
+ const h = 200;
129
+ const { centerX: cx, centerY: cy } = this.gfx.viewport;
130
+ const id = surface.addElement({
131
+ type: 'bpmnPool',
132
+ xywh: new Bound(cx - w / 2, cy - h / 2, w, h).serialize(),
133
+ });
134
+ this._track('FrameworkElementAdded', 'pool');
135
+ this._finish(id);
136
+ }
137
+
138
+ /**
139
+ * Arm the native connector tool, pre-styled for a BPMN sequence flow:
140
+ * orthogonal, solid, with a filled triangle head. The user then draws from
141
+ * one node to another (endpoints attach to centers).
142
+ */
143
+ private _activateSequenceFlow() {
144
+ this.edgeless.std.get(EditPropsStore).recordLastProps('connector', {
145
+ mode: ConnectorMode.Orthogonal,
146
+ stroke: SEQUENCE_STROKE,
147
+ strokeStyle: StrokeStyle.Solid,
148
+ strokeWidth: SEQUENCE_WIDTH,
149
+ frontEndpointStyle: PointStyle.None,
150
+ rearEndpointStyle: PointStyle.Triangle,
151
+ });
152
+ this._track('FrameworkToolPicked', 'connector:sequence');
153
+ this.gfx.tool.setTool(ConnectorTool, { mode: ConnectorMode.Orthogonal });
154
+ // Keep the palette open (native sub-menu behaviour).
155
+ }
156
+
157
+ private _finish(id: string) {
158
+ const { gfx } = this;
159
+ gfx.doc.captureSync();
160
+ gfx.tool.setTool(DefaultTool);
161
+ gfx.selection.set({ elements: [id], editing: false });
162
+ // Keep the palette open (native sub-menu behaviour).
163
+ }
164
+
165
+ private _track(
166
+ event: 'FrameworkElementAdded' | 'FrameworkToolPicked',
167
+ element: string
168
+ ) {
169
+ this.edgeless.std.getOptional(TelemetryProvider)?.track(event, {
170
+ framework: 'bpmn',
171
+ element,
172
+ page: 'whiteboard editor',
173
+ segment: 'bpmn toolbox',
174
+ module: 'bpmn menu',
175
+ });
176
+ }
177
+
178
+ override render() {
179
+ return html`
180
+ <edgeless-slide-menu>
181
+ <div class="menu-content">
182
+ <div class="button-group-container">
183
+ <edgeless-tool-icon-button
184
+ .tooltip=${'Start event'}
185
+ @click=${() => this._createNode('startEvent')}
186
+ >
187
+ ${bpmnStartIcon}
188
+ </edgeless-tool-icon-button>
189
+ <edgeless-tool-icon-button
190
+ .tooltip=${'End event'}
191
+ @click=${() => this._createNode('endEvent')}
192
+ >
193
+ ${bpmnEndIcon}
194
+ </edgeless-tool-icon-button>
195
+ <edgeless-tool-icon-button
196
+ .tooltip=${'Task'}
197
+ @click=${() => this._createNode('task')}
198
+ >
199
+ ${bpmnTaskIcon}
200
+ </edgeless-tool-icon-button>
201
+ <edgeless-tool-icon-button
202
+ .tooltip=${'Exclusive gateway'}
203
+ @click=${() => this._createNode('gatewayExclusive')}
204
+ >
205
+ ${bpmnGatewayIcon}
206
+ </edgeless-tool-icon-button>
207
+ <edgeless-tool-icon-button
208
+ .tooltip=${'Sequence flow'}
209
+ @click=${this._activateSequenceFlow}
210
+ >
211
+ ${bpmnSequenceIcon}
212
+ </edgeless-tool-icon-button>
213
+ <edgeless-tool-icon-button
214
+ .tooltip=${'Pool'}
215
+ @click=${this._createPool}
216
+ >
217
+ ${bpmnPoolIcon}
218
+ </edgeless-tool-icon-button>
219
+ </div>
220
+ </div>
221
+ </edgeless-slide-menu>
222
+ `;
223
+ }
224
+ }
@@ -1,97 +1,102 @@
1
- import { DefaultTool } from '@formicoidea/labre-core/blocks/surface';
2
- import { EmptyTool } from '@formicoidea/labre-core/gfx/pointer';
3
- import { EdgelessToolbarToolMixin } from '@formicoidea/labre-core/widgets/edgeless-toolbar';
4
- import { SignalWatcher } from '@formicoidea/labre-core/global/lit';
5
- import { css, html, LitElement } from 'lit';
6
- import { bpmnToolbarIcon } from './icons';
7
- /**
8
- * Main toolbar button (colored BPMN glyph) that opens the BPMN toolbox sub-menu
9
- * above the toolbar. Mirrors the EDGY / Wardley senior buttons.
10
- */
11
- export class EdgelessBpmnSeniorButton extends EdgelessToolbarToolMixin(SignalWatcher(LitElement)) {
12
- constructor() {
13
- super(...arguments);
14
- this.enableActiveBackground = true;
15
- this.type = EmptyTool;
16
- }
17
- static { this.styles = css `
18
- :host,
19
- .bpmn-button {
20
- display: block;
21
- width: 100%;
22
- height: 100%;
23
- }
24
- :host {
25
- position: relative;
26
- }
27
- .bpmn-root {
28
- width: 100%;
29
- height: 64px;
30
- position: relative;
31
- overflow: hidden;
32
- cursor: pointer;
33
- display: flex;
34
- align-items: flex-end;
35
- justify-content: center;
36
- }
37
- .bpmn-card {
38
- --y: -4px;
39
- --s: 1;
40
- position: absolute;
41
- bottom: 0;
42
- width: 54px;
43
- height: 54px;
44
- transform: translateY(var(--y)) scale(var(--s));
45
- translate: var(--active-x, 0) var(--active-y, 0);
46
- rotate: var(--active-r, -2deg);
47
- scale: var(--active-s, 1);
48
- transition: transform 0.3s ease, translate 0.3s ease, rotate 0.3s ease,
49
- scale 0.3s ease;
50
- }
51
- .bpmn-card svg {
52
- display: block;
53
- width: 100%;
54
- height: 100%;
55
- }
56
- .bpmn-root:hover .bpmn-card {
57
- --y: -10px;
58
- --s: 1.07;
59
- }
60
- `; }
61
- _toggleMenu() {
62
- if (this.popper) {
63
- this.popper.dispose();
64
- this.popper = null;
65
- return;
66
- }
67
- this.setEdgelessTool(DefaultTool);
68
- const menu = this.createPopper('edgeless-bpmn-menu', this);
69
- menu.element.edgeless = this.edgeless;
70
- const el = menu.element;
71
- const wrap = el.parentElement;
72
- if (wrap) {
73
- wrap.style.overflow = 'visible';
74
- wrap.style.justifyContent = 'flex-end';
75
- }
76
- Object.assign(el.style, {
77
- position: 'static',
78
- width: 'max-content',
79
- maxWidth: 'calc(100vw - 16px)',
80
- marginLeft: '0',
81
- });
82
- }
83
- render() {
84
- return html `<edgeless-toolbar-button
85
- class="bpmn-button"
86
- .tooltip=${this.popper ? '' : 'BPMN'}
87
- .tooltipOffset=${4}
88
- .active=${!!this.popper}
89
- @click=${this._toggleMenu}
90
- >
91
- <div class="bpmn-root">
92
- <div class="bpmn-card">${bpmnToolbarIcon}</div>
93
- </div>
94
- </edgeless-toolbar-button>`;
95
- }
96
- }
97
- //# sourceMappingURL=bpmn-senior-button.js.map
1
+ import { DefaultTool } from '@formicoidea/labre-core/blocks/surface';
2
+ import { EmptyTool } from '@formicoidea/labre-core/gfx/pointer';
3
+ import { EdgelessToolbarToolMixin } from '@formicoidea/labre-core/widgets/edgeless-toolbar';
4
+ import { SignalWatcher } from '@formicoidea/labre-core/global/lit';
5
+ import { css, html, LitElement } from 'lit';
6
+
7
+ import { bpmnToolbarIcon } from './icons';
8
+
9
+ /**
10
+ * Main toolbar button (colored BPMN glyph) that opens the BPMN toolbox sub-menu
11
+ * above the toolbar. Mirrors the EDGY / Wardley senior buttons.
12
+ */
13
+ export class EdgelessBpmnSeniorButton extends EdgelessToolbarToolMixin(
14
+ SignalWatcher(LitElement)
15
+ ) {
16
+ static override styles = css`
17
+ :host,
18
+ .bpmn-button {
19
+ display: block;
20
+ width: 100%;
21
+ height: 100%;
22
+ }
23
+ :host {
24
+ position: relative;
25
+ }
26
+ .bpmn-root {
27
+ width: 100%;
28
+ height: 64px;
29
+ position: relative;
30
+ overflow: hidden;
31
+ cursor: pointer;
32
+ display: flex;
33
+ align-items: flex-end;
34
+ justify-content: center;
35
+ }
36
+ .bpmn-card {
37
+ --y: -4px;
38
+ --s: 1;
39
+ position: absolute;
40
+ bottom: 0;
41
+ width: 54px;
42
+ height: 54px;
43
+ transform: translateY(var(--y)) scale(var(--s));
44
+ translate: var(--active-x, 0) var(--active-y, 0);
45
+ rotate: var(--active-r, -2deg);
46
+ scale: var(--active-s, 1);
47
+ transition: transform 0.3s ease, translate 0.3s ease, rotate 0.3s ease,
48
+ scale 0.3s ease;
49
+ }
50
+ .bpmn-card svg {
51
+ display: block;
52
+ width: 100%;
53
+ height: 100%;
54
+ }
55
+ .bpmn-root:hover .bpmn-card {
56
+ --y: -10px;
57
+ --s: 1.07;
58
+ }
59
+ `;
60
+
61
+ override enableActiveBackground = true;
62
+
63
+ override type = EmptyTool;
64
+
65
+ private _toggleMenu() {
66
+ if (this.popper) {
67
+ this.popper.dispose();
68
+ this.popper = null;
69
+ return;
70
+ }
71
+ this.setEdgelessTool(DefaultTool);
72
+ const menu = this.createPopper('edgeless-bpmn-menu', this);
73
+ menu.element.edgeless = this.edgeless;
74
+
75
+ const el = menu.element as HTMLElement;
76
+ const wrap = el.parentElement;
77
+ if (wrap) {
78
+ wrap.style.overflow = 'visible';
79
+ wrap.style.justifyContent = 'flex-end';
80
+ }
81
+ Object.assign(el.style, {
82
+ position: 'static',
83
+ width: 'max-content',
84
+ maxWidth: 'calc(100vw - 16px)',
85
+ marginLeft: '0',
86
+ });
87
+ }
88
+
89
+ override render() {
90
+ return html`<edgeless-toolbar-button
91
+ class="bpmn-button"
92
+ .tooltip=${this.popper ? '' : 'BPMN'}
93
+ .tooltipOffset=${4}
94
+ .active=${!!this.popper}
95
+ @click=${this._toggleMenu}
96
+ >
97
+ <div class="bpmn-root">
98
+ <div class="bpmn-card">${bpmnToolbarIcon}</div>
99
+ </div>
100
+ </edgeless-toolbar-button>`;
101
+ }
102
+ }
@@ -0,0 +1,74 @@
1
+ import { EdgelessCRUDIdentifier } from '@formicoidea/labre-core/blocks/surface';
2
+ import { BpmnPoolElementModel } from '@formicoidea/labre-core/model';
3
+ import {
4
+ type ToolbarContext,
5
+ type ToolbarModuleConfig,
6
+ ToolbarModuleExtension,
7
+ } from '@formicoidea/labre-core/shared/services';
8
+ import { BlockFlavourIdentifier } from '@formicoidea/labre-core/std';
9
+ import { html, type TemplateResult } from 'lit';
10
+
11
+ const ResizeIcon = html`<svg
12
+ width="24"
13
+ height="24"
14
+ viewBox="0 0 24 24"
15
+ fill="none"
16
+ stroke="currentColor"
17
+ stroke-width="1.6"
18
+ stroke-linecap="round"
19
+ stroke-linejoin="round"
20
+ >
21
+ <path d="M9 5H5v4M15 19h4v-4" />
22
+ <path d="M5 5l6 6M19 19l-6-6" />
23
+ </svg>`;
24
+
25
+ type BpmnPoolToggleProp = 'resizeEnabled';
26
+
27
+ /**
28
+ * Build a toolbar toggle that flips a boolean flag on every selected pool:
29
+ * `active` reflects the current state, `run` flips it (with an undo checkpoint).
30
+ */
31
+ function booleanToggle(
32
+ id: string,
33
+ tooltip: string,
34
+ icon: TemplateResult,
35
+ prop: BpmnPoolToggleProp
36
+ ) {
37
+ return {
38
+ id,
39
+ tooltip,
40
+ icon,
41
+ active(ctx: ToolbarContext) {
42
+ const models = ctx.getSurfaceModelsByType(BpmnPoolElementModel);
43
+ return models.length > 0 && models.every(model => model[prop]);
44
+ },
45
+ run(ctx: ToolbarContext) {
46
+ const models = ctx.getSurfaceModelsByType(BpmnPoolElementModel);
47
+ if (!models.length) return;
48
+
49
+ const enable = !models.every(model => model[prop]);
50
+ ctx.std.store.captureSync();
51
+ const crud = ctx.std.get(EdgelessCRUDIdentifier);
52
+ for (const model of models) {
53
+ crud.updateElement(model.id, { [prop]: enable });
54
+ }
55
+ },
56
+ };
57
+ }
58
+
59
+ export const bpmnPoolToolbarConfig = {
60
+ actions: [
61
+ booleanToggle(
62
+ 'a.toggle-resize',
63
+ 'Enable / lock resizing',
64
+ ResizeIcon,
65
+ 'resizeEnabled'
66
+ ),
67
+ ],
68
+ when: ctx => ctx.getSurfaceModelsByType(BpmnPoolElementModel).length > 0,
69
+ } as const satisfies ToolbarModuleConfig;
70
+
71
+ export const bpmnPoolToolbarExtension = ToolbarModuleExtension({
72
+ id: BlockFlavourIdentifier('affine:surface:bpmnPool'),
73
+ config: bpmnPoolToolbarConfig,
74
+ });
@@ -1,37 +1,43 @@
1
- import { svg } from 'lit';
2
- /** Colored BPMN glyph for the main toolbar button: a pool (green name band) with
3
- * a single activity inside. */
4
- export const bpmnToolbarIcon = svg `<svg width="100%" height="100%" viewBox="0 0 56 56" fill="none" xmlns="http://www.w3.org/2000/svg">
5
- <rect x="4" y="13" width="48" height="30" rx="3" fill="#ffffff" stroke="#262626" stroke-width="2.2"/>
6
- <path d="M6 14 h5 v28 h-5 z" fill="#43a06b"/>
7
- <line x1="11" y1="13" x2="11" y2="43" stroke="#262626" stroke-width="1.8"/>
8
- <rect x="20" y="20" width="24" height="16" rx="3.5" fill="#ffffff" stroke="#262626" stroke-width="2.2"/>
9
- </svg>`;
10
- /** Start event — thin green ring. */
11
- export const bpmnStartIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
12
- <circle cx="12" cy="12" r="8" stroke="#43a06b" stroke-width="2"/>
13
- </svg>`;
14
- /** End event thick red ring. */
15
- export const bpmnEndIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
16
- <circle cx="12" cy="12" r="8" stroke="#cf5648" stroke-width="3.5"/>
17
- </svg>`;
18
- /** Task rounded rectangle. */
19
- export const bpmnTaskIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
20
- <rect x="3.5" y="6.5" width="17" height="11" rx="2.5" stroke="currentColor" stroke-width="1.6"/>
21
- </svg>`;
22
- /** Exclusive gateway diamond with an X. */
23
- export const bpmnGatewayIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
24
- <path d="M12 3 L21 12 L12 21 L3 12 Z" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/>
25
- <path d="M9 9 L15 15 M15 9 L9 15" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>
26
- </svg>`;
27
- /** Sequence flowsolid arrow with a filled head. */
28
- export const bpmnSequenceIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
29
- <path d="M3 12 H17" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
30
- <path d="M15 8 L21 12 L15 16 Z" fill="currentColor"/>
31
- </svg>`;
32
- /** Pool — rectangle with a left name band. */
33
- export const bpmnPoolIcon = svg `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
34
- <rect x="3.5" y="5.5" width="17" height="13" rx="1.5" stroke="currentColor" stroke-width="1.6"/>
35
- <path d="M8 5.5 V18.5" stroke="currentColor" stroke-width="1.6"/>
36
- </svg>`;
37
- //# sourceMappingURL=icons.js.map
1
+ import { svg } from 'lit';
2
+
3
+ /** Colored BPMN glyph for the main toolbar button: a pool (green name band) with
4
+ * a single activity inside. */
5
+ export const bpmnToolbarIcon = svg`<svg width="100%" height="100%" viewBox="0 0 56 56" fill="none" xmlns="http://www.w3.org/2000/svg">
6
+ <rect x="4" y="13" width="48" height="30" rx="3" fill="#ffffff" stroke="#262626" stroke-width="2.2"/>
7
+ <path d="M6 14 h5 v28 h-5 z" fill="#43a06b"/>
8
+ <line x1="11" y1="13" x2="11" y2="43" stroke="#262626" stroke-width="1.8"/>
9
+ <rect x="20" y="20" width="24" height="16" rx="3.5" fill="#ffffff" stroke="#262626" stroke-width="2.2"/>
10
+ </svg>`;
11
+
12
+ /** Start event thin green ring. */
13
+ export const bpmnStartIcon = svg`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
14
+ <circle cx="12" cy="12" r="8" stroke="#43a06b" stroke-width="2"/>
15
+ </svg>`;
16
+
17
+ /** End event — thick red ring. */
18
+ export const bpmnEndIcon = svg`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
19
+ <circle cx="12" cy="12" r="8" stroke="#cf5648" stroke-width="3.5"/>
20
+ </svg>`;
21
+
22
+ /** Taskrounded rectangle. */
23
+ export const bpmnTaskIcon = svg`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
24
+ <rect x="3.5" y="6.5" width="17" height="11" rx="2.5" stroke="currentColor" stroke-width="1.6"/>
25
+ </svg>`;
26
+
27
+ /** Exclusive gatewaydiamond with an X. */
28
+ export const bpmnGatewayIcon = svg`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
29
+ <path d="M12 3 L21 12 L12 21 L3 12 Z" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/>
30
+ <path d="M9 9 L15 15 M15 9 L9 15" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>
31
+ </svg>`;
32
+
33
+ /** Sequence flow solid arrow with a filled head. */
34
+ export const bpmnSequenceIcon = svg`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
35
+ <path d="M3 12 H17" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
36
+ <path d="M15 8 L21 12 L15 16 Z" fill="currentColor"/>
37
+ </svg>`;
38
+
39
+ /** Pool — rectangle with a left name band. */
40
+ export const bpmnPoolIcon = svg`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
41
+ <rect x="3.5" y="5.5" width="17" height="13" rx="1.5" stroke="currentColor" stroke-width="1.6"/>
42
+ <path d="M8 5.5 V18.5" stroke="currentColor" stroke-width="1.6"/>
43
+ </svg>`;
@@ -1,11 +1,11 @@
1
- import { SeniorToolExtension } from '@formicoidea/labre-core/widgets/edgeless-toolbar';
2
- import { html } from 'lit';
3
- export const bpmnSeniorTool = SeniorToolExtension('bpmn', ({ block }) => {
4
- return {
5
- name: 'BPMN',
6
- content: html `<edgeless-bpmn-senior-button
7
- .edgeless=${block}
8
- ></edgeless-bpmn-senior-button>`,
9
- };
10
- });
11
- //# sourceMappingURL=senior-tool.js.map
1
+ import { SeniorToolExtension } from '@formicoidea/labre-core/widgets/edgeless-toolbar';
2
+ import { html } from 'lit';
3
+
4
+ export const bpmnSeniorTool = SeniorToolExtension('bpmn', ({ block }) => {
5
+ return {
6
+ name: 'BPMN',
7
+ content: html`<edgeless-bpmn-senior-button
8
+ .edgeless=${block}
9
+ ></edgeless-bpmn-senior-button>`,
10
+ };
11
+ });
package/src/view.ts ADDED
@@ -0,0 +1,37 @@
1
+ import {
2
+ type ViewExtensionContext,
3
+ ViewExtensionProvider,
4
+ } from '@formicoidea/labre-core/ext-loader';
5
+ import { extendTemplateCategory } from '@formicoidea/labre-core/gfx/template';
6
+
7
+ import { effects } from './effects';
8
+ import { bpmnTemplateCategory } from './templates';
9
+ import { BpmnPoolRendererExtension } from './element-renderer';
10
+ import { BpmnPoolInteraction, BpmnPoolView } from './element-view';
11
+ import { BpmnNodeRendererExtension } from './node/node-renderer';
12
+ import { BpmnNodeView } from './node/node-view';
13
+ import { bpmnPoolToolbarExtension } from './toolbar/config';
14
+ import { bpmnSeniorTool } from './toolbar/senior-tool';
15
+
16
+ export class BpmnViewExtension extends ViewExtensionProvider {
17
+ override name = 'affine-bpmn-gfx';
18
+
19
+ override effect(): void {
20
+ super.effect();
21
+ effects();
22
+ extendTemplateCategory(bpmnTemplateCategory);
23
+ }
24
+
25
+ override setup(context: ViewExtensionContext) {
26
+ super.setup(context);
27
+ context.register(BpmnPoolView);
28
+ context.register(BpmnPoolRendererExtension);
29
+ context.register(BpmnNodeView);
30
+ context.register(BpmnNodeRendererExtension);
31
+ if (this.isEdgeless(context.scope)) {
32
+ context.register(BpmnPoolInteraction);
33
+ context.register(bpmnSeniorTool);
34
+ context.register(bpmnPoolToolbarExtension);
35
+ }
36
+ }
37
+ }