@formicoidea/labre-framework-bpmn 0.32.0 → 0.34.1

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 (49) hide show
  1. package/dist/actions.d.ts +202 -6
  2. package/dist/actions.js +427 -43
  3. package/dist/background.d.ts +2 -0
  4. package/dist/background.js +158 -0
  5. package/dist/commands-manifest.d.ts +18 -0
  6. package/dist/commands-manifest.js +226 -0
  7. package/dist/commands.js +496 -5
  8. package/dist/consts.d.ts +195 -4
  9. package/dist/consts.js +230 -4
  10. package/dist/element-renderer.d.ts +10 -4
  11. package/dist/element-renderer.js +14 -55
  12. package/dist/element-view.d.ts +119 -8
  13. package/dist/element-view.js +274 -30
  14. package/dist/export.d.ts +277 -0
  15. package/dist/export.js +1802 -0
  16. package/dist/facts.d.ts +48 -0
  17. package/dist/facts.js +127 -0
  18. package/dist/import.d.ts +69 -0
  19. package/dist/import.js +1476 -0
  20. package/dist/index.d.ts +12 -0
  21. package/dist/index.js +47 -0
  22. package/dist/interchange.d.ts +109 -0
  23. package/dist/interchange.js +191 -0
  24. package/dist/morph.d.ts +61 -0
  25. package/dist/morph.js +118 -0
  26. package/dist/node/node-renderer.d.ts +0 -9
  27. package/dist/node/node-renderer.js +294 -17
  28. package/dist/pool-hit.d.ts +98 -0
  29. package/dist/pool-hit.js +130 -0
  30. package/dist/presets.d.ts +168 -0
  31. package/dist/presets.js +327 -0
  32. package/dist/profiles.d.ts +2 -0
  33. package/dist/profiles.js +189 -0
  34. package/dist/roles.d.ts +96 -0
  35. package/dist/roles.js +410 -0
  36. package/dist/rules.d.ts +199 -0
  37. package/dist/rules.js +1539 -0
  38. package/dist/templates/index.js +116 -9
  39. package/dist/toolbar/bpmn-senior-button.js +8 -2
  40. package/dist/toolbar/config.d.ts +28 -2
  41. package/dist/toolbar/config.js +93 -4
  42. package/dist/toolbar/icons.d.ts +67 -0
  43. package/dist/toolbar/icons.js +141 -0
  44. package/dist/toolbar/senior-tool.js +1 -0
  45. package/dist/translations.d.ts +3 -1
  46. package/dist/translations.js +38 -3
  47. package/dist/view.d.ts +6 -2
  48. package/dist/view.js +68 -5
  49. package/package.json +6 -2
package/dist/consts.d.ts CHANGED
@@ -17,25 +17,216 @@ export declare const NODE_FILL = "#ffffff";
17
17
  export declare const START_WIDTH = 2;
18
18
  export declare const END_WIDTH = 4;
19
19
  export declare const NODE_STROKE_WIDTH = 2;
20
+ /**
21
+ * The call activity's border, which the spec draws THICK — it is the one way to
22
+ * tell it from the sub-process, since both carry the same `+` marker. Same
23
+ * weight as the end-event ring, and for the same reason: this is the heaviest
24
+ * line the notation uses, and it is spent on "this one stands for a whole
25
+ * process defined somewhere else".
26
+ */
27
+ export declare const CALL_ACTIVITY_WIDTH = 4;
20
28
  /** Task corner radius (absolute px — a lightly rounded rectangle). */
21
29
  export declare const TASK_RADIUS = 10;
30
+ /**
31
+ * The group's corner radius — twice a task's, because it is drawn at three
32
+ * times the size and a 10-unit corner on a 300-unit box reads as a square one.
33
+ */
34
+ export declare const GROUP_RADIUS = 20;
35
+ /**
36
+ * The group's dashed border.
37
+ *
38
+ * Grey and not the flow objects' near-black: a group is furniture drawn AROUND
39
+ * the work, and it is the one artefact on the canvas guaranteed to overlap
40
+ * several others. At the neutral stroke it out-shouts everything it encloses,
41
+ * which is the exact opposite of what a lasso is for. Every tool that draws
42
+ * BPMN makes the same call; the spec prescribes the dash and says nothing about
43
+ * the colour.
44
+ */
45
+ export declare const GROUP_STROKE = "#8e8d91";
22
46
  /** Inner-text font for the task label. */
23
47
  export declare const INNER_FONT_SIZE = 18;
