@formicoidea/labre-framework-cynefin 0.23.0 → 0.23.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/cynefin/consts.d.ts +80 -0
- package/dist/cynefin/consts.js +142 -0
- package/dist/cynefin/element-renderer.d.ts +15 -0
- package/dist/cynefin/element-renderer.js +115 -0
- package/dist/cynefin/element-view.d.ts +15 -0
- package/dist/cynefin/element-view.js +24 -0
- package/dist/cynefin/toolbar/config.d.ts +32 -0
- package/dist/cynefin/toolbar/config.js +44 -0
- package/dist/descriptor.d.ts +7 -0
- package/{src/descriptor.ts → dist/descriptor.js} +1 -1
- package/dist/effects.d.ts +10 -0
- package/dist/effects.js +7 -0
- package/dist/estuarine/consts.d.ts +85 -0
- package/dist/estuarine/consts.js +55 -0
- package/dist/estuarine/element-renderer.d.ts +14 -0
- package/dist/estuarine/element-renderer.js +84 -0
- package/dist/estuarine/element-view.d.ts +15 -0
- package/dist/estuarine/element-view.js +24 -0
- package/dist/estuarine/toolbar/config.d.ts +38 -0
- package/dist/estuarine/toolbar/config.js +48 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/templates/index.d.ts +4 -0
- package/dist/templates/index.js +95 -0
- package/dist/toolbar/cynefin-menu.d.ts +12 -0
- package/dist/toolbar/cynefin-menu.js +66 -0
- package/dist/toolbar/cynefin-senior-button.d.ts +13 -0
- package/dist/toolbar/cynefin-senior-button.js +90 -0
- package/dist/toolbar/estuarine-menu.d.ts +14 -0
- package/dist/toolbar/estuarine-menu.js +113 -0
- package/dist/toolbar/estuarine-senior-button.d.ts +13 -0
- package/dist/toolbar/estuarine-senior-button.js +90 -0
- package/dist/toolbar/icons.d.ts +9 -0
- package/{src/toolbar/icons.ts → dist/toolbar/icons.js} +14 -17
- package/dist/toolbar/menu.d.ts +18 -0
- package/{src/toolbar/menu.ts → dist/toolbar/menu.js} +68 -91
- package/dist/toolbar/senior-button.d.ts +13 -0
- package/{src/toolbar/senior-button.ts → dist/toolbar/senior-button.js} +33 -38
- package/dist/toolbar/senior-tool.d.ts +3 -0
- package/{src/toolbar/senior-tool.ts → dist/toolbar/senior-tool.js} +5 -8
- package/dist/utils.d.ts +12 -0
- package/{src/utils.ts → dist/utils.js} +11 -11
- package/dist/view.d.ts +7 -0
- package/dist/view.js +38 -0
- package/package.json +15 -6
- package/src/cynefin/consts.ts +0 -188
- package/src/cynefin/element-renderer.ts +0 -156
- package/src/cynefin/element-view.ts +0 -32
- package/src/cynefin/toolbar/config.ts +0 -60
- package/src/effects.ts +0 -20
- package/src/estuarine/consts.ts +0 -69
- package/src/estuarine/element-renderer.ts +0 -122
- package/src/estuarine/element-view.ts +0 -32
- package/src/estuarine/toolbar/config.ts +0 -65
- package/src/index.ts +0 -1
- package/src/templates/index.ts +0 -130
- package/src/view.ts +0 -44
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type ElementRenderer } from '@formicoidea/labre-core/blocks/surface';
|
|
2
|
+
import type { EstuarineElementModel } from '@formicoidea/labre-core/model';
|
|
3
|
+
/**
|
|
4
|
+
* Canvas renderer for the Estuarine framework map — reproduces the official SVG:
|
|
5
|
+
* the e (vertical, double-headed) / t (horizontal, single-headed) axes and the
|
|
6
|
+
* three reference curves (Liminal / Volatile / Counter-factual), each with its
|
|
7
|
+
* legend and individually hideable. Drawn in the fixed reference space and
|
|
8
|
+
* scaled uniformly to the element bounds.
|
|
9
|
+
*/
|
|
10
|
+
export declare const estuarine: ElementRenderer<EstuarineElementModel>;
|
|
11
|
+
export declare const EstuarineRendererExtension: import("@formicoidea/labre-core/store").ExtensionType & {
|
|
12
|
+
identifier: import("@formicoidea/labre-core/global/di").ServiceIdentifier<ElementRenderer<EstuarineElementModel>>;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=element-renderer.d.ts.map
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ElementRendererExtension, } from '@formicoidea/labre-core/blocks/surface';
|
|
2
|
+
import { FONT_FAMILY, refScale } from '../utils';
|
|
3
|
+
import { ARROWHEADS, AXIS_LABELS, AXIS_WIDTH, COLORS, COUNTERFACTUAL_PATH, COUNTERFACTUAL_WIDTH, E_AXIS, LABEL_LETTER_SPACING, LABELS, LIMINAL_PATH, LIMINAL_WIDTH, REF_H, REF_W, T_AXIS, VOLATILE_PATH, VOLATILE_WIDTH, } from './consts';
|
|
4
|
+
/**
|
|
5
|
+
* Canvas renderer for the Estuarine framework map — reproduces the official SVG:
|
|
6
|
+
* the e (vertical, double-headed) / t (horizontal, single-headed) axes and the
|
|
7
|
+
* three reference curves (Liminal / Volatile / Counter-factual), each with its
|
|
8
|
+
* legend and individually hideable. Drawn in the fixed reference space and
|
|
9
|
+
* scaled uniformly to the element bounds.
|
|
10
|
+
*/
|
|
11
|
+
export const estuarine = (model, ctx, matrix) => {
|
|
12
|
+
const [, , w, h] = model.deserializedXYWH;
|
|
13
|
+
const cx = w / 2;
|
|
14
|
+
const cy = h / 2;
|
|
15
|
+
ctx.setTransform(matrix.translateSelf(cx, cy).rotateSelf(model.rotate).translateSelf(-cx, -cy));
|
|
16
|
+
const { s, ox, oy } = refScale(w, h, REF_W, REF_H);
|
|
17
|
+
ctx.translate(ox, oy);
|
|
18
|
+
ctx.scale(s, s);
|
|
19
|
+
ctx.lineCap = 'round';
|
|
20
|
+
ctx.lineJoin = 'round';
|
|
21
|
+
// ── Axes ────────────────────────────────────────────────────────────
|
|
22
|
+
ctx.strokeStyle = COLORS.axis;
|
|
23
|
+
ctx.fillStyle = COLORS.axis;
|
|
24
|
+
ctx.lineWidth = AXIS_WIDTH;
|
|
25
|
+
ctx.beginPath();
|
|
26
|
+
ctx.moveTo(E_AXIS.x, E_AXIS.y1);
|
|
27
|
+
ctx.lineTo(E_AXIS.x, E_AXIS.y2);
|
|
28
|
+
ctx.moveTo(T_AXIS.x1, T_AXIS.y);
|
|
29
|
+
ctx.lineTo(T_AXIS.x2, T_AXIS.y);
|
|
30
|
+
ctx.stroke();
|
|
31
|
+
for (const [[tx, ty], [ax, ay], [bx, by]] of ARROWHEADS) {
|
|
32
|
+
ctx.beginPath();
|
|
33
|
+
ctx.moveTo(tx, ty);
|
|
34
|
+
ctx.lineTo(ax, ay);
|
|
35
|
+
ctx.lineTo(bx, by);
|
|
36
|
+
ctx.closePath();
|
|
37
|
+
ctx.fill();
|
|
38
|
+
}
|
|
39
|
+
// Uppercase legend (centre-anchored, alphabetic baseline, letter-spaced).
|
|
40
|
+
const hasSpacing = 'letterSpacing' in ctx;
|
|
41
|
+
const legend = (l) => {
|
|
42
|
+
ctx.fillStyle = l.color;
|
|
43
|
+
ctx.font = `600 ${l.size}px ${FONT_FAMILY}`;
|
|
44
|
+
ctx.textAlign = 'center';
|
|
45
|
+
ctx.textBaseline = 'alphabetic';
|
|
46
|
+
if (hasSpacing)
|
|
47
|
+
ctx.letterSpacing = `${LABEL_LETTER_SPACING}px`;
|
|
48
|
+
ctx.fillText(l.text, l.x, l.y);
|
|
49
|
+
if (hasSpacing)
|
|
50
|
+
ctx.letterSpacing = '0px';
|
|
51
|
+
};
|
|
52
|
+
// ── Liminal (green) ─────────────────────────────────────────────────
|
|
53
|
+
if (model.showLiminal) {
|
|
54
|
+
ctx.strokeStyle = COLORS.liminal;
|
|
55
|
+
ctx.lineWidth = LIMINAL_WIDTH;
|
|
56
|
+
ctx.stroke(new Path2D(LIMINAL_PATH));
|
|
57
|
+
legend(LABELS.liminal);
|
|
58
|
+
}
|
|
59
|
+
// ── Volatile (red) ──────────────────────────────────────────────────
|
|
60
|
+
if (model.showVolatile) {
|
|
61
|
+
ctx.strokeStyle = COLORS.volatile;
|
|
62
|
+
ctx.lineWidth = VOLATILE_WIDTH;
|
|
63
|
+
ctx.stroke(new Path2D(VOLATILE_PATH));
|
|
64
|
+
legend(LABELS.volatile);
|
|
65
|
+
}
|
|
66
|
+
// ── Counter-factual (dark) ──────────────────────────────────────────
|
|
67
|
+
if (model.showCounterfactual) {
|
|
68
|
+
ctx.strokeStyle = COLORS.counterfactual;
|
|
69
|
+
ctx.lineWidth = COUNTERFACTUAL_WIDTH;
|
|
70
|
+
ctx.stroke(new Path2D(COUNTERFACTUAL_PATH));
|
|
71
|
+
legend(LABELS.counterfactual);
|
|
72
|
+
}
|
|
73
|
+
// ── Italic e / t axis letters ───────────────────────────────────────
|
|
74
|
+
if (model.showAxisLabels) {
|
|
75
|
+
ctx.fillStyle = COLORS.axisLabel;
|
|
76
|
+
ctx.font = `italic 700 ${AXIS_LABELS.size}px Georgia, serif`;
|
|
77
|
+
ctx.textAlign = 'left';
|
|
78
|
+
ctx.textBaseline = 'alphabetic';
|
|
79
|
+
ctx.fillText(AXIS_LABELS.e.text, AXIS_LABELS.e.x, AXIS_LABELS.e.y);
|
|
80
|
+
ctx.fillText(AXIS_LABELS.t.text, AXIS_LABELS.t.x, AXIS_LABELS.t.y);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
export const EstuarineRendererExtension = ElementRendererExtension('estuarine', estuarine);
|
|
84
|
+
//# sourceMappingURL=element-renderer.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { EstuarineElementModel } from '@formicoidea/labre-core/model';
|
|
2
|
+
import { GfxElementModelView } from '@formicoidea/labre-core/std/gfx';
|
|
3
|
+
/**
|
|
4
|
+
* View for the Estuarine background. Registering it ensures `gfx.view.get(model)`
|
|
5
|
+
* returns a view (required so move / select interactions work).
|
|
6
|
+
*/
|
|
7
|
+
export declare class EstuarineView extends GfxElementModelView<EstuarineElementModel> {
|
|
8
|
+
static type: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Resize gating: the resize handles are hidden unless `model.resizeEnabled` is
|
|
12
|
+
* true (toggled from the toolbar). Moving / selecting stays available.
|
|
13
|
+
*/
|
|
14
|
+
export declare const EstuarineInteraction: import("@formicoidea/labre-core/store").ExtensionType;
|
|
15
|
+
//# sourceMappingURL=element-view.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { GfxElementModelView, GfxViewInteractionExtension, } from '@formicoidea/labre-core/std/gfx';
|
|
2
|
+
/**
|
|
3
|
+
* View for the Estuarine background. Registering it ensures `gfx.view.get(model)`
|
|
4
|
+
* returns a view (required so move / select interactions work).
|
|
5
|
+
*/
|
|
6
|
+
export class EstuarineView extends GfxElementModelView {
|
|
7
|
+
static { this.type = 'estuarine'; }
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Resize gating: the resize handles are hidden unless `model.resizeEnabled` is
|
|
11
|
+
* true (toggled from the toolbar). Moving / selecting stays available.
|
|
12
|
+
*/
|
|
13
|
+
export const EstuarineInteraction = GfxViewInteractionExtension(EstuarineView.type, {
|
|
14
|
+
handleResize({ model }) {
|
|
15
|
+
return {
|
|
16
|
+
beforeResize({ set }) {
|
|
17
|
+
if (!model.resizeEnabled) {
|
|
18
|
+
set({ allowedHandlers: [] });
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
//# sourceMappingURL=element-view.js.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type ToolbarContext } from '@formicoidea/labre-core/shared/services';
|
|
2
|
+
import { type TemplateResult } from 'lit';
|
|
3
|
+
export declare const estuarineToolbarConfig: {
|
|
4
|
+
readonly actions: [{
|
|
5
|
+
id: string;
|
|
6
|
+
tooltip: string;
|
|
7
|
+
icon: TemplateResult;
|
|
8
|
+
active(ctx: ToolbarContext): boolean;
|
|
9
|
+
run(ctx: ToolbarContext): void;
|
|
10
|
+
}, {
|
|
11
|
+
id: string;
|
|
12
|
+
tooltip: string;
|
|
13
|
+
icon: TemplateResult;
|
|
14
|
+
active(ctx: ToolbarContext): boolean;
|
|
15
|
+
run(ctx: ToolbarContext): void;
|
|
16
|
+
}, {
|
|
17
|
+
id: string;
|
|
18
|
+
tooltip: string;
|
|
19
|
+
icon: TemplateResult;
|
|
20
|
+
active(ctx: ToolbarContext): boolean;
|
|
21
|
+
run(ctx: ToolbarContext): void;
|
|
22
|
+
}, {
|
|
23
|
+
id: string;
|
|
24
|
+
tooltip: string;
|
|
25
|
+
icon: TemplateResult;
|
|
26
|
+
active(ctx: ToolbarContext): boolean;
|
|
27
|
+
run(ctx: ToolbarContext): void;
|
|
28
|
+
}, {
|
|
29
|
+
id: string;
|
|
30
|
+
tooltip: string;
|
|
31
|
+
icon: TemplateResult;
|
|
32
|
+
active(ctx: ToolbarContext): boolean;
|
|
33
|
+
run(ctx: ToolbarContext): void;
|
|
34
|
+
}];
|
|
35
|
+
readonly when: (ctx: ToolbarContext) => boolean;
|
|
36
|
+
};
|
|
37
|
+
export declare const estuarineToolbarExtension: import("@formicoidea/labre-core/store").ExtensionType;
|
|
38
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { EdgelessCRUDIdentifier } from '@formicoidea/labre-core/blocks/surface';
|
|
2
|
+
import { EstuarineElementModel } from '@formicoidea/labre-core/model';
|
|
3
|
+
import { ToolbarModuleExtension, } from '@formicoidea/labre-core/shared/services';
|
|
4
|
+
import { BlockFlavourIdentifier } from '@formicoidea/labre-core/std';
|
|
5
|
+
import { html } from 'lit';
|
|
6
|
+
const ResizeIcon = html `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M9 5H5v4M15 19h4v-4" /><path d="M5 5l6 6M19 19l-6-6" /></svg>`;
|
|
7
|
+
// All curve icons use currentColor so the toolbar can grey them when inactive;
|
|
8
|
+
// they are distinguished by shape (wave / arc / hooked curve).
|
|
9
|
+
const LiminalIcon = html `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M3 13c3-6 6 4 9 0s6-6 9 0" /></svg>`;
|
|
10
|
+
const VolatileIcon = html `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M7 4a9 9 0 0 1 0 18" /></svg>`;
|
|
11
|
+
const CounterfactualIcon = html `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M4 7c7 0 11 4 12 14" /></svg>`;
|
|
12
|
+
const AxisIcon = html `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3v18M6 12h15" /><path d="M3 6l3-3 3 3M18 9l3 3-3 3" /></svg>`;
|
|
13
|
+
function booleanToggle(id, tooltip, icon, prop) {
|
|
14
|
+
return {
|
|
15
|
+
id,
|
|
16
|
+
tooltip,
|
|
17
|
+
icon,
|
|
18
|
+
active(ctx) {
|
|
19
|
+
const models = ctx.getSurfaceModelsByType(EstuarineElementModel);
|
|
20
|
+
return models.length > 0 && models.every(model => model[prop]);
|
|
21
|
+
},
|
|
22
|
+
run(ctx) {
|
|
23
|
+
const models = ctx.getSurfaceModelsByType(EstuarineElementModel);
|
|
24
|
+
if (!models.length)
|
|
25
|
+
return;
|
|
26
|
+
const enable = !models.every(model => model[prop]);
|
|
27
|
+
ctx.std.store.captureSync();
|
|
28
|
+
const crud = ctx.std.get(EdgelessCRUDIdentifier);
|
|
29
|
+
for (const model of models)
|
|
30
|
+
crud.updateElement(model.id, { [prop]: enable });
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export const estuarineToolbarConfig = {
|
|
35
|
+
actions: [
|
|
36
|
+
booleanToggle('a.toggle-resize', 'Enable / lock resizing', ResizeIcon, 'resizeEnabled'),
|
|
37
|
+
booleanToggle('b.toggle-liminal', 'Show / hide the Liminal line', LiminalIcon, 'showLiminal'),
|
|
38
|
+
booleanToggle('c.toggle-volatile', 'Show / hide the Volatile line', VolatileIcon, 'showVolatile'),
|
|
39
|
+
booleanToggle('d.toggle-counterfactual', 'Show / hide the Counter-factual line', CounterfactualIcon, 'showCounterfactual'),
|
|
40
|
+
booleanToggle('e.toggle-axis-labels', 'Show / hide axis labels (e / t)', AxisIcon, 'showAxisLabels'),
|
|
41
|
+
],
|
|
42
|
+
when: ctx => ctx.getSurfaceModelsByType(EstuarineElementModel).length > 0,
|
|
43
|
+
};
|
|
44
|
+
export const estuarineToolbarExtension = ToolbarModuleExtension({
|
|
45
|
+
id: BlockFlavourIdentifier('affine:surface:estuarine'),
|
|
46
|
+
config: estuarineToolbarConfig,
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=config.js.map
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { makeTemplateSnapshot, surfaceText, } from '@formicoidea/labre-core/gfx/template';
|
|
2
|
+
import { FontFamily, ShapeStyle, TextAlign } from '@formicoidea/labre-core/model';
|
|
3
|
+
import { REF_H as CYN_H, REF_W as CYN_W } from '../cynefin/consts';
|
|
4
|
+
import { REF_H as EST_H, REF_W as EST_W } from '../estuarine/consts';
|
|
5
|
+
const HEX_SIZE = 60;
|
|
6
|
+
const HEX_FILL = '#34c724';
|
|
7
|
+
const HEX_STROKE = '#1f1f1f';
|
|
8
|
+
const HEX_VERTICES = [
|
|
9
|
+
[1, 0.5],
|
|
10
|
+
[0.75, 0.933],
|
|
11
|
+
[0.25, 0.933],
|
|
12
|
+
[0, 0.5],
|
|
13
|
+
[0.25, 0.067],
|
|
14
|
+
[0.75, 0.067],
|
|
15
|
+
];
|
|
16
|
+
function sticky(x, y, text) {
|
|
17
|
+
return {
|
|
18
|
+
type: 'shape',
|
|
19
|
+
shapeType: 'rect',
|
|
20
|
+
filled: true,
|
|
21
|
+
fillColor: '#fff3b0',
|
|
22
|
+
strokeColor: '#d9b740',
|
|
23
|
+
strokeWidth: 1.5,
|
|
24
|
+
shapeStyle: ShapeStyle.General,
|
|
25
|
+
roughness: 0,
|
|
26
|
+
radius: 8,
|
|
27
|
+
text: surfaceText(text),
|
|
28
|
+
color: '#1a1a1a',
|
|
29
|
+
fontFamily: FontFamily.Inter,
|
|
30
|
+
fontSize: 18,
|
|
31
|
+
textAlign: TextAlign.Center,
|
|
32
|
+
xywh: `[${x},${y},200,70]`,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function hexagon(x, y) {
|
|
36
|
+
return {
|
|
37
|
+
type: 'shape',
|
|
38
|
+
shapeType: 'polygon',
|
|
39
|
+
vertices: HEX_VERTICES,
|
|
40
|
+
filled: true,
|
|
41
|
+
fillColor: HEX_FILL,
|
|
42
|
+
strokeColor: HEX_STROKE,
|
|
43
|
+
strokeWidth: 2,
|
|
44
|
+
shapeStyle: ShapeStyle.General,
|
|
45
|
+
roughness: 0,
|
|
46
|
+
xywh: `[${x},${y},${HEX_SIZE},${HEX_SIZE}]`,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function caption(x, y, str) {
|
|
50
|
+
return {
|
|
51
|
+
type: 'text',
|
|
52
|
+
text: surfaceText(str),
|
|
53
|
+
color: '#1a1a1a',
|
|
54
|
+
fontFamily: FontFamily.Inter,
|
|
55
|
+
fontSize: 16,
|
|
56
|
+
textAlign: TextAlign.Center,
|
|
57
|
+
xywh: `[${x},${y},120,24]`,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function tpl(name, preview, elements) {
|
|
61
|
+
return { name, type: 'template', preview, content: makeTemplateSnapshot(elements, name) };
|
|
62
|
+
}
|
|
63
|
+
const ATTRS = 'width="100%" height="100%" viewBox="0 0 135 80" xmlns="http://www.w3.org/2000/svg"';
|
|
64
|
+
const cynefinBg = (xywh) => ({ type: 'cynefin', xywh });
|
|
65
|
+
const estuarineBg = (xywh) => ({ type: 'estuarine', xywh });
|
|
66
|
+
export const cynefinTemplateCategory = {
|
|
67
|
+
name: 'Cynefin',
|
|
68
|
+
templates: [
|
|
69
|
+
tpl('Decision sorting', `<svg ${ATTRS} fill="none"><rect x="8" y="10" width="119" height="60" rx="4" stroke="#2a9d99" stroke-width="1.5"/><path d="M67 10 V70 M8 40 H127" stroke="#9aa0a6"/><rect x="18" y="18" width="34" height="14" rx="2" fill="#fff3b0"/><rect x="83" y="18" width="34" height="14" rx="2" fill="#fff3b0"/><rect x="18" y="48" width="34" height="14" rx="2" fill="#fff3b0"/><rect x="83" y="48" width="34" height="14" rx="2" fill="#fff3b0"/></svg>`, {
|
|
70
|
+
bg: cynefinBg(`[0,0,${CYN_W},${CYN_H}]`),
|
|
71
|
+
s1: sticky(190, 175, 'Probe & learn'),
|
|
72
|
+
s2: sticky(690, 175, 'Expert analysis'),
|
|
73
|
+
s3: sticky(190, 505, 'Act now'),
|
|
74
|
+
s4: sticky(690, 505, 'Known issue'),
|
|
75
|
+
}),
|
|
76
|
+
tpl('Cynefin framework', `<svg ${ATTRS} fill="none"><rect x="14" y="12" width="107" height="56" rx="4" stroke="#2a9d99" stroke-width="1.6"/><path d="M67 12 V68 M14 40 H121" stroke="#9aa0a6"/></svg>`, { bg: cynefinBg(`[0,0,${CYN_W},${CYN_H}]`) }),
|
|
77
|
+
],
|
|
78
|
+
};
|
|
79
|
+
export const estuarineTemplateCategory = {
|
|
80
|
+
name: 'Estuarine',
|
|
81
|
+
templates: [
|
|
82
|
+
tpl('Constraint map', `<svg ${ATTRS} fill="none"><path d="M20 12 V70 M20 70 H120" stroke="#941253" stroke-width="2"/><g fill="#34c724" stroke="#1f1f1f"><path d="M44 28 l6 4 l0 8 l-6 4 l-6 -4 l0 -8 z"/><path d="M74 40 l6 4 l0 8 l-6 4 l-6 -4 l0 -8 z"/><path d="M56 52 l6 4 l0 8 l-6 4 l-6 -4 l0 -8 z"/></g></svg>`, {
|
|
83
|
+
bg: estuarineBg(`[0,0,${EST_W},${EST_H}]`),
|
|
84
|
+
h1: hexagon(150, 220),
|
|
85
|
+
c1: caption(120, 284, 'Policy'),
|
|
86
|
+
h2: hexagon(330, 360),
|
|
87
|
+
c2: caption(300, 424, 'Habit'),
|
|
88
|
+
h3: hexagon(230, 520),
|
|
89
|
+
c3: caption(200, 584, 'Budget'),
|
|
90
|
+
}),
|
|
91
|
+
tpl('Estuarine map', `<svg ${ATTRS} fill="none"><path d="M24 10 V70 M24 70 H120" stroke="#941253" stroke-width="2.4"/><path d="M30 52 q40 -30 84 -34" stroke="#5ecc44" stroke-width="2" fill="none"/></svg>`, { bg: estuarineBg(`[0,0,${EST_W},${EST_H}]`) }),
|
|
92
|
+
tpl('Hexagon constraint', `<svg ${ATTRS} fill="none"><path d="M67 24 l18 11 l0 22 l-18 11 l-18 -11 l0 -22 z" fill="#34c724" stroke="#1f1f1f" stroke-width="2"/></svg>`, { hex: hexagon(0, 0) }),
|
|
93
|
+
],
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { EmptyTool } from '@blocksuite/affine-gfx-pointer';
|
|
2
|
+
import { LitElement } from 'lit';
|
|
3
|
+
declare const EdgelessCynefinMenu_base: typeof LitElement & import("@blocksuite/global/utils").Constructor<import("@blocksuite/affine-widget-edgeless-toolbar").EdgelessToolbarToolClass>;
|
|
4
|
+
/** The popover above the toolbar that creates the Cynefin diagram. */
|
|
5
|
+
export declare class EdgelessCynefinMenu extends EdgelessCynefinMenu_base {
|
|
6
|
+
static styles: import("lit").CSSResult;
|
|
7
|
+
type: typeof EmptyTool;
|
|
8
|
+
private _createCynefin;
|
|
9
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
10
|
+
}
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=cynefin-menu.d.ts.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
|
2
|
+
import { EmptyTool } from '@blocksuite/affine-gfx-pointer';
|
|
3
|
+
import { EdgelessToolbarToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar';
|
|
4
|
+
import { Bound } from '@blocksuite/global/gfx';
|
|
5
|
+
import { css, html, LitElement } from 'lit';
|
|
6
|
+
import { REF_H, REF_W } from '../cynefin/consts';
|
|
7
|
+
import { cynefinMenuIcon } from './icons';
|
|
8
|
+
/** The popover above the toolbar that creates the Cynefin diagram. */
|
|
9
|
+
export class EdgelessCynefinMenu extends EdgelessToolbarToolMixin(LitElement) {
|
|
10
|
+
constructor() {
|
|
11
|
+
super(...arguments);
|
|
12
|
+
this.type = EmptyTool;
|
|
13
|
+
}
|
|
14
|
+
static { this.styles = css `
|
|
15
|
+
:host {
|
|
16
|
+
position: absolute;
|
|
17
|
+
display: flex;
|
|
18
|
+
z-index: -1;
|
|
19
|
+
}
|
|
20
|
+
.menu-content {
|
|
21
|
+
display: flex;
|
|
22
|
+
align-items: center;
|
|
23
|
+
justify-content: center;
|
|
24
|
+
}
|
|
25
|
+
.button-group-container {
|
|
26
|
+
display: flex;
|
|
27
|
+
align-items: center;
|
|
28
|
+
gap: 14px;
|
|
29
|
+
fill: var(--affine-icon-color);
|
|
30
|
+
}
|
|
31
|
+
.button-group-container svg {
|
|
32
|
+
width: 24px;
|
|
33
|
+
height: 24px;
|
|
34
|
+
}
|
|
35
|
+
`; }
|
|
36
|
+
_createCynefin() {
|
|
37
|
+
const { gfx } = this;
|
|
38
|
+
if (!gfx.surface)
|
|
39
|
+
return;
|
|
40
|
+
const { centerX, centerY } = gfx.viewport;
|
|
41
|
+
const id = gfx.surface.addElement({
|
|
42
|
+
type: 'cynefin',
|
|
43
|
+
xywh: new Bound(centerX - REF_W / 2, centerY - REF_H / 2, REF_W, REF_H).serialize(),
|
|
44
|
+
});
|
|
45
|
+
gfx.doc.captureSync();
|
|
46
|
+
gfx.tool.setTool(DefaultTool);
|
|
47
|
+
gfx.selection.set({ elements: [id], editing: false });
|
|
48
|
+
}
|
|
49
|
+
render() {
|
|
50
|
+
return html `
|
|
51
|
+
<edgeless-slide-menu>
|
|
52
|
+
<div class="menu-content">
|
|
53
|
+
<div class="button-group-container">
|
|
54
|
+
<edgeless-tool-icon-button
|
|
55
|
+
.tooltip=${'Cynefin framework'}
|
|
56
|
+
@click=${this._createCynefin}
|
|
57
|
+
>
|
|
58
|
+
${cynefinMenuIcon}
|
|
59
|
+
</edgeless-tool-icon-button>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
</edgeless-slide-menu>
|
|
63
|
+
`;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=cynefin-menu.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { EmptyTool } from '@blocksuite/affine-gfx-pointer';
|
|
2
|
+
import { LitElement } from 'lit';
|
|
3
|
+
declare const EdgelessCynefinSeniorButton_base: typeof LitElement & import("@blocksuite/global/utils").Constructor<import("@blocksuite/affine-widget-edgeless-toolbar").EdgelessToolbarToolClass>;
|
|
4
|
+
/** Main toolbar button that opens the Cynefin toolbox sub-menu. */
|
|
5
|
+
export declare class EdgelessCynefinSeniorButton extends EdgelessCynefinSeniorButton_base {
|
|
6
|
+
static styles: import("lit").CSSResult;
|
|
7
|
+
enableActiveBackground: boolean;
|
|
8
|
+
type: typeof EmptyTool;
|
|
9
|
+
private _toggleMenu;
|
|
10
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
11
|
+
}
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=cynefin-senior-button.d.ts.map
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
|
2
|
+
import { EmptyTool } from '@blocksuite/affine-gfx-pointer';
|
|
3
|
+
import { EdgelessToolbarToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar';
|
|
4
|
+
import { SignalWatcher } from '@blocksuite/global/lit';
|
|
5
|
+
import { css, html, LitElement } from 'lit';
|
|
6
|
+
import { cynefinToolbarIcon } from './icons';
|
|
7
|
+
/** Main toolbar button that opens the Cynefin toolbox sub-menu. */
|
|
8
|
+
export class EdgelessCynefinSeniorButton extends EdgelessToolbarToolMixin(SignalWatcher(LitElement)) {
|
|
9
|
+
constructor() {
|
|
10
|
+
super(...arguments);
|
|
11
|
+
this.enableActiveBackground = true;
|
|
12
|
+
this.type = EmptyTool;
|
|
13
|
+
}
|
|
14
|
+
static { this.styles = css `
|
|
15
|
+
:host,
|
|
16
|
+
.cynefin-button {
|
|
17
|
+
display: block;
|
|
18
|
+
width: 100%;
|
|
19
|
+
height: 100%;
|
|
20
|
+
}
|
|
21
|
+
:host {
|
|
22
|
+
position: relative;
|
|
23
|
+
}
|
|
24
|
+
.cynefin-root {
|
|
25
|
+
width: 100%;
|
|
26
|
+
height: 64px;
|
|
27
|
+
position: relative;
|
|
28
|
+
overflow: hidden;
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
display: flex;
|
|
31
|
+
align-items: flex-end;
|
|
32
|
+
justify-content: center;
|
|
33
|
+
}
|
|
34
|
+
.cynefin-card {
|
|
35
|
+
--y: 6px;
|
|
36
|
+
--s: 1;
|
|
37
|
+
position: absolute;
|
|
38
|
+
bottom: 0;
|
|
39
|
+
width: 54px;
|
|
40
|
+
height: 54px;
|
|
41
|
+
transform: translateY(var(--y)) scale(var(--s));
|
|
42
|
+
transition: transform 0.3s ease;
|
|
43
|
+
}
|
|
44
|
+
.cynefin-card svg {
|
|
45
|
+
display: block;
|
|
46
|
+
width: 100%;
|
|
47
|
+
height: 100%;
|
|
48
|
+
}
|
|
49
|
+
.cynefin-root:hover .cynefin-card {
|
|
50
|
+
--y: -2px;
|
|
51
|
+
--s: 1.07;
|
|
52
|
+
}
|
|
53
|
+
`; }
|
|
54
|
+
_toggleMenu() {
|
|
55
|
+
if (this.popper) {
|
|
56
|
+
this.popper.dispose();
|
|
57
|
+
this.popper = null;
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
this.setEdgelessTool(DefaultTool);
|
|
61
|
+
const menu = this.createPopper('edgeless-cynefin-menu', this);
|
|
62
|
+
menu.element.edgeless = this.edgeless;
|
|
63
|
+
const el = menu.element;
|
|
64
|
+
const wrap = el.parentElement;
|
|
65
|
+
if (wrap) {
|
|
66
|
+
wrap.style.overflow = 'visible';
|
|
67
|
+
wrap.style.justifyContent = 'flex-end';
|
|
68
|
+
}
|
|
69
|
+
Object.assign(el.style, {
|
|
70
|
+
position: 'static',
|
|
71
|
+
width: 'max-content',
|
|
72
|
+
maxWidth: 'calc(100vw - 16px)',
|
|
73
|
+
marginLeft: '0',
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
render() {
|
|
77
|
+
return html `<edgeless-toolbar-button
|
|
78
|
+
class="cynefin-button"
|
|
79
|
+
.tooltip=${this.popper ? '' : 'Cynefin'}
|
|
80
|
+
.tooltipOffset=${4}
|
|
81
|
+
.active=${!!this.popper}
|
|
82
|
+
@click=${this._toggleMenu}
|
|
83
|
+
>
|
|
84
|
+
<div class="cynefin-root">
|
|
85
|
+
<div class="cynefin-card">${cynefinToolbarIcon}</div>
|
|
86
|
+
</div>
|
|
87
|
+
</edgeless-toolbar-button>`;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=cynefin-senior-button.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { EmptyTool } from '@blocksuite/affine-gfx-pointer';
|
|
2
|
+
import { LitElement } from 'lit';
|
|
3
|
+
declare const EdgelessEstuarineMenu_base: typeof LitElement & import("@blocksuite/global/utils").Constructor<import("@blocksuite/affine-widget-edgeless-toolbar").EdgelessToolbarToolClass>;
|
|
4
|
+
/** The popover above the toolbar: create the Estuarine map or a hexagon node. */
|
|
5
|
+
export declare class EdgelessEstuarineMenu extends EdgelessEstuarineMenu_base {
|
|
6
|
+
static styles: import("lit").CSSResult;
|
|
7
|
+
type: typeof EmptyTool;
|
|
8
|
+
private _finish;
|
|
9
|
+
private _createMap;
|
|
10
|
+
private _createHexagon;
|
|
11
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=estuarine-menu.d.ts.map
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { DefaultTool } from '@blocksuite/affine-block-surface';
|
|
2
|
+
import { EmptyTool } from '@blocksuite/affine-gfx-pointer';
|
|
3
|
+
import { ShapeStyle } from '@blocksuite/affine-model';
|
|
4
|
+
import { EdgelessToolbarToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar';
|
|
5
|
+
import { Bound } from '@blocksuite/global/gfx';
|
|
6
|
+
import { css, html, LitElement } from 'lit';
|
|
7
|
+
import { REF_H, REF_W } from '../estuarine/consts';
|
|
8
|
+
import { estuarineMenuIcon, hexagonMenuIcon } from './icons';
|
|
9
|
+
/** Estuarine map default size (REF aspect, scaled up so it reads on canvas). */
|
|
10
|
+
const MAP_SCALE = 1.2;
|
|
11
|
+
/** Default hexagon node size + fill (a constraint token). */
|
|
12
|
+
const HEX_SIZE = 60;
|
|
13
|
+
const HEX_FILL = '#34c724';
|
|
14
|
+
const HEX_STROKE = '#1f1f1f';
|
|
15
|
+
/** Flat-top regular hexagon, normalized vertices. */
|
|
16
|
+
const HEX_VERTICES = [
|
|
17
|
+
[1, 0.5],
|
|
18
|
+
[0.75, 0.933],
|
|
19
|
+
[0.25, 0.933],
|
|
20
|
+
[0, 0.5],
|
|
21
|
+
[0.25, 0.067],
|
|
22
|
+
[0.75, 0.067],
|
|
23
|
+
];
|
|
24
|
+
/** The popover above the toolbar: create the Estuarine map or a hexagon node. */
|
|
25
|
+
export class EdgelessEstuarineMenu extends EdgelessToolbarToolMixin(LitElement) {
|
|
26
|
+
constructor() {
|
|
27
|
+
super(...arguments);
|
|
28
|
+
this.type = EmptyTool;
|
|
29
|
+
}
|
|
30
|
+
static { this.styles = css `
|
|
31
|
+
:host {
|
|
32
|
+
position: absolute;
|
|
33
|
+
display: flex;
|
|
34
|
+
z-index: -1;
|
|
35
|
+
}
|
|
36
|
+
.menu-content {
|
|
37
|
+
display: flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
justify-content: center;
|
|
40
|
+
}
|
|
41
|
+
.button-group-container {
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: center;
|
|
44
|
+
gap: 14px;
|
|
45
|
+
fill: var(--affine-icon-color);
|
|
46
|
+
}
|
|
47
|
+
.button-group-container svg {
|
|
48
|
+
width: 24px;
|
|
49
|
+
height: 24px;
|
|
50
|
+
}
|
|
51
|
+
`; }
|
|
52
|
+
_finish(id) {
|
|
53
|
+
const { gfx } = this;
|
|
54
|
+
gfx.doc.captureSync();
|
|
55
|
+
gfx.tool.setTool(DefaultTool);
|
|
56
|
+
gfx.selection.set({ elements: [id], editing: false });
|
|
57
|
+
}
|
|
58
|
+
_createMap() {
|
|
59
|
+
const { gfx } = this;
|
|
60
|
+
if (!gfx.surface)
|
|
61
|
+
return;
|
|
62
|
+
const width = REF_W * MAP_SCALE;
|
|
63
|
+
const height = REF_H * MAP_SCALE;
|
|
64
|
+
const { centerX, centerY } = gfx.viewport;
|
|
65
|
+
const id = gfx.surface.addElement({
|
|
66
|
+
type: 'estuarine',
|
|
67
|
+
xywh: new Bound(centerX - width / 2, centerY - height / 2, width, height).serialize(),
|
|
68
|
+
});
|
|
69
|
+
this._finish(id);
|
|
70
|
+
}
|
|
71
|
+
_createHexagon() {
|
|
72
|
+
const { gfx } = this;
|
|
73
|
+
if (!gfx.surface)
|
|
74
|
+
return;
|
|
75
|
+
const { centerX: cx, centerY: cy } = gfx.viewport;
|
|
76
|
+
const id = gfx.surface.addElement({
|
|
77
|
+
type: 'shape',
|
|
78
|
+
shapeType: 'polygon',
|
|
79
|
+
vertices: HEX_VERTICES,
|
|
80
|
+
filled: true,
|
|
81
|
+
fillColor: HEX_FILL,
|
|
82
|
+
strokeColor: HEX_STROKE,
|
|
83
|
+
strokeWidth: 2,
|
|
84
|
+
shapeStyle: ShapeStyle.General,
|
|
85
|
+
roughness: 0,
|
|
86
|
+
xywh: new Bound(cx - HEX_SIZE / 2, cy - HEX_SIZE / 2, HEX_SIZE, HEX_SIZE).serialize(),
|
|
87
|
+
});
|
|
88
|
+
this._finish(id);
|
|
89
|
+
}
|
|
90
|
+
render() {
|
|
91
|
+
return html `
|
|
92
|
+
<edgeless-slide-menu>
|
|
93
|
+
<div class="menu-content">
|
|
94
|
+
<div class="button-group-container">
|
|
95
|
+
<edgeless-tool-icon-button
|
|
96
|
+
.tooltip=${'Estuarine map'}
|
|
97
|
+
@click=${this._createMap}
|
|
98
|
+
>
|
|
99
|
+
${estuarineMenuIcon}
|
|
100
|
+
</edgeless-tool-icon-button>
|
|
101
|
+
<edgeless-tool-icon-button
|
|
102
|
+
.tooltip=${'Hexagon node'}
|
|
103
|
+
@click=${this._createHexagon}
|
|
104
|
+
>
|
|
105
|
+
${hexagonMenuIcon}
|
|
106
|
+
</edgeless-tool-icon-button>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
</edgeless-slide-menu>
|
|
110
|
+
`;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=estuarine-menu.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { EmptyTool } from '@blocksuite/affine-gfx-pointer';
|
|
2
|
+
import { LitElement } from 'lit';
|
|
3
|
+
declare const EdgelessEstuarineSeniorButton_base: typeof LitElement & import("@blocksuite/global/utils").Constructor<import("@blocksuite/affine-widget-edgeless-toolbar").EdgelessToolbarToolClass>;
|
|
4
|
+
/** Main toolbar button that opens the Estuarine toolbox sub-menu. */
|
|
5
|
+
export declare class EdgelessEstuarineSeniorButton extends EdgelessEstuarineSeniorButton_base {
|
|
6
|
+
static styles: import("lit").CSSResult;
|
|
7
|
+
enableActiveBackground: boolean;
|
|
8
|
+
type: typeof EmptyTool;
|
|
9
|
+
private _toggleMenu;
|
|
10
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
11
|
+
}
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=estuarine-senior-button.d.ts.map
|