@formicoidea/labre-framework-wardley 0.31.0 → 0.32.0
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/dist/actions.d.ts +14 -18
- package/dist/actions.js +79 -38
- package/dist/audit-criteria.d.ts +31 -0
- package/dist/audit-criteria.js +90 -0
- package/dist/background.d.ts +14 -0
- package/dist/background.js +338 -0
- package/dist/commands.d.ts +5 -0
- package/dist/commands.js +190 -0
- package/dist/consts.d.ts +10 -4
- package/dist/consts.js +10 -9
- package/dist/descriptor.d.ts +8 -3
- package/dist/descriptor.js +6 -3
- package/dist/element-renderer.d.ts +8 -5
- package/dist/element-renderer.js +12 -147
- package/dist/element-view.d.ts +8 -4
- package/dist/element-view.js +30 -22
- package/dist/gradient.d.ts +6 -11
- package/dist/gradient.js +58 -47
- package/dist/index.d.ts +9 -1
- package/dist/index.js +9 -1
- package/dist/legend.js +8 -0
- package/dist/natures.d.ts +50 -0
- package/dist/natures.js +93 -0
- package/dist/nudges.d.ts +41 -0
- package/dist/nudges.js +69 -0
- package/dist/profiles.d.ts +2 -0
- package/dist/profiles.js +87 -0
- package/dist/reading.d.ts +3 -0
- package/dist/reading.js +129 -0
- package/dist/roles.d.ts +50 -0
- package/dist/roles.js +132 -0
- package/dist/rules.d.ts +2 -0
- package/dist/rules.js +270 -0
- package/dist/templates/index.js +51 -7
- package/dist/templates/maps.js +121 -17
- package/dist/toolbar/wardley-menu.d.ts +8 -15
- package/dist/toolbar/wardley-menu.js +8 -136
- package/dist/translations.d.ts +16 -0
- package/dist/translations.js +24 -0
- package/dist/view.d.ts +17 -0
- package/dist/view.js +116 -13
- package/package.json +2 -2
- package/dist/label-layout.d.ts +0 -20
- package/dist/label-layout.js +0 -72
- package/dist/shortcuts.d.ts +0 -2
- package/dist/shortcuts.js +0 -37
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import { ARROW, AXIS_LABELS, CARD_RADIUS, COLORS, FONT_FAMILY, FONTS, LINE, MARGIN, OFFSETS, PHASE_LABELS, REF_WIDTH, } from './consts.js';
|
|
2
|
+
import { WARDLEY_WASHES } from './gradient.js';
|
|
3
|
+
import { WARDLEY_RED } from './node/consts.js';
|
|
4
|
+
import { WARDLEY_ROLE } from './roles.js';
|
|
5
|
+
/**
|
|
6
|
+
* The Wardley map background, DECLARED (PF2.12).
|
|
7
|
+
*
|
|
8
|
+
* This file is the whole of what makes a Wardley background look like a Wardley
|
|
9
|
+
* background. There is no Wardley rendering code left: the primitive
|
|
10
|
+
* (`FrameworkBackgroundDef` / `createFrameworkBackgroundRenderer` in
|
|
11
|
+
* `@labre/affine-block-surface`) paints this declaration, and would paint any
|
|
12
|
+
* other framework's the same way.
|
|
13
|
+
*
|
|
14
|
+
* Nothing here changes the DOCUMENT. The persisted element type is still
|
|
15
|
+
* `wardley` and its props are untouched — `variant`, `banded`, the ten label
|
|
16
|
+
* texts, the six visibility toggles — they are simply named by the declaration
|
|
17
|
+
* instead of being read by hand-written drawing code. A map authored before
|
|
18
|
+
* this file existed opens with the same geometry, the same zones and the same
|
|
19
|
+
* words.
|
|
20
|
+
*
|
|
21
|
+
* ## i18n
|
|
22
|
+
*
|
|
23
|
+
* Every label declares BOTH a `labelKey` (the vocabulary, for a host that ships
|
|
24
|
+
* a locale) and a `prop` (the user's own text, which always wins).
|
|
25
|
+
*
|
|
26
|
+
* For the key to be REACHABLE the prop has to be able to be absent, so the ten
|
|
27
|
+
* label fields on `WardleyBackgroundElementModel` default to `undefined`: an
|
|
28
|
+
* `undefined` default is written nowhere (see `field.ts`), so a map the user
|
|
29
|
+
* has never renamed carries no label key at all and falls through to the
|
|
30
|
+
* vocabulary. The moment the user edits a label in place, the prop is written
|
|
31
|
+
* and wins forever after — which is exactly the old behaviour, arrived at from
|
|
32
|
+
* the other side.
|
|
33
|
+
*
|
|
34
|
+
* A map authored before this change carries all ten props with their English
|
|
35
|
+
* values and is completely unaffected.
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Green, for the benefit half of the tone convention (Q5).
|
|
39
|
+
*
|
|
40
|
+
* Declared here rather than in `node/consts.ts` because nothing DRAWS it: no
|
|
41
|
+
* Wardley artefact is created green, and the framework has no "benefit" role
|
|
42
|
+
* yet. It exists so the convention has a reference colour to be judged against
|
|
43
|
+
* — the day an artefact of that kind is created, it takes this entry, and the
|
|
44
|
+
* check-up already knows about it.
|
|
45
|
+
*
|
|
46
|
+
* Picked in the same register as {@link WARDLEY_RED}, so a map using both reads
|
|
47
|
+
* as one palette rather than as two decisions.
|
|
48
|
+
*/
|
|
49
|
+
const BENEFIT_GREEN = '#2f9e63';
|
|
50
|
+
/**
|
|
51
|
+
* The colour code: every colour below is named, never repeated as a hex.
|
|
52
|
+
*
|
|
53
|
+
* The last three entries are the **tone convention** (PF13.8 / Q5), and they are
|
|
54
|
+
* palette entries for a reason: the check-up rule names them
|
|
55
|
+
* (`ToneConventionDef.palette`) instead of restating a colour, so the convention
|
|
56
|
+
* and the map are restyled together, in one place, by whoever owns the frame.
|
|
57
|
+
* Nothing paints them — see {@link BENEFIT_GREEN} — which is exactly what a
|
|
58
|
+
* declared REFERENCE looks like.
|
|
59
|
+
*/
|
|
60
|
+
const PALETTE = {
|
|
61
|
+
card: COLORS.card,
|
|
62
|
+
cardBorder: COLORS.cardBorder,
|
|
63
|
+
axis: COLORS.axis,
|
|
64
|
+
divider: COLORS.divider,
|
|
65
|
+
label: COLORS.label,
|
|
66
|
+
band0: COLORS.band[0],
|
|
67
|
+
band1: COLORS.band[1],
|
|
68
|
+
band2: COLORS.band[2],
|
|
69
|
+
band3: COLORS.band[3],
|
|
70
|
+
/** The landscape: everything the map is MADE of, drawn in greys. */
|
|
71
|
+
landscape: COLORS.label,
|
|
72
|
+
/** Reserved for what is moving — change points, investments, costs. */
|
|
73
|
+
change: WARDLEY_RED,
|
|
74
|
+
/** Reserved for benefits and functional differences. */
|
|
75
|
+
benefit: BENEFIT_GREEN,
|
|
76
|
+
};
|
|
77
|
+
const AXIS_TEXT = { size: FONTS.axis, color: '@axis' };
|
|
78
|
+
const PHASE_TEXT = { size: FONTS.phase, color: '@label' };
|
|
79
|
+
const DIRECTION_TEXT = { size: FONTS.direction, color: '@label' };
|
|
80
|
+
const VISIBILITY_TEXT = { size: FONTS.visibility, color: '@label' };
|
|
81
|
+
/**
|
|
82
|
+
* The four evolution phases, as named zones of the plot. `banded` tints them,
|
|
83
|
+
* `showColumnLabels` names them; the dashed dividers between them are the
|
|
84
|
+
* graduations of the evolution axis, declared with it.
|
|
85
|
+
*/
|
|
86
|
+
const EVOLUTION_ZONES = [
|
|
87
|
+
{
|
|
88
|
+
id: 'genesis',
|
|
89
|
+
rect: { x: 0, y: 0, w: 0.175, h: 1 },
|
|
90
|
+
fill: '@band0',
|
|
91
|
+
fillVisibleProp: 'banded',
|
|
92
|
+
label: {
|
|
93
|
+
id: 'phase0',
|
|
94
|
+
prop: 'phase0',
|
|
95
|
+
labelKey: 'com.labre.wardley.background.phase.genesis',
|
|
96
|
+
fallback: PHASE_LABELS.genesis,
|
|
97
|
+
anchor: { x: 0, y: 1, dx: OFFSETS.phasePad, dy: OFFSETS.phaseBaseline },
|
|
98
|
+
style: PHASE_TEXT,
|
|
99
|
+
align: 'left',
|
|
100
|
+
visibleProp: 'showColumnLabels',
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
id: 'custom-built',
|
|
105
|
+
rect: { x: 0.175, y: 0, w: 0.225, h: 1 },
|
|
106
|
+
fill: '@band1',
|
|
107
|
+
fillVisibleProp: 'banded',
|
|
108
|
+
label: {
|
|
109
|
+
id: 'phase1',
|
|
110
|
+
prop: 'phase1',
|
|
111
|
+
labelKey: 'com.labre.wardley.background.phase.custom-built',
|
|
112
|
+
fallback: PHASE_LABELS.customBuilt,
|
|
113
|
+
anchor: {
|
|
114
|
+
x: 0.175,
|
|
115
|
+
y: 1,
|
|
116
|
+
dx: OFFSETS.phasePad,
|
|
117
|
+
dy: OFFSETS.phaseBaseline,
|
|
118
|
+
},
|
|
119
|
+
style: PHASE_TEXT,
|
|
120
|
+
align: 'left',
|
|
121
|
+
visibleProp: 'showColumnLabels',
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
id: 'product',
|
|
126
|
+
rect: { x: 0.4, y: 0, w: 0.3, h: 1 },
|
|
127
|
+
fill: '@band2',
|
|
128
|
+
fillVisibleProp: 'banded',
|
|
129
|
+
label: {
|
|
130
|
+
id: 'phase2',
|
|
131
|
+
prop: 'phase2',
|
|
132
|
+
labelKey: 'com.labre.wardley.background.phase.product',
|
|
133
|
+
fallback: PHASE_LABELS.product,
|
|
134
|
+
anchor: { x: 0.4, y: 1, dx: OFFSETS.phasePad, dy: OFFSETS.phaseBaseline },
|
|
135
|
+
style: PHASE_TEXT,
|
|
136
|
+
align: 'left',
|
|
137
|
+
visibleProp: 'showColumnLabels',
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
id: 'commodity',
|
|
142
|
+
rect: { x: 0.7, y: 0, w: 0.3, h: 1 },
|
|
143
|
+
fill: '@band3',
|
|
144
|
+
fillVisibleProp: 'banded',
|
|
145
|
+
label: {
|
|
146
|
+
id: 'phase3',
|
|
147
|
+
prop: 'phase3',
|
|
148
|
+
labelKey: 'com.labre.wardley.background.phase.commodity',
|
|
149
|
+
fallback: PHASE_LABELS.commodity,
|
|
150
|
+
anchor: { x: 0.7, y: 1, dx: OFFSETS.phasePad, dy: OFFSETS.phaseBaseline },
|
|
151
|
+
style: PHASE_TEXT,
|
|
152
|
+
align: 'left',
|
|
153
|
+
visibleProp: 'showColumnLabels',
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
];
|
|
157
|
+
/**
|
|
158
|
+
* The two axes. Evolution runs along the bottom with its phase dividers as
|
|
159
|
+
* graduations; Value Chain runs up the left edge. Both arrows point "forward",
|
|
160
|
+
* i.e. towards more evolved / more visible.
|
|
161
|
+
*
|
|
162
|
+
* The end labels (Uncharted / Industrialized, Visible / Invisible) carry their
|
|
163
|
+
* own visibility: naming where an axis leads has always been a separate toggle
|
|
164
|
+
* from drawing the axis, and the declaration keeps it that way.
|
|
165
|
+
*/
|
|
166
|
+
const WARDLEY_AXES = [
|
|
167
|
+
{
|
|
168
|
+
id: 'evolution',
|
|
169
|
+
orientation: 'horizontal',
|
|
170
|
+
at: 1,
|
|
171
|
+
arrow: 'forward',
|
|
172
|
+
arrowSize: ARROW,
|
|
173
|
+
stroke: { color: '@axis', width: LINE.axis },
|
|
174
|
+
visibleProp: 'showXAxis',
|
|
175
|
+
title: {
|
|
176
|
+
id: 'xAxisTitle',
|
|
177
|
+
prop: 'xAxisTitle',
|
|
178
|
+
labelKey: 'com.labre.wardley.background.axis.evolution',
|
|
179
|
+
fallback: AXIS_LABELS.xAxis,
|
|
180
|
+
anchor: {
|
|
181
|
+
x: 1,
|
|
182
|
+
y: 1,
|
|
183
|
+
dx: -OFFSETS.evolutionPadRight,
|
|
184
|
+
dy: OFFSETS.phaseBaseline,
|
|
185
|
+
},
|
|
186
|
+
style: AXIS_TEXT,
|
|
187
|
+
align: 'right',
|
|
188
|
+
},
|
|
189
|
+
endLabels: [
|
|
190
|
+
{
|
|
191
|
+
id: 'evolutionStart',
|
|
192
|
+
prop: 'evolutionStart',
|
|
193
|
+
labelKey: 'com.labre.wardley.background.evolution.start',
|
|
194
|
+
fallback: AXIS_LABELS.evolutionStart,
|
|
195
|
+
anchor: {
|
|
196
|
+
x: 0,
|
|
197
|
+
y: 0,
|
|
198
|
+
dx: OFFSETS.directionPadLeft,
|
|
199
|
+
dy: OFFSETS.directionTop,
|
|
200
|
+
},
|
|
201
|
+
style: DIRECTION_TEXT,
|
|
202
|
+
align: 'left',
|
|
203
|
+
visibleProp: 'showCornerLabels',
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
id: 'evolutionEnd',
|
|
207
|
+
prop: 'evolutionEnd',
|
|
208
|
+
labelKey: 'com.labre.wardley.background.evolution.end',
|
|
209
|
+
fallback: AXIS_LABELS.evolutionEnd,
|
|
210
|
+
anchor: {
|
|
211
|
+
x: 1,
|
|
212
|
+
y: 0,
|
|
213
|
+
dx: -OFFSETS.directionPadRight,
|
|
214
|
+
dy: OFFSETS.directionTop,
|
|
215
|
+
},
|
|
216
|
+
style: DIRECTION_TEXT,
|
|
217
|
+
align: 'right',
|
|
218
|
+
visibleProp: 'showCornerLabels',
|
|
219
|
+
},
|
|
220
|
+
],
|
|
221
|
+
ticks: {
|
|
222
|
+
ticks: [{ at: 0.175 }, { at: 0.4 }, { at: 0.7 }],
|
|
223
|
+
stroke: { color: '@divider', width: LINE.divider, dash: [5, 5] },
|
|
224
|
+
visibleProp: 'showColumnDividers',
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
id: 'value-chain',
|
|
229
|
+
orientation: 'vertical',
|
|
230
|
+
at: 0,
|
|
231
|
+
arrow: 'forward',
|
|
232
|
+
arrowSize: ARROW,
|
|
233
|
+
stroke: { color: '@axis', width: LINE.axis },
|
|
234
|
+
visibleProp: 'showYAxis',
|
|
235
|
+
title: {
|
|
236
|
+
id: 'yAxisTitle',
|
|
237
|
+
prop: 'yAxisTitle',
|
|
238
|
+
labelKey: 'com.labre.wardley.background.axis.value-chain',
|
|
239
|
+
fallback: AXIS_LABELS.yAxis,
|
|
240
|
+
anchor: { x: 0, y: 0.5, dx: -OFFSETS.yHug, dy: 0 },
|
|
241
|
+
style: AXIS_TEXT,
|
|
242
|
+
vertical: true,
|
|
243
|
+
},
|
|
244
|
+
endLabels: [
|
|
245
|
+
{
|
|
246
|
+
id: 'visibilityHigh',
|
|
247
|
+
prop: 'visibilityHigh',
|
|
248
|
+
labelKey: 'com.labre.wardley.background.visibility.high',
|
|
249
|
+
fallback: AXIS_LABELS.visibilityHigh,
|
|
250
|
+
anchor: { x: 0, y: 0, dx: -OFFSETS.yHug, dy: OFFSETS.visibleTop },
|
|
251
|
+
style: VISIBILITY_TEXT,
|
|
252
|
+
vertical: true,
|
|
253
|
+
visibleProp: 'showVisibilityLabels',
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
id: 'visibilityLow',
|
|
257
|
+
prop: 'visibilityLow',
|
|
258
|
+
labelKey: 'com.labre.wardley.background.visibility.low',
|
|
259
|
+
fallback: AXIS_LABELS.visibilityLow,
|
|
260
|
+
anchor: { x: 0, y: 1, dx: -OFFSETS.yHug, dy: -OFFSETS.invisibleBottom },
|
|
261
|
+
style: VISIBILITY_TEXT,
|
|
262
|
+
vertical: true,
|
|
263
|
+
visibleProp: 'showVisibilityLabels',
|
|
264
|
+
},
|
|
265
|
+
],
|
|
266
|
+
},
|
|
267
|
+
];
|
|
268
|
+
export const WARDLEY_BACKGROUND = {
|
|
269
|
+
type: 'wardley',
|
|
270
|
+
// The map is a first-class role: validation rules position artefacts against
|
|
271
|
+
// `wardley:map`, never against the `wardley` element type.
|
|
272
|
+
role: WARDLEY_ROLE.map,
|
|
273
|
+
variantProp: 'variant',
|
|
274
|
+
geometry: {
|
|
275
|
+
width: REF_WIDTH,
|
|
276
|
+
height: (REF_WIDTH * 9) / 16,
|
|
277
|
+
lockAspectRatio: true,
|
|
278
|
+
// A map is a frame you place things on, not a shape you nudge: the handles
|
|
279
|
+
// stay locked until the user asks for them from the toolbar.
|
|
280
|
+
resizable: false,
|
|
281
|
+
margin: MARGIN,
|
|
282
|
+
},
|
|
283
|
+
chrome: {
|
|
284
|
+
fontFamily: FONT_FAMILY,
|
|
285
|
+
palette: PALETTE,
|
|
286
|
+
surface: {
|
|
287
|
+
fill: '@card',
|
|
288
|
+
border: { color: '@cardBorder', width: LINE.card, radius: CARD_RADIUS },
|
|
289
|
+
},
|
|
290
|
+
washes: WARDLEY_WASHES,
|
|
291
|
+
},
|
|
292
|
+
zones: EVOLUTION_ZONES,
|
|
293
|
+
axes: WARDLEY_AXES,
|
|
294
|
+
/**
|
|
295
|
+
* The **zone of punctuated equilibrium**: how wide, as a ratio of the plot,
|
|
296
|
+
* the frontier between two evolution phases really is.
|
|
297
|
+
*
|
|
298
|
+
* Wardley's point is that a phase transition is not a coordinate. Things do
|
|
299
|
+
* not become products at `x = 0.4`; they resist, then move, and the inertia
|
|
300
|
+
* that resists lives AROUND the frontier. A rule asking "is this symbol at
|
|
301
|
+
* the transition" therefore measures against this band, not against the
|
|
302
|
+
* dashed line the renderer draws.
|
|
303
|
+
*
|
|
304
|
+
* `0.1` of the plot — ±5% either side of the divider — chosen on the PO
|
|
305
|
+
* recette of 01/08/2026, where two bars dropped by eye on the "Product" and
|
|
306
|
+
* "Commodity" dividers had to come out green. In model units that is ±76 on
|
|
307
|
+
* the 1600-wide reference map (against the 40 absolute units it replaces) and
|
|
308
|
+
* ±36 on an 800-wide one — the same band to the eye at every size, which is
|
|
309
|
+
* the whole reason it is a ratio. Still narrow enough to mean something: the
|
|
310
|
+
* narrowest gap between two transitions is 0.225 of the plot, so its middle
|
|
311
|
+
* stays 0.0625 of the plot clear of either band.
|
|
312
|
+
*/
|
|
313
|
+
transitionBandWidth: 0.1,
|
|
314
|
+
};
|
|
315
|
+
/**
|
|
316
|
+
* The props the in-place label editor is allowed to write.
|
|
317
|
+
*
|
|
318
|
+
* A closed list, not `string`: the hit test reports whatever `prop` a
|
|
319
|
+
* declaration names, and since #73 an element preserves keys it does not
|
|
320
|
+
* declare — so a typo in the declaration would happily persist a junk key onto
|
|
321
|
+
* every map it was double-clicked on. This is the gate between "the
|
|
322
|
+
* declaration says so" and "the document gets it".
|
|
323
|
+
*/
|
|
324
|
+
export const WARDLEY_LABEL_PROPS = [
|
|
325
|
+
'xAxisTitle',
|
|
326
|
+
'yAxisTitle',
|
|
327
|
+
'evolutionStart',
|
|
328
|
+
'evolutionEnd',
|
|
329
|
+
'visibilityHigh',
|
|
330
|
+
'visibilityLow',
|
|
331
|
+
'phase0',
|
|
332
|
+
'phase1',
|
|
333
|
+
'phase2',
|
|
334
|
+
'phase3',
|
|
335
|
+
];
|
|
336
|
+
export function isWardleyLabelProp(prop) {
|
|
337
|
+
return WARDLEY_LABEL_PROPS.includes(prop);
|
|
338
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CommandDescriptor } from '@formicoidea/labre-core/std';
|
|
2
|
+
import type { TemplateResult } from 'lit';
|
|
3
|
+
export declare const wardleyCommands: CommandDescriptor[];
|
|
4
|
+
/** `iconKey` → template. Never travels through either manifest (ADR 0008). */
|
|
5
|
+
export declare const wardleyCommandIcons: Record<string, TemplateResult>;
|
package/dist/commands.js
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { GfxControllerIdentifier } from '@formicoidea/labre-core/std/gfx';
|
|
2
|
+
import { activateWardleyConnector, createWardleyBackground, createWardleyInertia, createWardleyMarket, createWardleyNode, createWardleyPipeline, } from './actions.js';
|
|
3
|
+
import { WARDLEY_ROLE, WARDLEY_ROLES, } from './roles.js';
|
|
4
|
+
import { wardleyAnchorIcon, wardleyArrowIcon, wardleyBackgroundIcon, wardleyBenefitIcon, wardleyComponentIcon, wardleyEcosystemIcon, wardleyEvolutionGradientIcon, wardleyInertiaIcon, wardleyLinkIcon, wardleyMarketIcon, wardleyMethodIcon, wardleyOpportunityIcon, wardleyPipelineIcon, } from './toolbar/icons.js';
|
|
5
|
+
const SPECS = [
|
|
6
|
+
{
|
|
7
|
+
id: 'addBackground',
|
|
8
|
+
label: 'Wardley map background',
|
|
9
|
+
labelKey: 'com.labre.keyboardShortcuts.wardley.addBackground',
|
|
10
|
+
key: 'b',
|
|
11
|
+
iconKey: 'wardley.background',
|
|
12
|
+
category: 'backgrounds',
|
|
13
|
+
kind: 'artefact',
|
|
14
|
+
element: 'background:classic',
|
|
15
|
+
run: gfx => createWardleyBackground(gfx, 'classic'),
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: 'addOpportunityBackground',
|
|
19
|
+
label: 'Opportunity background (gradient)',
|
|
20
|
+
iconKey: 'wardley.background.opportunity',
|
|
21
|
+
category: 'backgrounds',
|
|
22
|
+
kind: 'artefact',
|
|
23
|
+
element: 'background:opportunity',
|
|
24
|
+
run: gfx => createWardleyBackground(gfx, 'opportunity'),
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: 'addBenefitBackground',
|
|
28
|
+
label: 'Benefit / Investment background (gradient)',
|
|
29
|
+
iconKey: 'wardley.background.benefit',
|
|
30
|
+
category: 'backgrounds',
|
|
31
|
+
kind: 'artefact',
|
|
32
|
+
element: 'background:benefit',
|
|
33
|
+
run: gfx => createWardleyBackground(gfx, 'benefit'),
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: 'addEvolutionBackground',
|
|
37
|
+
label: 'Evolution background (Wardley presentation)',
|
|
38
|
+
iconKey: 'wardley.background.evolution',
|
|
39
|
+
category: 'backgrounds',
|
|
40
|
+
kind: 'artefact',
|
|
41
|
+
element: 'background:evolution-gradient',
|
|
42
|
+
run: gfx => createWardleyBackground(gfx, 'evolution-gradient'),
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: 'addComponent',
|
|
46
|
+
label: 'Component',
|
|
47
|
+
labelKey: 'com.labre.keyboardShortcuts.wardley.addComponent',
|
|
48
|
+
key: 'c',
|
|
49
|
+
iconKey: 'wardley.component',
|
|
50
|
+
category: 'nodes',
|
|
51
|
+
kind: 'artefact',
|
|
52
|
+
element: 'node:component',
|
|
53
|
+
run: gfx => createWardleyNode(gfx, 'component'),
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: 'addMethod',
|
|
57
|
+
label: 'Component + method',
|
|
58
|
+
labelKey: 'com.labre.keyboardShortcuts.wardley.addMethod',
|
|
59
|
+
key: 'm',
|
|
60
|
+
iconKey: 'wardley.method',
|
|
61
|
+
category: 'nodes',
|
|
62
|
+
kind: 'artefact',
|
|
63
|
+
element: 'node:method',
|
|
64
|
+
run: gfx => createWardleyNode(gfx, 'method'),
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: 'addMarket',
|
|
68
|
+
label: 'Market',
|
|
69
|
+
iconKey: 'wardley.market',
|
|
70
|
+
category: 'nodes',
|
|
71
|
+
kind: 'artefact',
|
|
72
|
+
element: 'node:market',
|
|
73
|
+
run: createWardleyMarket,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: 'addEcosystem',
|
|
77
|
+
label: 'Ecosystem',
|
|
78
|
+
iconKey: 'wardley.ecosystem',
|
|
79
|
+
category: 'nodes',
|
|
80
|
+
kind: 'artefact',
|
|
81
|
+
element: 'node:ecosystem',
|
|
82
|
+
run: gfx => createWardleyNode(gfx, 'ecosystem'),
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: 'addAnchor',
|
|
86
|
+
label: 'Anchor',
|
|
87
|
+
iconKey: 'wardley.anchor',
|
|
88
|
+
category: 'nodes',
|
|
89
|
+
kind: 'artefact',
|
|
90
|
+
element: 'node:anchor',
|
|
91
|
+
run: gfx => createWardleyNode(gfx, 'anchor'),
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: 'addPipeline',
|
|
95
|
+
label: 'Pipeline',
|
|
96
|
+
labelKey: 'com.labre.keyboardShortcuts.wardley.addPipeline',
|
|
97
|
+
key: 'p',
|
|
98
|
+
iconKey: 'wardley.pipeline',
|
|
99
|
+
category: 'nodes',
|
|
100
|
+
kind: 'artefact',
|
|
101
|
+
element: 'node:pipeline',
|
|
102
|
+
run: createWardleyPipeline,
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: 'linkTool',
|
|
106
|
+
label: 'Link',
|
|
107
|
+
labelKey: 'com.labre.keyboardShortcuts.wardley.linkTool',
|
|
108
|
+
key: 'l',
|
|
109
|
+
iconKey: 'wardley.link',
|
|
110
|
+
category: 'connectors',
|
|
111
|
+
kind: 'tool',
|
|
112
|
+
element: 'connector:link',
|
|
113
|
+
edgeRole: WARDLEY_ROLE.dependency,
|
|
114
|
+
run: gfx => activateWardleyConnector(gfx, 'link'),
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
id: 'evolutionArrow',
|
|
118
|
+
label: 'Arrow (evolution)',
|
|
119
|
+
labelKey: 'com.labre.keyboardShortcuts.wardley.evolutionArrow',
|
|
120
|
+
key: 'a',
|
|
121
|
+
iconKey: 'wardley.arrow',
|
|
122
|
+
category: 'connectors',
|
|
123
|
+
kind: 'tool',
|
|
124
|
+
element: 'connector:arrow',
|
|
125
|
+
edgeRole: WARDLEY_ROLE.changeArrow,
|
|
126
|
+
run: gfx => activateWardleyConnector(gfx, 'arrow'),
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
id: 'addInertia',
|
|
130
|
+
label: 'Inertia',
|
|
131
|
+
labelKey: 'com.labre.keyboardShortcuts.wardley.addInertia',
|
|
132
|
+
key: 'i',
|
|
133
|
+
iconKey: 'wardley.inertia',
|
|
134
|
+
category: 'nodes',
|
|
135
|
+
kind: 'artefact',
|
|
136
|
+
element: 'node:inertia',
|
|
137
|
+
run: createWardleyInertia,
|
|
138
|
+
},
|
|
139
|
+
];
|
|
140
|
+
/**
|
|
141
|
+
* The sentence a tool shows under its label — the role's own gesture hint
|
|
142
|
+
* (M1 of `docs/adr/0010`), or nothing at all for a tool that draws no typed
|
|
143
|
+
* edge. Read off the vocabulary rather than written here twice.
|
|
144
|
+
*/
|
|
145
|
+
function gestureOf(spec) {
|
|
146
|
+
const direction = spec.edgeRole === undefined
|
|
147
|
+
? undefined
|
|
148
|
+
: WARDLEY_ROLES[spec.edgeRole]?.direction;
|
|
149
|
+
if (!direction?.gestureHintKey)
|
|
150
|
+
return {};
|
|
151
|
+
return {
|
|
152
|
+
descriptionKey: direction.gestureHintKey,
|
|
153
|
+
descriptionFallback: direction.gestureHintFallback,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
export const wardleyCommands = SPECS.map((spec, order) => ({
|
|
157
|
+
id: `wardley.${spec.id}`,
|
|
158
|
+
owner: 'wardley',
|
|
159
|
+
kind: spec.kind,
|
|
160
|
+
labelKey: spec.labelKey ?? `com.labre.commands.wardley.${spec.id}`,
|
|
161
|
+
labelFallback: spec.label,
|
|
162
|
+
...gestureOf(spec),
|
|
163
|
+
category: spec.category,
|
|
164
|
+
iconKey: spec.iconKey,
|
|
165
|
+
surfaces: ['senior-menu', 'catalogue', 'palette', 'agent'],
|
|
166
|
+
order,
|
|
167
|
+
scope: 'edgeless',
|
|
168
|
+
defaultKeys: spec.key
|
|
169
|
+
? { mac: ['w', spec.key], other: ['w', spec.key] }
|
|
170
|
+
: { mac: [], other: [] },
|
|
171
|
+
availability: 'always',
|
|
172
|
+
run: std => spec.run(std.get(GfxControllerIdentifier)),
|
|
173
|
+
telemetry: { framework: 'wardley', element: spec.element },
|
|
174
|
+
}));
|
|
175
|
+
/** `iconKey` → template. Never travels through either manifest (ADR 0008). */
|
|
176
|
+
export const wardleyCommandIcons = {
|
|
177
|
+
'wardley.background': wardleyBackgroundIcon,
|
|
178
|
+
'wardley.background.opportunity': wardleyOpportunityIcon,
|
|
179
|
+
'wardley.background.benefit': wardleyBenefitIcon,
|
|
180
|
+
'wardley.background.evolution': wardleyEvolutionGradientIcon,
|
|
181
|
+
'wardley.component': wardleyComponentIcon,
|
|
182
|
+
'wardley.method': wardleyMethodIcon,
|
|
183
|
+
'wardley.market': wardleyMarketIcon,
|
|
184
|
+
'wardley.ecosystem': wardleyEcosystemIcon,
|
|
185
|
+
'wardley.anchor': wardleyAnchorIcon,
|
|
186
|
+
'wardley.pipeline': wardleyPipelineIcon,
|
|
187
|
+
'wardley.link': wardleyLinkIcon,
|
|
188
|
+
'wardley.arrow': wardleyArrowIcon,
|
|
189
|
+
'wardley.inertia': wardleyInertiaIcon,
|
|
190
|
+
};
|
package/dist/consts.d.ts
CHANGED
|
@@ -47,10 +47,16 @@ export declare const LINE: {
|
|
|
47
47
|
};
|
|
48
48
|
export declare const ARROW = 11;
|
|
49
49
|
export declare const CARD_RADIUS = 10;
|
|
50
|
-
/**
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Default phase wording. The zone RATIOS live in `./background.ts`, with the
|
|
52
|
+
* zones they delimit — the declaration is the single source of the map's shape.
|
|
53
|
+
*/
|
|
54
|
+
export declare const PHASE_LABELS: {
|
|
55
|
+
genesis: string;
|
|
56
|
+
customBuilt: string;
|
|
57
|
+
product: string;
|
|
58
|
+
commodity: string;
|
|
59
|
+
};
|
|
54
60
|
export declare const AXIS_LABELS: {
|
|
55
61
|
xAxis: string;
|
|
56
62
|
yAxis: string;
|
package/dist/consts.js
CHANGED
|
@@ -33,15 +33,16 @@ export const OFFSETS = {
|
|
|
33
33
|
export const LINE = { axis: 2, divider: 1.2, card: 1.5 };
|
|
34
34
|
export const ARROW = 11;
|
|
35
35
|
export const CARD_RADIUS = 10;
|
|
36
|
-
/**
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Default phase wording. The zone RATIOS live in `./background.ts`, with the
|
|
38
|
+
* zones they delimit — the declaration is the single source of the map's shape.
|
|
39
|
+
*/
|
|
40
|
+
export const PHASE_LABELS = {
|
|
41
|
+
genesis: 'Genesis',
|
|
42
|
+
customBuilt: 'Custom-Built',
|
|
43
|
+
product: 'Product (+Rental)',
|
|
44
|
+
commodity: 'Commodity (+Utility)',
|
|
45
|
+
};
|
|
45
46
|
export const AXIS_LABELS = {
|
|
46
47
|
xAxis: 'Evolution',
|
|
47
48
|
yAxis: 'Value Chain',
|
package/dist/descriptor.d.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import { WardleyViewExtension } from './view.js';
|
|
1
|
+
import { WardleyRenderViewExtension, WardleyViewExtension } from './view.js';
|
|
2
2
|
/** Host wiring for the wardley framework. */
|
|
3
3
|
export declare const wardleyFramework: {
|
|
4
4
|
readonly flag: "wardley";
|
|
5
|
-
readonly
|
|
6
|
-
readonly
|
|
5
|
+
readonly telemetryKey: "wardley";
|
|
6
|
+
readonly extensions: readonly [{
|
|
7
|
+
readonly viewExtension: typeof WardleyRenderViewExtension;
|
|
8
|
+
}, {
|
|
9
|
+
readonly flag: "wardley";
|
|
10
|
+
readonly viewExtension: typeof WardleyViewExtension;
|
|
11
|
+
}];
|
|
7
12
|
};
|
package/dist/descriptor.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { WardleyViewExtension } from './view.js';
|
|
1
|
+
import { WardleyRenderViewExtension, WardleyViewExtension } from './view.js';
|
|
2
2
|
/** Host wiring for the wardley framework. */
|
|
3
3
|
export const wardleyFramework = {
|
|
4
4
|
flag: 'wardley',
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
telemetryKey: 'wardley',
|
|
6
|
+
extensions: [
|
|
7
|
+
{ viewExtension: WardleyRenderViewExtension },
|
|
8
|
+
{ flag: 'wardley', viewExtension: WardleyViewExtension },
|
|
9
|
+
],
|
|
7
10
|
};
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { type ElementRenderer } from '@formicoidea/labre-core/blocks/surface';
|
|
2
2
|
import type { WardleyBackgroundElementModel } from '@formicoidea/labre-core/model';
|
|
3
3
|
/**
|
|
4
|
-
* Canvas renderer for the Wardley map background
|
|
5
|
-
* an L-shaped axes frame (no top/right border), dashed evolution dividers and
|
|
6
|
-
* the symmetric axis labels.
|
|
4
|
+
* Canvas renderer for the Wardley map background.
|
|
7
5
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* There is no Wardley drawing code any more (PF2.12): the map is an
|
|
7
|
+
* INSTANTIATION of the framework-background primitive, configured by the
|
|
8
|
+
* `WARDLEY_BACKGROUND` declaration. What used to be two hundred lines of
|
|
9
|
+
* `ctx.fillText` is now a declaration any other framework can write for itself.
|
|
10
|
+
*
|
|
11
|
+
* Exported as a function as well as an extension because the non-regression
|
|
12
|
+
* suite drives it directly with a canvas stub.
|
|
10
13
|
*/
|
|
11
14
|
export declare const wardley: ElementRenderer<WardleyBackgroundElementModel>;
|
|
12
15
|
export declare const WardleyElementRendererExtension: import("@formicoidea/labre-core/store").ExtensionType & {
|