24
- /** Default node sizes (model units) per kind. */
48
+ /**
49
+ * The smallest font a FITTED label is asked for — the importer's floor, and
50
+ * only its (`bpmnLabelFit` in `presets.ts`).
51
+ *
52
+ * A file draws its artefacts at whatever scale its author's tool uses, and
53
+ * bpmn.io's normative sizes are about six tenths of this pack's: a 36-unit
54
+ * event against a 56-unit one, a 100×72 task against a 120×72. The label of an
55
+ * imported artefact is therefore asked for at a size proportional to the box
56
+ * the FILE gave, and 10 is where that shrinking stops — under it a label is no
57
+ * longer read, it is guessed at.
58
+ *
59
+ * It is a floor on what is ASKED for, not on what is painted: the shape
60
+ * renderer's own `TextFitMode.Contained` pass shrinks further, to its own floor
61
+ * of 8 (`MIN_CONTAINED_FONT_SIZE`), when even this does not fit. Kept here as a
62
+ * number of our own rather than imported from `@labre/affine-gfx-shape`, so the
63
+ * reader stays a pure function of a string with no renderer behind it (ADR
64
+ * 0012, P3).
65
+ */
66
+ export declare const LABEL_MIN_FONT_SIZE = 10;
67
+ /**
68
+ * How much of a box a fitted label gives up to its margin, per side.
69
+ *
70
+ * A shape's native inset is a FIXED 20 units horizontally
71
+ * (`SHAPE_TEXT_PADDING`), which is a sixth of this pack's 120-unit task and
72
+ * therefore invisible on a drawn board — and more than the whole width of a
73
+ * 36-unit event, which leaves NEGATIVE room for the text and is why an imported
74
+ * label breaks in the middle of a word. Expressed as a ratio, the margin
75
+ * follows the artefact down: it is exactly the native inset at the pack's own
76
+ * task width and it never grows past it, so a drawn node is untouched and a
77
+ * small one keeps a usable line.
78
+ */
79
+ export declare const LABEL_INSET_RATIO: number;
80
+ /**
81
+ * Default node sizes (model units) per kind.
82
+ *
83
+ * Three sizes carry the whole scale: the 56-unit event, the 120×72 task and the
84
+ * 72-unit gateway. Everything the descriptive profile adds takes one of them —
85
+ * a message start is a start event, a user task is a task — except the three
86
+ * data/artifact shapes, which have no sibling to inherit from:
87
+ *
88
+ * - `dataObject` is a PORTRAIT page (3:4), 64 tall so it stands beside a
89
+ * 56-unit event without looking like a shrunken task;
90
+ * - `dataStore` is the event's own diameter, which is what a cylinder needs to
91
+ * read as one rather than as a squashed ellipse;
92
+ * - `textAnnotation` is wider than a task and shorter — it holds a sentence,
93
+ * not a verb phrase.
94
+ *
95
+ * These three are ~1.2–1.4× bpmn.io's normative pixel sizes, which is the ratio
96
+ * this pack's event and task already sit at against the same reference.
97
+ *
98
+ * `group` is on no scale at all: it is a LASSO, so it has to be born big enough
99
+ * to have something in it. 300×200 holds two tasks and the arrow between them,
100
+ * which is the smallest thing anybody draws a group around.
101
+ */
25
102
  export declare const NODE_SIZE: Record<BpmnNodeKind, {
26
103
  w: number;
27
104
  h: number;
28
105
  }>;
29
- /** Default inner text per kind (only the task carries a label). */
106
+ /**
107
+ * Default inner text per kind.
108
+ *
109
+ * The activities carry one, because a rectangle with nothing written in it says
110
+ * nothing at all. Events and gateways do not: their meaning is the glyph, and
111
+ * BPMN puts whatever name they have OUTSIDE the symbol.
112
+ *
113
+ * `dataObject` and `dataStore` are empty for the same reason plus one of our
114
+ * own: the spec puts their name under the shape, the native inner text can only
115
+ * go inside it, and inside is where the folded page and the cylinder already
116
+ * are. The user can still type — the text simply overflows, which is the
117
+ * honest failure rather than a label painted over the glyph.
118
+ *
119
+ * The caption is asked of the host's catalogue under {@link nodeLabelKey} when
120
+ * the artefact is placed, with the entry below as the English default.
121
+ */
30
122
  export declare const NODE_LABEL: Record<BpmnNodeKind, string>;
