@formicoidea/labre-framework-cynefin 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.
- package/dist/actions.js +8 -0
- package/dist/commands-manifest.d.ts +18 -0
- package/dist/commands-manifest.js +42 -0
- package/dist/cynefin/consts.js +49 -13
- package/dist/cynefin/element-renderer.js +4 -1
- package/dist/cynefin/toolbar/config.d.ts +5 -1
- package/dist/cynefin/toolbar/config.js +57 -7
- package/dist/estuarine/consts.d.ts +10 -3
- package/dist/estuarine/consts.js +41 -8
- package/dist/estuarine/element-renderer.d.ts +108 -2
- package/dist/estuarine/element-renderer.js +146 -43
- package/dist/estuarine/ghost-overlay.d.ts +134 -0
- package/dist/estuarine/ghost-overlay.js +277 -0
- package/dist/estuarine/nudges.d.ts +41 -0
- package/dist/estuarine/nudges.js +69 -0
- package/dist/estuarine/roles.d.ts +48 -0
- package/dist/estuarine/roles.js +28 -0
- package/dist/estuarine/toolbar/config.d.ts +6 -1
- package/dist/estuarine/toolbar/config.js +67 -8
- package/dist/templates/index.js +18 -2
- package/dist/toolbar/senior-button.js +4 -1
- package/dist/toolbar/senior-tool.js +1 -0
- package/dist/translations.d.ts +5 -0
- package/dist/translations.js +15 -2
- package/dist/view.js +49 -1
- package/package.json +7 -2
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { QualityNudge } from '@formicoidea/labre-core/blocks/surface';
|
|
2
|
+
/**
|
|
3
|
+
* Estuarine **map quality** — the checklist, and this framework's ENTIRE
|
|
4
|
+
* contribution to validation (WS4).
|
|
5
|
+
*
|
|
6
|
+
* ## No rules, and therefore no profiles (PO arbitration, 26/08/2026)
|
|
7
|
+
*
|
|
8
|
+
* The 26/08 study looked for deterministic rules on an Estuarine map and found
|
|
9
|
+
* none worth shipping. Everything an Estuarine session decides — where the
|
|
10
|
+
* counter-factual line falls, which constraints are volatile, whether a
|
|
11
|
+
* constraint is a constructor or an actor — is a judgement the group makes out
|
|
12
|
+
* loud; an algorithm that claimed to check any of it would be lying about the
|
|
13
|
+
* one thing the method exists to produce.
|
|
14
|
+
*
|
|
15
|
+
* A severity profile is a dial over rules. With no rule to dial, a profile
|
|
16
|
+
* picker is a control that decides nothing: three entries, no observable
|
|
17
|
+
* effect, and a user reasonably concluding that the tool checks something it
|
|
18
|
+
* does not. So this framework ships **no `profiles.ts`** — deliberately, not
|
|
19
|
+
* by omission. The profiles will be born WITH the first rule, if one is ever
|
|
20
|
+
* born; until then the file's absence is the honest statement.
|
|
21
|
+
*
|
|
22
|
+
* What does reach the user is this checklist, offered on the map because
|
|
23
|
+
* `ValidationFrameworkExtension` declares `estuarine:map` a root instance
|
|
24
|
+
* (WS0.3) — the gate no longer needs a rule to exist.
|
|
25
|
+
*
|
|
26
|
+
* Registered from the flag-gated `CynefinEstuarineViewExtension`, beside the
|
|
27
|
+
* framework declaration: a checklist is tooling. Switching the flag off takes
|
|
28
|
+
* it away and leaves the ticks written on the map, unread, until it comes back.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* **Q1–Q4** — the four things an Estuarine map needs in order to do its job,
|
|
32
|
+
* and that no algorithm can check.
|
|
33
|
+
*
|
|
34
|
+
* Q1 and Q2 are about the two lines that make the map a map: a counter-factual
|
|
35
|
+
* line nobody argued over is a curve, not a boundary, and an undelimited
|
|
36
|
+
* volatile zone leaves every constraint equally urgent. Q3 is the method's own
|
|
37
|
+
* discipline — above the counter-factual line you do not act, you Monitor,
|
|
38
|
+
* Research or Request. Q4 is the typing the hexagons carry in the group's head
|
|
39
|
+
* and nowhere in the document.
|
|
40
|
+
*/
|
|
41
|
+
export declare const ESTUARINE_NUDGES: readonly QualityNudge[];
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Estuarine **map quality** — the checklist, and this framework's ENTIRE
|
|
3
|
+
* contribution to validation (WS4).
|
|
4
|
+
*
|
|
5
|
+
* ## No rules, and therefore no profiles (PO arbitration, 26/08/2026)
|
|
6
|
+
*
|
|
7
|
+
* The 26/08 study looked for deterministic rules on an Estuarine map and found
|
|
8
|
+
* none worth shipping. Everything an Estuarine session decides — where the
|
|
9
|
+
* counter-factual line falls, which constraints are volatile, whether a
|
|
10
|
+
* constraint is a constructor or an actor — is a judgement the group makes out
|
|
11
|
+
* loud; an algorithm that claimed to check any of it would be lying about the
|
|
12
|
+
* one thing the method exists to produce.
|
|
13
|
+
*
|
|
14
|
+
* A severity profile is a dial over rules. With no rule to dial, a profile
|
|
15
|
+
* picker is a control that decides nothing: three entries, no observable
|
|
16
|
+
* effect, and a user reasonably concluding that the tool checks something it
|
|
17
|
+
* does not. So this framework ships **no `profiles.ts`** — deliberately, not
|
|
18
|
+
* by omission. The profiles will be born WITH the first rule, if one is ever
|
|
19
|
+
* born; until then the file's absence is the honest statement.
|
|
20
|
+
*
|
|
21
|
+
* What does reach the user is this checklist, offered on the map because
|
|
22
|
+
* `ValidationFrameworkExtension` declares `estuarine:map` a root instance
|
|
23
|
+
* (WS0.3) — the gate no longer needs a rule to exist.
|
|
24
|
+
*
|
|
25
|
+
* Registered from the flag-gated `CynefinEstuarineViewExtension`, beside the
|
|
26
|
+
* framework declaration: a checklist is tooling. Switching the flag off takes
|
|
27
|
+
* it away and leaves the ticks written on the map, unread, until it comes back.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* **Q1–Q4** — the four things an Estuarine map needs in order to do its job,
|
|
31
|
+
* and that no algorithm can check.
|
|
32
|
+
*
|
|
33
|
+
* Q1 and Q2 are about the two lines that make the map a map: a counter-factual
|
|
34
|
+
* line nobody argued over is a curve, not a boundary, and an undelimited
|
|
35
|
+
* volatile zone leaves every constraint equally urgent. Q3 is the method's own
|
|
36
|
+
* discipline — above the counter-factual line you do not act, you Monitor,
|
|
37
|
+
* Research or Request. Q4 is the typing the hexagons carry in the group's head
|
|
38
|
+
* and nowhere in the document.
|
|
39
|
+
*/
|
|
40
|
+
export const ESTUARINE_NUDGES = [
|
|
41
|
+
{
|
|
42
|
+
id: 'estuarine.q1-counterfactual',
|
|
43
|
+
framework: 'estuarine',
|
|
44
|
+
labelKey: 'com.labre.estuarine.quality.counterfactual',
|
|
45
|
+
fallback: 'The counter-factual line has been negotiated and drawn by the group',
|
|
46
|
+
order: 1,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 'estuarine.q2-volatile-zone',
|
|
50
|
+
framework: 'estuarine',
|
|
51
|
+
labelKey: 'com.labre.estuarine.quality.volatile-zone',
|
|
52
|
+
fallback: 'The volatile zone has been delimited',
|
|
53
|
+
order: 2,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: 'estuarine.q3-strategies',
|
|
57
|
+
framework: 'estuarine',
|
|
58
|
+
labelKey: 'com.labre.estuarine.quality.strategies',
|
|
59
|
+
fallback: 'Every element above the counter-factual line has a Monitor, Research or Request strategy',
|
|
60
|
+
order: 3,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: 'estuarine.q4-hexagon-types',
|
|
64
|
+
framework: 'estuarine',
|
|
65
|
+
labelKey: 'com.labre.estuarine.quality.hexagon-types',
|
|
66
|
+
fallback: 'Every hexagon is typed: constraint, constructor or actor',
|
|
67
|
+
order: 4,
|
|
68
|
+
},
|
|
69
|
+
];
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { RoleDefs } from '@formicoidea/labre-core/std/gfx';
|
|
2
|
+
/**
|
|
3
|
+
* Estuarine role vocabulary (WS4).
|
|
4
|
+
*
|
|
5
|
+
* Two roles, and deliberately only two: the MAP — the axes and the three
|
|
6
|
+
* reference curves an Estuarine session is read against — and the CONSTRAINT
|
|
7
|
+
* hexagon the group drops onto it. Everything else on such a board (the
|
|
8
|
+
* captions, the stickies, a free arrow drawn to link two hexagons) is a plain
|
|
9
|
+
* drawing and stays neutral, because nothing in this framework has anything to
|
|
10
|
+
* say about it.
|
|
11
|
+
*
|
|
12
|
+
* ## Cynefin declares NO role, and never will
|
|
13
|
+
*
|
|
14
|
+
* The two frameworks share this package and share nothing else here. The PO's
|
|
15
|
+
* arbitration of 26/08/2026 is that Cynefin is out of the validation perimeter
|
|
16
|
+
* for good: its four domains are a sense-making device, not a notation with
|
|
17
|
+
* rules, so giving its background a role would advertise tooling — a profile
|
|
18
|
+
* picker, a quality checklist — over a framework that has nothing to check.
|
|
19
|
+
* A role with no consumer is a promise the product does not keep.
|
|
20
|
+
*
|
|
21
|
+
* ## What a role buys Estuarine, which ships no rule either
|
|
22
|
+
*
|
|
23
|
+
* The map role is what makes the map a ROOT INSTANCE: it is handed to
|
|
24
|
+
* `ValidationFrameworkExtension` so the engine can answer "is this element
|
|
25
|
+
* somebody's frame?" and offer the Map quality checklist on it. That gate used
|
|
26
|
+
* to be derived from the registered rules alone, which is exactly why WS0.3
|
|
27
|
+
* gave it a second, explicit source — see `ValidationFrameworkDef`.
|
|
28
|
+
*
|
|
29
|
+
* The constraint role earns its keep on its own: a hexagon is a plain polygon
|
|
30
|
+
* shape on the canvas, so nothing about its geometry says what it means, and
|
|
31
|
+
* the first rule this framework ever writes will be written against this role
|
|
32
|
+
* rather than against `shapeType === 'polygon'`.
|
|
33
|
+
*
|
|
34
|
+
* ## Compatibility
|
|
35
|
+
*
|
|
36
|
+
* No backfill (promise #71): maps and hexagons drawn before today carry no
|
|
37
|
+
* role, are nobody's frame, and go on painting exactly as they did. They simply
|
|
38
|
+
* offer no checklist until they are redrawn.
|
|
39
|
+
*/
|
|
40
|
+
/** Every role this framework declares. */
|
|
41
|
+
export type EstuarineRole = 'map' | 'constraint';
|
|
42
|
+
export type EstuarineRoleId = `estuarine:${EstuarineRole}`;
|
|
43
|
+
/** Role ids, keyed by the name used at the creation sites. */
|
|
44
|
+
export declare const ESTUARINE_ROLE: {
|
|
45
|
+
readonly map: "estuarine:map";
|
|
46
|
+
readonly constraint: "estuarine:constraint";
|
|
47
|
+
};
|
|
48
|
+
export declare const ESTUARINE_ROLES: RoleDefs;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Role ids, keyed by the name used at the creation sites. */
|
|
2
|
+
export const ESTUARINE_ROLE = {
|
|
3
|
+
map: 'estuarine:map',
|
|
4
|
+
constraint: 'estuarine:constraint',
|
|
5
|
+
};
|
|
6
|
+
const DEFS = [
|
|
7
|
+
// The map itself: the e / t axes and the three curves everything else is
|
|
8
|
+
// positioned against. A frame, so it specialises nothing — a rule written on
|
|
9
|
+
// `estuarine:constraint` must never match the map it is measured against.
|
|
10
|
+
{
|
|
11
|
+
id: ESTUARINE_ROLE.map,
|
|
12
|
+
kind: 'node',
|
|
13
|
+
labelKey: 'com.labre.estuarine.role.map',
|
|
14
|
+
labelFallback: 'Estuarine map',
|
|
15
|
+
},
|
|
16
|
+
// The hexi constraint. A `node`: it is measured by its bounds, which is
|
|
17
|
+
// exactly what an Estuarine reading is about — where on the energy/time
|
|
18
|
+
// plane the group placed this constraint.
|
|
19
|
+
{
|
|
20
|
+
id: ESTUARINE_ROLE.constraint,
|
|
21
|
+
kind: 'node',
|
|
22
|
+
labelKey: 'com.labre.estuarine.role.constraint',
|
|
23
|
+
labelFallback: 'Constraint',
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
// Null prototype: a lookup table keyed by ids that may one day come from
|
|
27
|
+
// host-supplied packs, so `defs['toString']` must not resolve.
|
|
28
|
+
export const ESTUARINE_ROLES = Object.assign(Object.create(null), Object.fromEntries(DEFS.map(def => [def.id, def])));
|
|
@@ -1,33 +1,38 @@
|
|
|
1
|
-
import { type ToolbarContext } from '@formicoidea/labre-core/shared/services';
|
|
1
|
+
import { type ChromeWording, type ToolbarContext } from '@formicoidea/labre-core/shared/services';
|
|
2
2
|
import { type TemplateResult } from 'lit';
|
|
3
3
|
export declare const estuarineToolbarConfig: {
|
|
4
4
|
readonly actions: [{
|
|
5
5
|
id: string;
|
|
6
6
|
tooltip: string;
|
|
7
|
+
tooltipWording: ChromeWording | undefined;
|
|
7
8
|
icon: TemplateResult;
|
|
8
9
|
active(ctx: ToolbarContext): boolean;
|
|
9
10
|
run(ctx: ToolbarContext): void;
|
|
10
11
|
}, {
|
|
11
12
|
id: string;
|
|
12
13
|
tooltip: string;
|
|
14
|
+
tooltipWording: ChromeWording | undefined;
|
|
13
15
|
icon: TemplateResult;
|
|
14
16
|
active(ctx: ToolbarContext): boolean;
|
|
15
17
|
run(ctx: ToolbarContext): void;
|
|
16
18
|
}, {
|
|
17
19
|
id: string;
|
|
18
20
|
tooltip: string;
|
|
21
|
+
tooltipWording: ChromeWording | undefined;
|
|
19
22
|
icon: TemplateResult;
|
|
20
23
|
active(ctx: ToolbarContext): boolean;
|
|
21
24
|
run(ctx: ToolbarContext): void;
|
|
22
25
|
}, {
|
|
23
26
|
id: string;
|
|
24
27
|
tooltip: string;
|
|
28
|
+
tooltipWording: ChromeWording | undefined;
|
|
25
29
|
icon: TemplateResult;
|
|
26
30
|
active(ctx: ToolbarContext): boolean;
|
|
27
31
|
run(ctx: ToolbarContext): void;
|
|
28
32
|
}, {
|
|
29
33
|
id: string;
|
|
30
34
|
tooltip: string;
|
|
35
|
+
tooltipWording: ChromeWording | undefined;
|
|
31
36
|
icon: TemplateResult;
|
|
32
37
|
active(ctx: ToolbarContext): boolean;
|
|
33
38
|
run(ctx: ToolbarContext): void;
|
|
@@ -1,19 +1,78 @@
|
|
|
1
1
|
import { EdgelessCRUDIdentifier } from '@formicoidea/labre-core/blocks/surface';
|
|
2
2
|
import { EstuarineElementModel } from '@formicoidea/labre-core/model';
|
|
3
|
-
import { ToolbarModuleExtension, } from '@formicoidea/labre-core/shared/services';
|
|
3
|
+
import { BOARD_RESIZE_TOGGLE, ToolbarModuleExtension, } from '@formicoidea/labre-core/shared/services';
|
|
4
4
|
import { BlockFlavourIdentifier } from '@formicoidea/labre-core/std';
|
|
5
5
|
import { html } from 'lit';
|
|
6
|
-
const ResizeIcon = html `<svg
|
|
6
|
+
const ResizeIcon = html `<svg
|
|
7
|
+
width="24"
|
|
8
|
+
height="24"
|
|
9
|
+
viewBox="0 0 24 24"
|
|
10
|
+
fill="none"
|
|
11
|
+
stroke="currentColor"
|
|
12
|
+
stroke-width="1.6"
|
|
13
|
+
stroke-linecap="round"
|
|
14
|
+
stroke-linejoin="round"
|
|
15
|
+
>
|
|
16
|
+
<path d="M9 5H5v4M15 19h4v-4" />
|
|
17
|
+
<path d="M5 5l6 6M19 19l-6-6" />
|
|
18
|
+
</svg>`;
|
|
7
19
|
// All curve icons use currentColor so the toolbar can grey them when inactive;
|
|
8
20
|
// they are distinguished by shape (wave / arc / hooked curve).
|
|
9
|
-
const LiminalIcon = html `<svg
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
21
|
+
const LiminalIcon = html `<svg
|
|
22
|
+
width="24"
|
|
23
|
+
height="24"
|
|
24
|
+
viewBox="0 0 24 24"
|
|
25
|
+
fill="none"
|
|
26
|
+
stroke="currentColor"
|
|
27
|
+
stroke-width="2"
|
|
28
|
+
stroke-linecap="round"
|
|
29
|
+
>
|
|
30
|
+
<path d="M3 13c3-6 6 4 9 0s6-6 9 0" />
|
|
31
|
+
</svg>`;
|
|
32
|
+
const VolatileIcon = html `<svg
|
|
33
|
+
width="24"
|
|
34
|
+
height="24"
|
|
35
|
+
viewBox="0 0 24 24"
|
|
36
|
+
fill="none"
|
|
37
|
+
stroke="currentColor"
|
|
38
|
+
stroke-width="2"
|
|
39
|
+
stroke-linecap="round"
|
|
40
|
+
>
|
|
41
|
+
<path d="M7 4a9 9 0 0 1 0 18" />
|
|
42
|
+
</svg>`;
|
|
43
|
+
const CounterfactualIcon = html `<svg
|
|
44
|
+
width="24"
|
|
45
|
+
height="24"
|
|
46
|
+
viewBox="0 0 24 24"
|
|
47
|
+
fill="none"
|
|
48
|
+
stroke="currentColor"
|
|
49
|
+
stroke-width="2"
|
|
50
|
+
stroke-linecap="round"
|
|
51
|
+
>
|
|
52
|
+
<path d="M4 7c7 0 11 4 12 14" />
|
|
53
|
+
</svg>`;
|
|
54
|
+
const AxisIcon = html `<svg
|
|
55
|
+
width="24"
|
|
56
|
+
height="24"
|
|
57
|
+
viewBox="0 0 24 24"
|
|
58
|
+
fill="none"
|
|
59
|
+
stroke="currentColor"
|
|
60
|
+
stroke-width="1.6"
|
|
61
|
+
stroke-linecap="round"
|
|
62
|
+
stroke-linejoin="round"
|
|
63
|
+
>
|
|
64
|
+
<path d="M6 3v18M6 12h15" />
|
|
65
|
+
<path d="M3 6l3-3 3 3M18 9l3 3-3 3" />
|
|
66
|
+
</svg>`;
|
|
13
67
|
function booleanToggle(id, tooltip, icon, prop) {
|
|
14
68
|
return {
|
|
15
69
|
id,
|
|
16
|
-
tooltip,
|
|
70
|
+
tooltip: typeof tooltip === 'string' ? tooltip : tooltip[1],
|
|
71
|
+
// The declared wording, when the caller gave one instead of a literal:
|
|
72
|
+
// `combine` resolves it against the host's catalogue and writes it over
|
|
73
|
+
// the English default above, so a playground with no catalogue reads
|
|
74
|
+
// exactly what it read before (#183).
|
|
75
|
+
tooltipWording: typeof tooltip === 'string' ? undefined : tooltip,
|
|
17
76
|
icon,
|
|
18
77
|
active(ctx) {
|
|
19
78
|
const models = ctx.getSurfaceModelsByType(EstuarineElementModel);
|
|
@@ -33,7 +92,7 @@ function booleanToggle(id, tooltip, icon, prop) {
|
|
|
33
92
|
}
|
|
34
93
|
export const estuarineToolbarConfig = {
|
|
35
94
|
actions: [
|
|
36
|
-
booleanToggle('a.toggle-resize',
|
|
95
|
+
booleanToggle('a.toggle-resize', BOARD_RESIZE_TOGGLE, ResizeIcon, 'resizeEnabled'),
|
|
37
96
|
booleanToggle('b.toggle-liminal', 'Show / hide the Liminal line', LiminalIcon, 'showLiminal'),
|
|
38
97
|
booleanToggle('c.toggle-volatile', 'Show / hide the Volatile line', VolatileIcon, 'showVolatile'),
|
|
39
98
|
booleanToggle('d.toggle-counterfactual', 'Show / hide the Counter-factual line', CounterfactualIcon, 'showCounterfactual'),
|
package/dist/templates/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { makeTemplateSnapshot, surfaceText, } from '@formicoidea/labre-core/gfx/
|
|
|
2
2
|
import { FontFamily, ShapeStyle, TextAlign } from '@formicoidea/labre-core/model';
|
|
3
3
|
import { REF_H as CYN_H, REF_W as CYN_W } from '../cynefin/consts.js';
|
|
4
4
|
import { HEX_FILL, HEX_SIZE, HEX_STROKE, HEX_VERTICES, REF_H as EST_H, REF_W as EST_W, } from '../estuarine/consts.js';
|
|
5
|
+
import { ESTUARINE_ROLE } from '../estuarine/roles.js';
|
|
5
6
|
function sticky(x, y, text) {
|
|
6
7
|
return {
|
|
7
8
|
type: 'shape',
|
|
@@ -24,6 +25,9 @@ function sticky(x, y, text) {
|
|
|
24
25
|
function hexagon(x, y) {
|
|
25
26
|
return {
|
|
26
27
|
type: 'shape',
|
|
28
|
+
// Same role the toolbox stamps (`actions.ts`): a template must produce the
|
|
29
|
+
// map a user would have drawn by hand, roles included.
|
|
30
|
+
role: ESTUARINE_ROLE.constraint,
|
|
27
31
|
shapeType: 'polygon',
|
|
28
32
|
vertices: HEX_VERTICES,
|
|
29
33
|
filled: true,
|
|
@@ -47,11 +51,23 @@ function caption(x, y, str) {
|
|
|
47
51
|
};
|
|
48
52
|
}
|
|
49
53
|
function tpl(name, preview, elements) {
|
|
50
|
-
return {
|
|
54
|
+
return {
|
|
55
|
+
name,
|
|
56
|
+
type: 'template',
|
|
57
|
+
preview,
|
|
58
|
+
content: makeTemplateSnapshot(elements, name),
|
|
59
|
+
};
|
|
51
60
|
}
|
|
52
61
|
const ATTRS = 'width="100%" height="100%" viewBox="0 0 135 80" xmlns="http://www.w3.org/2000/svg"';
|
|
62
|
+
// Cynefin's background carries NO role, deliberately and for good: the
|
|
63
|
+
// framework is out of the validation perimeter (PO, 26/08/2026). See
|
|
64
|
+
// `estuarine/roles.ts`.
|
|
53
65
|
const cynefinBg = (xywh) => ({ type: 'cynefin', xywh });
|
|
54
|
-
const estuarineBg = (xywh) => ({
|
|
66
|
+
const estuarineBg = (xywh) => ({
|
|
67
|
+
type: 'estuarine',
|
|
68
|
+
role: ESTUARINE_ROLE.map,
|
|
69
|
+
xywh,
|
|
70
|
+
});
|
|
55
71
|
export const cynefinTemplateCategory = {
|
|
56
72
|
name: 'Cynefin',
|
|
57
73
|
templates: [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DefaultTool } from '@formicoidea/labre-core/blocks/surface';
|
|
2
2
|
import { EmptyTool } from '@formicoidea/labre-core/gfx/pointer';
|
|
3
|
+
import { translateKey } from '@formicoidea/labre-core/shared/services';
|
|
3
4
|
import { EdgelessToolbarToolMixin } from '@formicoidea/labre-core/widgets/edgeless-toolbar';
|
|
4
5
|
import { SignalWatcher } from '@formicoidea/labre-core/global/lit';
|
|
5
6
|
import { css, html, LitElement } from 'lit';
|
|
@@ -64,7 +65,9 @@ export class EdgelessCynefinEstuarineSeniorButton extends EdgelessToolbarToolMix
|
|
|
64
65
|
render() {
|
|
65
66
|
return html `<edgeless-toolbar-button
|
|
66
67
|
class="ce-button"
|
|
67
|
-
.tooltip=${this.popper
|
|
68
|
+
.tooltip=${this.popper
|
|
69
|
+
? ''
|
|
70
|
+
: translateKey(this.edgeless.std, 'com.labre.framework.cynefin-estuarine', 'Cynefin / Estuarine')}
|
|
68
71
|
.tooltipOffset=${4}
|
|
69
72
|
.active=${!!this.popper}
|
|
70
73
|
@click=${this._toggleMenu}
|
|
@@ -4,6 +4,7 @@ import { html } from 'lit';
|
|
|
4
4
|
export const cynefinEstuarineSeniorTool = SeniorToolExtension('cynefin-estuarine', ({ block }) => {
|
|
5
5
|
return {
|
|
6
6
|
name: 'Cynefin / Estuarine',
|
|
7
|
+
labelKey: 'com.labre.framework.cynefin-estuarine',
|
|
7
8
|
content: html `<edgeless-cynefin-estuarine-senior-button
|
|
8
9
|
.edgeless=${block}
|
|
9
10
|
></edgeless-cynefin-estuarine-senior-button>`,
|
package/dist/translations.d.ts
CHANGED
|
@@ -2,6 +2,11 @@ import { type TranslationKeyManifestEntry } from '@formicoidea/labre-core/std';
|
|
|
2
2
|
/**
|
|
3
3
|
* THIS framework's contribution to the translation-key manifest.
|
|
4
4
|
*
|
|
5
|
+
* Since WS4 it also carries the Estuarine ROLE labels and the four Map quality
|
|
6
|
+
* NUDGES — the framework's entire validation vocabulary, since it declares no
|
|
7
|
+
* rule and no profile (`estuarine/nudges.ts`). Cynefin contributes neither,
|
|
8
|
+
* having no role of its own.
|
|
9
|
+
*
|
|
5
10
|
* Its command labels and descriptions are built from a TEMPLATE, so the
|
|
6
11
|
* concrete keys exist nowhere but in the declarations themselves and the
|
|
7
12
|
* core manifest could not restate them even if it wanted to. The
|
package/dist/translations.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import { commandTranslationEntries, } from '@formicoidea/labre-core/std';
|
|
1
|
+
import { collectTranslationKeys, commandCategoryTranslationEntries, commandTranslationEntries, mergeTranslationEntries, } from '@formicoidea/labre-core/std';
|
|
2
2
|
import { cynefinEstuarineCommands } from './commands.js';
|
|
3
|
+
import { ESTUARINE_NUDGES } from './estuarine/nudges.js';
|
|
4
|
+
import { ESTUARINE_ROLES } from './estuarine/roles.js';
|
|
3
5
|
/**
|
|
4
6
|
* THIS framework's contribution to the translation-key manifest.
|
|
5
7
|
*
|
|
8
|
+
* Since WS4 it also carries the Estuarine ROLE labels and the four Map quality
|
|
9
|
+
* NUDGES — the framework's entire validation vocabulary, since it declares no
|
|
10
|
+
* rule and no profile (`estuarine/nudges.ts`). Cynefin contributes neither,
|
|
11
|
+
* having no role of its own.
|
|
12
|
+
*
|
|
6
13
|
* Its command labels and descriptions are built from a TEMPLATE, so the
|
|
7
14
|
* concrete keys exist nowhere but in the declarations themselves and the
|
|
8
15
|
* core manifest could not restate them even if it wanted to. The
|
|
@@ -12,4 +19,10 @@ import { cynefinEstuarineCommands } from './commands.js';
|
|
|
12
19
|
* `cynefinEstuarineCommands` into the command registry. See
|
|
13
20
|
* `packages/affine/all/src/translations.ts`.
|
|
14
21
|
*/
|
|
15
|
-
export const cynefinEstuarineTranslationEntries = commandTranslationEntries(cynefinEstuarineCommands)
|
|
22
|
+
export const cynefinEstuarineTranslationEntries = mergeTranslationEntries(commandTranslationEntries(cynefinEstuarineCommands),
|
|
23
|
+
// The catalogue's own group headers, derived from the very categories
|
|
24
|
+
// these commands declare. They ship WITH the framework because core's
|
|
25
|
+
// registry names no framework category in the bundled distribution, so a
|
|
26
|
+
// host that composed core's manifest alone drew translated entries under
|
|
27
|
+
// English headers (#183).
|
|
28
|
+
commandCategoryTranslationEntries(cynefinEstuarineCommands), collectTranslationKeys('role', ESTUARINE_ROLES), collectTranslationKeys('nudge', ESTUARINE_NUDGES));
|
package/dist/view.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { QualityNudgeExtension, ValidationFrameworkExtension, validationToolbarConfig, } from '@formicoidea/labre-core/blocks/surface';
|
|
1
2
|
import { ViewExtensionProvider, } from '@formicoidea/labre-core/ext-loader';
|
|
2
3
|
import { extendTemplateCategory } from '@formicoidea/labre-core/gfx/template';
|
|
3
|
-
import {
|
|
4
|
+
import { ToolbarModuleExtension } from '@formicoidea/labre-core/shared/services';
|
|
5
|
+
import { BlockFlavourIdentifier, CommandExtension } from '@formicoidea/labre-core/std';
|
|
6
|
+
import { RoleVocabularyExtension } from '@formicoidea/labre-core/std/gfx';
|
|
4
7
|
import { cynefinEstuarineCommandIcons, cynefinEstuarineCommands, } from './commands.js';
|
|
5
8
|
import { CynefinRendererExtension } from './cynefin/element-renderer.js';
|
|
6
9
|
import { CynefinInteraction, CynefinView } from './cynefin/element-view.js';
|
|
@@ -8,6 +11,9 @@ import { cynefinToolbarExtension } from './cynefin/toolbar/config.js';
|
|
|
8
11
|
import { effects } from './effects.js';
|
|
9
12
|
import { EstuarineRendererExtension } from './estuarine/element-renderer.js';
|
|
10
13
|
import { EstuarineInteraction, EstuarineView } from './estuarine/element-view.js';
|
|
14
|
+
import { EstuarineGhostManager, EstuarineGhostOverlay, } from './estuarine/ghost-overlay.js';
|
|
15
|
+
import { ESTUARINE_NUDGES } from './estuarine/nudges.js';
|
|
16
|
+
import { ESTUARINE_ROLE, ESTUARINE_ROLES } from './estuarine/roles.js';
|
|
11
17
|
import { estuarineToolbarExtension } from './estuarine/toolbar/config.js';
|
|
12
18
|
import { cynefinTemplateCategory, estuarineTemplateCategory, } from './templates/index.js';
|
|
13
19
|
import { cynefinEstuarineSeniorTool } from './toolbar/senior-tool.js';
|
|
@@ -29,11 +35,26 @@ export class CynefinEstuarineRenderViewExtension extends ViewExtensionProvider {
|
|
|
29
35
|
context.register(CynefinRendererExtension);
|
|
30
36
|
context.register(EstuarineView);
|
|
31
37
|
context.register(EstuarineRendererExtension);
|
|
38
|
+
// The role VOCABULARY, always on. A role is written in the document, not in
|
|
39
|
+
// the tooling: a map drawn while the flag was on and opened while it is off
|
|
40
|
+
// still carries `estuarine:map`, and anything that READS a role — the
|
|
41
|
+
// qualification toolbar, a host panel — has to keep working
|
|
42
|
+
// (`docs/adr/0009`). What JUDGES those roles stays flag-gated below.
|
|
43
|
+
// Cynefin contributes nothing here and never will (`estuarine/roles.ts`).
|
|
44
|
+
context.register(RoleVocabularyExtension(ESTUARINE_ROLES));
|
|
32
45
|
if (this.isEdgeless(context.scope)) {
|
|
33
46
|
context.register(CynefinInteraction);
|
|
34
47
|
context.register(EstuarineInteraction);
|
|
35
48
|
context.register(cynefinToolbarExtension);
|
|
36
49
|
context.register(estuarineToolbarExtension);
|
|
50
|
+
// The reveal animation of a curve toggle. ALWAYS on, with the renderer
|
|
51
|
+
// it animates: the permanent ghost is how a shown curve looks now, so
|
|
52
|
+
// the ~600 ms that makes its arrival visible is part of painting the
|
|
53
|
+
// element, not part of the creation tooling. It writes nothing, and it
|
|
54
|
+
// costs one media query plus one map lookup on a board with no
|
|
55
|
+
// Estuarine map at all.
|
|
56
|
+
context.register(EstuarineGhostOverlay);
|
|
57
|
+
context.register(EstuarineGhostManager);
|
|
37
58
|
}
|
|
38
59
|
}
|
|
39
60
|
}
|
|
@@ -56,6 +77,33 @@ export class CynefinEstuarineViewExtension extends ViewExtensionProvider {
|
|
|
56
77
|
setup(context) {
|
|
57
78
|
super.setup(context);
|
|
58
79
|
if (this.isEdgeless(context.scope)) {
|
|
80
|
+
// Estuarine's ROOT INSTANCE declaration (WS0.3). Every other framework
|
|
81
|
+
// derives "this element is my frame" from a rule naming the role as its
|
|
82
|
+
// background; Estuarine ships no rule at all — by arbitration, not by
|
|
83
|
+
// omission (see `estuarine/nudges.ts`) — so it says so explicitly rather
|
|
84
|
+
// than inventing a rule that fires on nothing just to open a gate.
|
|
85
|
+
context.register(ValidationFrameworkExtension([
|
|
86
|
+
{
|
|
87
|
+
framework: 'estuarine',
|
|
88
|
+
backgroundRole: ESTUARINE_ROLE.map,
|
|
89
|
+
roles: ESTUARINE_ROLES,
|
|
90
|
+
},
|
|
91
|
+
]));
|
|
92
|
+
// Map quality: the four expectations no algorithm can check. This is the
|
|
93
|
+
// whole of what validation offers on an Estuarine map — no rules, and
|
|
94
|
+
// therefore NO profiles: a severity dial over an empty rule set is a
|
|
95
|
+
// control that decides nothing.
|
|
96
|
+
context.register(QualityNudgeExtension(ESTUARINE_NUDGES));
|
|
97
|
+
// The Validation dropdown on a selected map's contextual toolbar — a
|
|
98
|
+
// SECOND module on the same element, through the free `custom:` flavour
|
|
99
|
+
// slot (`estuarineToolbarExtension` owns the plain one and is always-on,
|
|
100
|
+
// because a stored map must keep its curve toggles). The config names no
|
|
101
|
+
// framework: it reads roles, profiles and nudges, so here it renders the
|
|
102
|
+
// checklist entry and no profile picker.
|
|
103
|
+
context.register(ToolbarModuleExtension({
|
|
104
|
+
id: BlockFlavourIdentifier('custom:affine:surface:estuarine'),
|
|
105
|
+
config: validationToolbarConfig,
|
|
106
|
+
}));
|
|
59
107
|
context.register(cynefinEstuarineSeniorTool);
|
|
60
108
|
context.register(CommandExtension(cynefinEstuarineCommands, cynefinEstuarineCommandIcons));
|
|
61
109
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formicoidea/labre-framework-cynefin",
|
|
3
3
|
"description": "Labre cynefin-estuarine framework for @formicoidea/labre-core.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.34.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"author": "lajola",
|
|
@@ -21,13 +21,18 @@
|
|
|
21
21
|
"./descriptor": {
|
|
22
22
|
"types": "./dist/descriptor.d.ts",
|
|
23
23
|
"import": "./dist/descriptor.js"
|
|
24
|
+
},
|
|
25
|
+
"./commands-manifest": {
|
|
26
|
+
"types": "./dist/commands-manifest.d.ts",
|
|
27
|
+
"import": "./dist/commands-manifest.js"
|
|
24
28
|
}
|
|
25
29
|
},
|
|
26
30
|
"files": [
|
|
27
31
|
"dist"
|
|
28
32
|
],
|
|
29
33
|
"dependencies": {
|
|
30
|
-
"@formicoidea/labre-core": "0.
|
|
34
|
+
"@formicoidea/labre-core": "0.34.1",
|
|
35
|
+
"@preact/signals-core": "^1.8.0",
|
|
31
36
|
"lit": "^3.2.0"
|
|
32
37
|
}
|
|
33
38
|
}
|