@formicoidea/labre-framework-bpmn 0.23.0 → 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.
@@ -1,102 +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
-
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
- }
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
+ }
@@ -1,74 +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
+ 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,43 +1,43 @@
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
- /** Task — rounded 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 gateway — diamond 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
+ 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
+ /** Task — rounded 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 gateway — diamond 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
-
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
- });
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
+ });