31
- /** Pool (background container) defaults. */
32
- export declare const POOL_BAND_WIDTH = 28;
123
+ /**
124
+ * The i18n key {@link NODE_LABEL} is the English default of.
125
+ *
126
+ * Resolved AT PLACEMENT (`createBpmnNode`) and never afterwards: what a gesture
127
+ * writes into the document is content the author owns from that moment on, and
128
+ * a renderer that re-translated it on every paint would silently overwrite a
129
+ * name somebody typed. The kinds with an empty label ask for nothing — there is
130
+ * no word to translate, and BPMN puts an event's name outside its glyph anyway.
131
+ */
132
+ export declare const nodeLabelKey: (kind: BpmnNodeKind) => string;
133
+ /**
134
+ * Pool (background container) defaults — read by the `BPMN_POOL_BACKGROUND`
135
+ * declaration (`background.ts`), which is the only thing that draws a pool.
136
+ */
33
137
  export declare const POOL_FRAME_COLOR = "#262626";
138
+ /**
139
+ * The card. The same white every framework background paints — it is what
140
+ * `DEFAULT_BACKGROUND_SURFACE` gives a declaration that names no fill, and what
141
+ * the Wardley map, the Core Domain Chart and the Context Map board all declare.
142
+ */
143
+ export declare const POOL_CARD_FILL = "#ffffff";
34
144
  export declare const POOL_BAND_FILL = "#f4f4f5";
35
145
  export declare const POOL_FRAME_WIDTH = 1.5;
146
+ export declare const POOL_CORNER_RADIUS = 6;
36
147
  export declare const POOL_NAME_FONT_SIZE = 15;
37
148
  export declare const POOL_NAME_COLOR = "#262626";
38
149
  export declare const POOL_FONT_FAMILY = "Inter, sans-serif";
150
+ /**
151
+ * Lane (couloir) name size — two units under the participant's own.
152
+ *
153
+ * The pool names WHO does the work and the lane names which part of them does
154
+ * it: a subdivision reads as a subdivision when its label is quieter than the
155
+ * one it sits under. Two units is the smallest difference that survives being
156
+ * zoomed out, which is the size the distinction has to hold at.
157
+ */
158
+ export declare const POOL_LANE_NAME_FONT_SIZE = 13;
159
+ /**
160
+ * The two band widths live in `@labre/affine-model`, beside the pool model that
161
+ * hit-tests against them (a pool is clickable by its title bands as well as by
162
+ * its border — the bpmn.io convention, issue #194). They are re-exported here
163
+ * so this file stays the one place a reader looks for a pool's metrics, and so
164
+ * the declaration keeps reading them from where it always did.
165
+ */
166
+ export { POOL_BAND_WIDTH, POOL_LANE_BAND_WIDTH } from '@formicoidea/labre-core/model';
167
+ /**
168
+ * How close to an internal lane boundary a pointer has to be, in MODEL units,
169
+ * for the gesture to be a separator drag rather than a click on the pool.
170
+ *
171
+ * Symmetric, so the zone is 12 units wide. Model units and not view pixels on
172
+ * purpose: the grab zone then scales with the drawing, exactly like the lane it
173
+ * belongs to, and a pool zoomed out to a thumbnail does not become a strip of
174
+ * overlapping hit zones with no lane left between them.
175
+ */
176
+ export declare const POOL_LANE_GRAB = 6;
177
+ /**
178
+ * The smallest a lane may be dragged to, in model units of a pool at its
179
+ * REFERENCE height ({@link POOL_REF_HEIGHT}).
180
+ *
181
+ * A floor and not a minimum height: sizes are weights, so this is converted to
182
+ * a weight against the pool's current total before it is applied. 24 units is
183
+ * about one line of a lane name plus its inset — below that the band cannot
184
+ * show what it is, and a lane nothing can be put in and nothing can be read off
185
+ * is one the user did not mean to make.
186
+ */
187
+ export declare const POOL_LANE_MIN_HEIGHT = 24;
188
+ /**
189
+ * The size a fresh pool is created at. Unlike a map, a pool is NOT grown to
190
+ * cover the ones already on the board: pools sit side by side, one per
191
+ * participant, and a second lane that matched the first one's height would
192
+ * claim room the process has not asked for.
193
+ *
194
+ * `actions.ts` and the templates still write these two numbers themselves; the
195
+ * declaration names them so there is somewhere for them to converge.
196
+ */
197
+ export declare const POOL_REF_WIDTH = 560;
198
+ export declare const POOL_REF_HEIGHT = 200;
39
199
  /** Sequence-flow connector preset. */
40
200
  export declare const SEQUENCE_STROKE = "#262626";
41
201
  export declare const SEQUENCE_WIDTH = 2;
202
+ /**
203
+ * Message-flow connector preset — the dashed line that crosses between pools.
204
+ *
205
+ * Same ink and same weight as the sequence flow: what tells the two apart is
206
+ * the DASH and the endpoints (an open circle where the message leaves, an open
207
+ * arrowhead where it lands), which is exactly the distinction BPMN draws.
208
+ */
209
+ export declare const MESSAGE_STROKE = "#262626";
210
+ export declare const MESSAGE_WIDTH = 2;
211
+ /**
212
+ * Association connector preset — the line that ties a note or a data object to
213
+ * the work it is about.
214
+ *
215
+ * ## Dashed, not dotted (simplification, and why it is survivable)
216
+ *
217
+ * BPMN draws a message flow DASHED and an association DOTTED. This editor's
218
+ * `StrokeStyle` has three members — `Solid`, `Dash`, `None` — and the dash
219
+ * pattern is a fixed `[12, 12]` no framework can tighten, so there is no dotted
220
+ * stroke to ask for. Drawing it thinner instead is not available either: a
221
+ * connector's `strokeWidth` is a closed enum (`2 | 4 | … | 12`) the props store
222
+ * validates, and 2 is already the floor.
223
+ *
224
+ * So the association ships with the message flow's own line, and carries the
225
+ * distinction entirely on its ENDPOINTS: a message flow always shows a circle
226
+ * where it leaves and an arrowhead where it lands, an association shows neither
227
+ * at either end. That is a difference the eye reads at a glance and, unlike the
228
+ * dot pattern, it is one the notation itself means — an association has no
229
+ * direction to point in. A rule reads the `role`, which is exact either way.
230
+ */
231
+ export declare const ASSOCIATION_STROKE = "#262626";
232
+ export declare const ASSOCIATION_WIDTH = 2;
package/dist/consts.js CHANGED
@@ -16,32 +16,258 @@ export const NODE_FILL = '#ffffff';
16
16
  export const START_WIDTH = 2;
17
17
  export const END_WIDTH = 4;
18
18
  export const NODE_STROKE_WIDTH = 2;
19
+ /**
20
+ * The call activity's border, which the spec draws THICK — it is the one way to
21
+ * tell it from the sub-process, since both carry the same `+` marker. Same
22
+ * weight as the end-event ring, and for the same reason: this is the heaviest
23
+ * line the notation uses, and it is spent on "this one stands for a whole
24
+ * process defined somewhere else".
25
+ */
26
+ export const CALL_ACTIVITY_WIDTH = END_WIDTH;
19
27
  /** Task corner radius (absolute px — a lightly rounded rectangle). */
20
28
  export const TASK_RADIUS = 10;
29
+ /**
30
+ * The group's corner radius — twice a task's, because it is drawn at three
31
+ * times the size and a 10-unit corner on a 300-unit box reads as a square one.
32
+ */
33
+ export const GROUP_RADIUS = 20;
34
+ /**
35
+ * The group's dashed border.
36
+ *
37
+ * Grey and not the flow objects' near-black: a group is furniture drawn AROUND
38
+ * the work, and it is the one artefact on the canvas guaranteed to overlap
39
+ * several others. At the neutral stroke it out-shouts everything it encloses,
40
+ * which is the exact opposite of what a lasso is for. Every tool that draws
41
+ * BPMN makes the same call; the spec prescribes the dash and says nothing about
42
+ * the colour.
43
+ */
44
+ export const GROUP_STROKE = '#8e8d91';
21
45
  /** Inner-text font for the task label. */
22
46
  export const INNER_FONT_SIZE = 18;
23
- /** Default node sizes (model units) per kind. */
47
+ /**
48
+ * The smallest font a FITTED label is asked for — the importer's floor, and
49
+ * only its (`bpmnLabelFit` in `presets.ts`).
50
+ *
51
+ * A file draws its artefacts at whatever scale its author's tool uses, and
52
+ * bpmn.io's normative sizes are about six tenths of this pack's: a 36-unit
53
+ * event against a 56-unit one, a 100×72 task against a 120×72. The label of an
54
+ * imported artefact is therefore asked for at a size proportional to the box
55
+ * the FILE gave, and 10 is where that shrinking stops — under it a label is no
56
+ * longer read, it is guessed at.
57
+ *
58
+ * It is a floor on what is ASKED for, not on what is painted: the shape
59
+ * renderer's own `TextFitMode.Contained` pass shrinks further, to its own floor
60
+ * of 8 (`MIN_CONTAINED_FONT_SIZE`), when even this does not fit. Kept here as a
61
+ * number of our own rather than imported from `@labre/affine-gfx-shape`, so the
62
+ * reader stays a pure function of a string with no renderer behind it (ADR
63
+ * 0012, P3).
64
+ */
65
+ export const LABEL_MIN_FONT_SIZE = 10;
66
+ /**
67
+ * How much of a box a fitted label gives up to its margin, per side.
68
+ *
69
+ * A shape's native inset is a FIXED 20 units horizontally
70
+ * (`SHAPE_TEXT_PADDING`), which is a sixth of this pack's 120-unit task and
71
+ * therefore invisible on a drawn board — and more than the whole width of a
72
+ * 36-unit event, which leaves NEGATIVE room for the text and is why an imported
73
+ * label breaks in the middle of a word. Expressed as a ratio, the margin
74
+ * follows the artefact down: it is exactly the native inset at the pack's own
75
+ * task width and it never grows past it, so a drawn node is untouched and a
76
+ * small one keeps a usable line.
77
+ */
78
+ export const LABEL_INSET_RATIO = 1 / 6;
79
+ /**
80
+ * Default node sizes (model units) per kind.
81
+ *
82
+ * Three sizes carry the whole scale: the 56-unit event, the 120×72 task and the
83
+ * 72-unit gateway. Everything the descriptive profile adds takes one of them —
84
+ * a message start is a start event, a user task is a task — except the three
85
+ * data/artifact shapes, which have no sibling to inherit from:
86
+ *
87
+ * - `dataObject` is a PORTRAIT page (3:4), 64 tall so it stands beside a
88
+ * 56-unit event without looking like a shrunken task;
89
+ * - `dataStore` is the event's own diameter, which is what a cylinder needs to
90
+ * read as one rather than as a squashed ellipse;
91
+ * - `textAnnotation` is wider than a task and shorter — it holds a sentence,
92
+ * not a verb phrase.
93
+ *
94
+ * These three are ~1.2–1.4× bpmn.io's normative pixel sizes, which is the ratio
95
+ * this pack's event and task already sit at against the same reference.
96
+ *
97
+ * `group` is on no scale at all: it is a LASSO, so it has to be born big enough
98
+ * to have something in it. 300×200 holds two tasks and the arrow between them,
99
+ * which is the smallest thing anybody draws a group around.
100
+ */
24
101
  export const NODE_SIZE = {
25
102
  startEvent: { w: 56, h: 56 },
103
+ startEventMessage: { w: 56, h: 56 },
104
+ startEventTimer: { w: 56, h: 56 },
26
105
  endEvent: { w: 56, h: 56 },
106
+ endEventMessage: { w: 56, h: 56 },
107
+ endEventTerminate: { w: 56, h: 56 },
27
108
  task: { w: 120, h: 72 },
109
+ taskUser: { w: 120, h: 72 },
110
+ taskService: { w: 120, h: 72 },
111
+ subProcess: { w: 120, h: 72 },
112
+ callActivity: { w: 120, h: 72 },
28
113
  gatewayExclusive: { w: 72, h: 72 },
114
+ gatewayParallel: { w: 72, h: 72 },
115
+ dataObject: { w: 48, h: 64 },
116
+ dataStore: { w: 56, h: 56 },
117
+ textAnnotation: { w: 140, h: 48 },
118
+ group: { w: 300, h: 200 },
29
119
  };
30
- /** Default inner text per kind (only the task carries a label). */
120
+ /**
121
+ * Default inner text per kind.
122
+ *
123
+ * The activities carry one, because a rectangle with nothing written in it says
124
+ * nothing at all. Events and gateways do not: their meaning is the glyph, and
125
+ * BPMN puts whatever name they have OUTSIDE the symbol.
126
+ *
127
+ * `dataObject` and `dataStore` are empty for the same reason plus one of our
128
+ * own: the spec puts their name under the shape, the native inner text can only
129
+ * go inside it, and inside is where the folded page and the cylinder already
130
+ * are. The user can still type — the text simply overflows, which is the
131
+ * honest failure rather than a label painted over the glyph.
132
+ *
133
+ * The caption is asked of the host's catalogue under {@link nodeLabelKey} when
134
+ * the artefact is placed, with the entry below as the English default.
135
+ */
31
136
  export const NODE_LABEL = {
32
137
  startEvent: '',
138
+ startEventMessage: '',
139
+ startEventTimer: '',
33
140
  endEvent: '',
141
+ endEventMessage: '',
142
+ endEventTerminate: '',
34
143
  task: 'Task',
144
+ taskUser: 'User task',
145
+ taskService: 'Service task',
146
+ subProcess: 'Sub-process',
147
+ callActivity: 'Call activity',
35
148
  gatewayExclusive: '',
149
+ gatewayParallel: '',
150
+ dataObject: '',
151
+ dataStore: '',
152
+ // The one artefact that IS its text.
153
+ textAnnotation: 'Annotation',
154
+ // The group's label is a CategoryValue in the spec. A plain editable string
155
+ // is the v1 of that: it names the lasso, and it is drawn top-left rather than
156
+ // centred so it does not float over whatever the group encloses.
157
+ group: 'Group',
36
158
  };
37
- /** Pool (background container) defaults. */
38
- export const POOL_BAND_WIDTH = 28;
159
+ /**
160
+ * The i18n key {@link NODE_LABEL} is the English default of.
161
+ *
162
+ * Resolved AT PLACEMENT (`createBpmnNode`) and never afterwards: what a gesture
163
+ * writes into the document is content the author owns from that moment on, and
164
+ * a renderer that re-translated it on every paint would silently overwrite a
165
+ * name somebody typed. The kinds with an empty label ask for nothing — there is
166
+ * no word to translate, and BPMN puts an event's name outside its glyph anyway.
167
+ */
168
+ export const nodeLabelKey = (kind) => `com.labre.bpmn.seed.${kind}`;
169
+ /**
170
+ * Pool (background container) defaults — read by the `BPMN_POOL_BACKGROUND`
171
+ * declaration (`background.ts`), which is the only thing that draws a pool.
172
+ */
39
173
  export const POOL_FRAME_COLOR = '#262626';
174
+ /**
175
+ * The card. The same white every framework background paints — it is what
176
+ * `DEFAULT_BACKGROUND_SURFACE` gives a declaration that names no fill, and what
177
+ * the Wardley map, the Core Domain Chart and the Context Map board all declare.
178
+ */
179
+ export const POOL_CARD_FILL = '#ffffff';
40
180
  export const POOL_BAND_FILL = '#f4f4f5';
41
181
  export const POOL_FRAME_WIDTH = 1.5;
182
+ export const POOL_CORNER_RADIUS = 6;
42
183
  export const POOL_NAME_FONT_SIZE = 15;
43
184
  export const POOL_NAME_COLOR = '#262626';
44
185
  export const POOL_FONT_FAMILY = 'Inter, sans-serif';
186
+ /**
187
+ * Lane (couloir) name size — two units under the participant's own.
188
+ *
189
+ * The pool names WHO does the work and the lane names which part of them does
190
+ * it: a subdivision reads as a subdivision when its label is quieter than the
191
+ * one it sits under. Two units is the smallest difference that survives being
192
+ * zoomed out, which is the size the distinction has to hold at.
193
+ */
194
+ export const POOL_LANE_NAME_FONT_SIZE = 13;
195
+ /**
196
+ * The two band widths live in `@labre/affine-model`, beside the pool model that
197
+ * hit-tests against them (a pool is clickable by its title bands as well as by
198
+ * its border — the bpmn.io convention, issue #194). They are re-exported here
199
+ * so this file stays the one place a reader looks for a pool's metrics, and so
200
+ * the declaration keeps reading them from where it always did.
201
+ */
202
+ export { POOL_BAND_WIDTH, POOL_LANE_BAND_WIDTH } from '@formicoidea/labre-core/model';
203
+ /**
204
+ * How close to an internal lane boundary a pointer has to be, in MODEL units,
205
+ * for the gesture to be a separator drag rather than a click on the pool.
206
+ *
207
+ * Symmetric, so the zone is 12 units wide. Model units and not view pixels on
208
+ * purpose: the grab zone then scales with the drawing, exactly like the lane it
209
+ * belongs to, and a pool zoomed out to a thumbnail does not become a strip of
210
+ * overlapping hit zones with no lane left between them.
211
+ */
212
+ export const POOL_LANE_GRAB = 6;
213
+ /**
214
+ * The smallest a lane may be dragged to, in model units of a pool at its
215
+ * REFERENCE height ({@link POOL_REF_HEIGHT}).
216
+ *
217
+ * A floor and not a minimum height: sizes are weights, so this is converted to
218
+ * a weight against the pool's current total before it is applied. 24 units is
219
+ * about one line of a lane name plus its inset — below that the band cannot
220
+ * show what it is, and a lane nothing can be put in and nothing can be read off
221
+ * is one the user did not mean to make.
222
+ */
223
+ export const POOL_LANE_MIN_HEIGHT = 24;
224
+ // The lane-name hit box used to be a corner box declared here
225
+ // (`POOL_LANE_NAME_HIT_WIDTH` / `_HEIGHT`). Since the PO's recette moved the
226
+ // name into a title band, the target IS that band: `element-view.ts` reads it
227
+ // from `backgroundInstanceZoneBand`, so there is nothing left to declare and
228
+ // nothing left that can drift away from what is painted.
229
+ /**
230
+ * The size a fresh pool is created at. Unlike a map, a pool is NOT grown to
231
+ * cover the ones already on the board: pools sit side by side, one per
232
+ * participant, and a second lane that matched the first one's height would
233
+ * claim room the process has not asked for.
234
+ *
235
+ * `actions.ts` and the templates still write these two numbers themselves; the
236
+ * declaration names them so there is somewhere for them to converge.
237
+ */
238
+ export const POOL_REF_WIDTH = 560;
239
+ export const POOL_REF_HEIGHT = 200;
45
240
  /** Sequence-flow connector preset. */
46
241
  export const SEQUENCE_STROKE = '#262626';
47
242
  export const SEQUENCE_WIDTH = 2;
243
+ /**
244
+ * Message-flow connector preset — the dashed line that crosses between pools.
245
+ *
246
+ * Same ink and same weight as the sequence flow: what tells the two apart is
247
+ * the DASH and the endpoints (an open circle where the message leaves, an open
248
+ * arrowhead where it lands), which is exactly the distinction BPMN draws.
249
+ */
250
+ export const MESSAGE_STROKE = '#262626';
251
+ export const MESSAGE_WIDTH = 2;
252
+ /**
253
+ * Association connector preset — the line that ties a note or a data object to
254
+ * the work it is about.
255
+ *
256
+ * ## Dashed, not dotted (simplification, and why it is survivable)
257
+ *
258
+ * BPMN draws a message flow DASHED and an association DOTTED. This editor's
259
+ * `StrokeStyle` has three members — `Solid`, `Dash`, `None` — and the dash
260
+ * pattern is a fixed `[12, 12]` no framework can tighten, so there is no dotted
261
+ * stroke to ask for. Drawing it thinner instead is not available either: a
262
+ * connector's `strokeWidth` is a closed enum (`2 | 4 | … | 12`) the props store
263
+ * validates, and 2 is already the floor.
264
+ *
265
+ * So the association ships with the message flow's own line, and carries the
266
+ * distinction entirely on its ENDPOINTS: a message flow always shows a circle
267
+ * where it leaves and an arrowhead where it lands, an association shows neither
268
+ * at either end. That is a difference the eye reads at a glance and, unlike the
269
+ * dot pattern, it is one the notation itself means — an association has no
270
+ * direction to point in. A rule reads the `role`, which is exact either way.
271
+ */
272
+ export const ASSOCIATION_STROKE = '#262626';
273
+ export const ASSOCIATION_WIDTH = 2;
@@ -1,10 +1,16 @@
1
1
  import { type ElementRenderer } from '@formicoidea/labre-core/blocks/surface';
2
2
  import type { BpmnPoolElementModel } from '@formicoidea/labre-core/model';
3
3
  /**
4
- * Canvas renderer for a BPMN pool: a rounded-rect frame with a vertical name
5
- * band on the left (the participant name is drawn rotated, as in the spec).
6
- * Drawn directly in element space; the band width and font are fixed so they
7
- * stay legible at any pool size. Mirrors the other framework backgrounds.
4
+ * Canvas renderer for the BPMN pool.
5
+ *
6
+ * There is no BPMN drawing code any more: the pool is an INSTANTIATION of the
7
+ * framework-background primitive, configured by the `BPMN_POOL_BACKGROUND`
8
+ * declaration. What used to be ninety lines of hand-traced rounded rectangle,
9
+ * filled band and rotated name is now a declaration any other framework can
10
+ * write for itself.
11
+ *
12
+ * Exported as a function as well as an extension because the fidelity suite
13
+ * drives it directly with a canvas stub.
8
14
  */
9
15
  export declare const bpmnPool: ElementRenderer<BpmnPoolElementModel>;
10
16
  export declare const BpmnPoolRendererExtension: import("@formicoidea/labre-core/store").ExtensionType & {
@@ -1,57 +1,16 @@
1
- import { ElementRendererExtension, } from '@formicoidea/labre-core/blocks/surface';
2
- import { POOL_BAND_FILL, POOL_BAND_WIDTH, POOL_FONT_FAMILY, POOL_FRAME_COLOR, POOL_FRAME_WIDTH, POOL_NAME_COLOR, POOL_NAME_FONT_SIZE, } from './consts.js';
3
- /** Trace a rounded-rectangle path (no dependency on ctx.roundRect). */
4
- function roundedRectPath(ctx, x, y, w, h, r) {
5
- const rr = Math.min(r, w / 2, h / 2);
6
- ctx.beginPath();
7
- ctx.moveTo(x + rr, y);
8
- ctx.lineTo(x + w - rr, y);
9
- ctx.arcTo(x + w, y, x + w, y + rr, rr);
10
- ctx.lineTo(x + w, y + h - rr);
11
- ctx.arcTo(x + w, y + h, x + w - rr, y + h, rr);
12
- ctx.lineTo(x + rr, y + h);
13
- ctx.arcTo(x, y + h, x, y + h - rr, rr);
14
- ctx.lineTo(x, y + rr);
15
- ctx.arcTo(x, y, x + rr, y, rr);
16
- ctx.closePath();
17
- }
1
+ import { createFrameworkBackgroundRenderer, ElementRendererExtension, } from '@formicoidea/labre-core/blocks/surface';
2
+ import { BPMN_POOL_BACKGROUND } from './background.js';
18
3
  /**
19
- * Canvas renderer for a BPMN pool: a rounded-rect frame with a vertical name
20
- * band on the left (the participant name is drawn rotated, as in the spec).
21
- * Drawn directly in element space; the band width and font are fixed so they
22
- * stay legible at any pool size. Mirrors the other framework backgrounds.
4
+ * Canvas renderer for the BPMN pool.
5
+ *
6
+ * There is no BPMN drawing code any more: the pool is an INSTANTIATION of the
7
+ * framework-background primitive, configured by the `BPMN_POOL_BACKGROUND`
8
+ * declaration. What used to be ninety lines of hand-traced rounded rectangle,
9
+ * filled band and rotated name is now a declaration any other framework can
10
+ * write for itself.
11
+ *
12
+ * Exported as a function as well as an extension because the fidelity suite
13
+ * drives it directly with a canvas stub.
23
14
  */
24
- export const bpmnPool = (model, ctx, matrix) => {
25
- const [, , w, h] = model.deserializedXYWH;
26
- const cx = w / 2;
27
- const cy = h / 2;
28
- ctx.setTransform(matrix.translateSelf(cx, cy).rotateSelf(model.rotate).translateSelf(-cx, -cy));
29
- const band = Math.min(POOL_BAND_WIDTH, w);
30
- const inset = POOL_FRAME_WIDTH / 2;
31
- // Name band (left), filled.
32
- ctx.fillStyle = POOL_BAND_FILL;
33
- ctx.fillRect(0, 0, band, h);
34
- // Frame + band divider.
35
- ctx.strokeStyle = POOL_FRAME_COLOR;
36
- ctx.lineWidth = POOL_FRAME_WIDTH;
37
- ctx.lineJoin = 'round';
38
- roundedRectPath(ctx, inset, inset, w - POOL_FRAME_WIDTH, h - POOL_FRAME_WIDTH, 6);
39
- ctx.stroke();
40
- ctx.beginPath();
41
- ctx.moveTo(band, 0);
42
- ctx.lineTo(band, h);
43
- ctx.stroke();
44
- // Participant name, rotated to read up the band (skip when empty / too narrow).
45
- if (model.name && band > 12) {
46
- ctx.save();
47
- ctx.translate(band / 2, h / 2);
48
- ctx.rotate(-Math.PI / 2);
49
- ctx.fillStyle = POOL_NAME_COLOR;
50
- ctx.font = `600 ${POOL_NAME_FONT_SIZE}px ${POOL_FONT_FAMILY}`;
51
- ctx.textAlign = 'center';
52
- ctx.textBaseline = 'middle';
53
- ctx.fillText(model.name, 0, 0);
54
- ctx.restore();
55
- }
56
- };
57
- export const BpmnPoolRendererExtension = ElementRendererExtension('bpmnPool', bpmnPool);
15
+ export const bpmnPool = createFrameworkBackgroundRenderer(BPMN_POOL_BACKGROUND);
16
+ export const BpmnPoolRendererExtension = ElementRendererExtension(BPMN_POOL_BACKGROUND.type, bpmnPool);