@formicoidea/labre-framework-edgy 0.35.0 → 0.37.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/commands.js +2 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -0
- package/dist/reading.d.ts +44 -0
- package/dist/reading.js +64 -0
- package/dist/toolbar/node-config.js +3 -113
- package/dist/translations.js +7 -1
- package/dist/view.js +9 -1
- package/package.json +3 -3
package/dist/commands.js
CHANGED
|
@@ -24,6 +24,7 @@ const SPECS = [
|
|
|
24
24
|
iconKey: 'edgy.board',
|
|
25
25
|
category: 'diagrams',
|
|
26
26
|
element: 'board',
|
|
27
|
+
board: true,
|
|
27
28
|
run: createEdgyBoard,
|
|
28
29
|
},
|
|
29
30
|
{
|
|
@@ -89,7 +90,7 @@ export const edgyCommands = SPECS.map((spec, order) => ({
|
|
|
89
90
|
defaultKeys: { mac: [], other: [] },
|
|
90
91
|
availability: 'always',
|
|
91
92
|
run: spec.run,
|
|
92
|
-
telemetry: { framework: 'edgy', element: spec.element },
|
|
93
|
+
telemetry: { framework: 'edgy', element: spec.element, board: spec.board },
|
|
93
94
|
}));
|
|
94
95
|
export const edgyCommandIcons = {
|
|
95
96
|
'edgy.facets': edgyFacetsIcon,
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
export { edgyCommandIcons, edgyCommands } from './commands.js';
|
|
2
2
|
export { edgyTranslationEntries } from './translations.js';
|
|
3
|
+
// The role vocabulary and the reading profile: DATA a host — and the
|
|
4
|
+
// library's own cross-framework guard test — can read without an editor.
|
|
5
|
+
export { EDGY_ROLE, EDGY_ROLES } from './roles.js';
|
|
6
|
+
export { EDGY_READING } from './reading.js';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ReadingProfile } from '@formicoidea/labre-core/blocks/surface';
|
|
2
|
+
/**
|
|
3
|
+
* What EDGY lets the tool read of an element (MF3, the reversed reading).
|
|
4
|
+
*
|
|
5
|
+
* DATA, like the rules and the profiles beside it: the engine
|
|
6
|
+
* (`@labre/affine-block-surface`) knows how to read a role and a typed edge — it
|
|
7
|
+
* knows nothing about EDGY. Everything below is already stated in `roles.ts` and
|
|
8
|
+
* is merely POINTED AT here.
|
|
9
|
+
*
|
|
10
|
+
* Registered from the FLAG-GATED view extension: reading a board is tooling, so
|
|
11
|
+
* a board whose EDGY flag is off keeps every element it has and simply stops
|
|
12
|
+
* being read (ADR 0009).
|
|
13
|
+
*
|
|
14
|
+
* ## One subject, sixteen kinds
|
|
15
|
+
*
|
|
16
|
+
* `edgy:element` is the root of the four persisted kinds and the twelve official
|
|
17
|
+
* elements, and `readingProfileFor` resolves through `roleIsA` — so one profile
|
|
18
|
+
* reads all sixteen, and the panel's type line says which one AND the chain
|
|
19
|
+
* above it ("Journey › Activity › Element"). The three FRAMES (`edgy:background`
|
|
20
|
+
* and its two children) stay out for the reason they are not children of
|
|
21
|
+
* `edgy:element`: a reading is about an artefact, never about the sheet it is
|
|
22
|
+
* drawn on.
|
|
23
|
+
*
|
|
24
|
+
* ## No nature, no phase
|
|
25
|
+
*
|
|
26
|
+
* EDGY ships no type-3 tag pack: its kinds ARE the roles, and the panel already
|
|
27
|
+
* says them on the type line. And its board declares no zones — the facets
|
|
28
|
+
* diagram is a legend, not a plotted axis — so there is nothing a position could
|
|
29
|
+
* be read against. Both sections are therefore absent rather than empty, which
|
|
30
|
+
* is the whole discipline of this feature: a reading offers what the document
|
|
31
|
+
* states and never a heading with nothing under it.
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* ## Why the two sides are named after the DIRECTION and not after a verb
|
|
35
|
+
*
|
|
36
|
+
* EDGY has 22 canonical verbs and the relation between two elements is entirely
|
|
37
|
+
* determined by the pair they run between (`EDGY_PAIR_TO_VERB`). There is no one
|
|
38
|
+
* word that names "what this element points at" across "requires", "is part of"
|
|
39
|
+
* and "delivers" — so the panel says the only thing that is true of all 22:
|
|
40
|
+
* which way the arrow runs. ADR 0010 tier 1 fixes what that means — the source
|
|
41
|
+
* is the subject of the verb — and the verb itself is already on the link's own
|
|
42
|
+
* chip, where the user drew it.
|
|
43
|
+
*/
|
|
44
|
+
export declare const EDGY_READING: ReadingProfile;
|
package/dist/reading.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { EDGY_ROLE, EDGY_ROLES } from './roles.js';
|
|
2
|
+
/**
|
|
3
|
+
* What EDGY lets the tool read of an element (MF3, the reversed reading).
|
|
4
|
+
*
|
|
5
|
+
* DATA, like the rules and the profiles beside it: the engine
|
|
6
|
+
* (`@labre/affine-block-surface`) knows how to read a role and a typed edge — it
|
|
7
|
+
* knows nothing about EDGY. Everything below is already stated in `roles.ts` and
|
|
8
|
+
* is merely POINTED AT here.
|
|
9
|
+
*
|
|
10
|
+
* Registered from the FLAG-GATED view extension: reading a board is tooling, so
|
|
11
|
+
* a board whose EDGY flag is off keeps every element it has and simply stops
|
|
12
|
+
* being read (ADR 0009).
|
|
13
|
+
*
|
|
14
|
+
* ## One subject, sixteen kinds
|
|
15
|
+
*
|
|
16
|
+
* `edgy:element` is the root of the four persisted kinds and the twelve official
|
|
17
|
+
* elements, and `readingProfileFor` resolves through `roleIsA` — so one profile
|
|
18
|
+
* reads all sixteen, and the panel's type line says which one AND the chain
|
|
19
|
+
* above it ("Journey › Activity › Element"). The three FRAMES (`edgy:background`
|
|
20
|
+
* and its two children) stay out for the reason they are not children of
|
|
21
|
+
* `edgy:element`: a reading is about an artefact, never about the sheet it is
|
|
22
|
+
* drawn on.
|
|
23
|
+
*
|
|
24
|
+
* ## No nature, no phase
|
|
25
|
+
*
|
|
26
|
+
* EDGY ships no type-3 tag pack: its kinds ARE the roles, and the panel already
|
|
27
|
+
* says them on the type line. And its board declares no zones — the facets
|
|
28
|
+
* diagram is a legend, not a plotted axis — so there is nothing a position could
|
|
29
|
+
* be read against. Both sections are therefore absent rather than empty, which
|
|
30
|
+
* is the whole discipline of this feature: a reading offers what the document
|
|
31
|
+
* states and never a heading with nothing under it.
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* ## Why the two sides are named after the DIRECTION and not after a verb
|
|
35
|
+
*
|
|
36
|
+
* EDGY has 22 canonical verbs and the relation between two elements is entirely
|
|
37
|
+
* determined by the pair they run between (`EDGY_PAIR_TO_VERB`). There is no one
|
|
38
|
+
* word that names "what this element points at" across "requires", "is part of"
|
|
39
|
+
* and "delivers" — so the panel says the only thing that is true of all 22:
|
|
40
|
+
* which way the arrow runs. ADR 0010 tier 1 fixes what that means — the source
|
|
41
|
+
* is the subject of the verb — and the verb itself is already on the link's own
|
|
42
|
+
* chip, where the user drew it.
|
|
43
|
+
*/
|
|
44
|
+
export const EDGY_READING = {
|
|
45
|
+
id: 'edgy',
|
|
46
|
+
framework: 'edgy',
|
|
47
|
+
roles: EDGY_ROLES,
|
|
48
|
+
appliesTo: EDGY_ROLE.element,
|
|
49
|
+
relation: {
|
|
50
|
+
// The parent of the 22 verb roles: a rule of `roleIsA` away from every one
|
|
51
|
+
// of them, which is why the vocabulary declares it.
|
|
52
|
+
edgeRole: EDGY_ROLE.relation,
|
|
53
|
+
sides: {
|
|
54
|
+
consumer: {
|
|
55
|
+
labelKey: 'com.labre.edgy.reading.relations.consumer',
|
|
56
|
+
labelFallback: 'Incoming relations',
|
|
57
|
+
},
|
|
58
|
+
supplier: {
|
|
59
|
+
labelKey: 'com.labre.edgy.reading.relations.supplier',
|
|
60
|
+
labelFallback: 'Outgoing relations',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
};
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { packColor, } from '@formicoidea/labre-core/components/color-picker';
|
|
3
|
-
import { shapeToolbarConfig } from '@formicoidea/labre-core/gfx/shape';
|
|
4
|
-
import { DefaultTheme, isTransparent, LineWidth, resolveColor, ShapeElementModel, StrokeStyle, } from '@formicoidea/labre-core/model';
|
|
1
|
+
import { neutralPalettes, paletteColorAction, shapeToolbarConfig, } from '@formicoidea/labre-core/gfx/shape';
|
|
5
2
|
import { ToolbarModuleExtension, } from '@formicoidea/labre-core/shared/services';
|
|
6
|
-
import { getMostCommonValue } from '@formicoidea/labre-core/shared/utils';
|
|
7
3
|
import { BlockFlavourIdentifier } from '@formicoidea/labre-core/std';
|
|
8
|
-
import { html } from 'lit';
|
|
9
4
|
/**
|
|
10
5
|
* The typical EDGY palette, surfaced as ready-made swatches in the EDGY node
|
|
11
6
|
* color picker (facet + intersection colours, saturated then pastel), followed
|
|
@@ -30,117 +25,12 @@ const EDGY_PALETTES = [
|
|
|
30
25
|
* black, transparent) — the historical colours are dropped in favour of the
|
|
31
26
|
* EDGY swatches above.
|
|
32
27
|
*/
|
|
33
|
-
const
|
|
34
|
-
const EDGY_PALETTE_LIST = [
|
|
35
|
-
...EDGY_PALETTES,
|
|
36
|
-
...DefaultTheme.Palettes.filter(p => NEUTRAL_KEY.test(p.key)),
|
|
37
|
-
];
|
|
38
|
-
// Mirror of the shape color action's text-color rule.
|
|
39
|
-
function getTextColor(fillColor) {
|
|
40
|
-
if (fillColor === DefaultTheme.black)
|
|
41
|
-
return DefaultTheme.white;
|
|
42
|
-
if (fillColor === DefaultTheme.white)
|
|
43
|
-
return DefaultTheme.black;
|
|
44
|
-
return DefaultTheme.shapeTextColor;
|
|
45
|
-
}
|
|
28
|
+
const EDGY_PALETTE_LIST = [...EDGY_PALETTES, ...neutralPalettes()];
|
|
46
29
|
/**
|
|
47
30
|
* EDGY fill / stroke colour picker — identical to the shape one but seeded with
|
|
48
31
|
* the EDGY palette swatches (`.palettes`).
|
|
49
32
|
*/
|
|
50
|
-
const edgyColorAction =
|
|
51
|
-
id: 'e.color',
|
|
52
|
-
when(ctx) {
|
|
53
|
-
return ctx.getSurfaceModelsByType(ShapeElementModel).length > 0;
|
|
54
|
-
},
|
|
55
|
-
content(ctx) {
|
|
56
|
-
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
|
57
|
-
if (!models.length)
|
|
58
|
-
return null;
|
|
59
|
-
const enableCustomColor = ctx.features.getFlag('enable_color_picker');
|
|
60
|
-
const theme = ctx.theme.edgeless$.value;
|
|
61
|
-
const firstModel = models[0];
|
|
62
|
-
const originalFillColor = firstModel.fillColor;
|
|
63
|
-
const originalStrokeColor = firstModel.strokeColor;
|
|
64
|
-
const mapped = models.map(({ filled, fillColor, strokeColor, strokeWidth, strokeStyle }) => ({
|
|
65
|
-
fillColor: filled
|
|
66
|
-
? resolveColor(fillColor, theme)
|
|
67
|
-
: DefaultTheme.transparent,
|
|
68
|
-
strokeColor: resolveColor(strokeColor, theme),
|
|
69
|
-
strokeWidth,
|
|
70
|
-
strokeStyle,
|
|
71
|
-
}));
|
|
72
|
-
const fillColor = getMostCommonValue(mapped, 'fillColor') ??
|
|
73
|
-
resolveColor(DefaultTheme.shapeFillColor, theme);
|
|
74
|
-
const strokeColor = getMostCommonValue(mapped, 'strokeColor') ??
|
|
75
|
-
resolveColor(DefaultTheme.shapeStrokeColor, theme);
|
|
76
|
-
const strokeWidth = getMostCommonValue(mapped, 'strokeWidth') ?? LineWidth.Four;
|
|
77
|
-
const strokeStyle = getMostCommonValue(mapped, 'strokeStyle') ?? StrokeStyle.Solid;
|
|
78
|
-
const pickColorWrapper = (field, pickCallback) => (e) => {
|
|
79
|
-
e.stopPropagation();
|
|
80
|
-
switch (e.detail.type) {
|
|
81
|
-
case 'pick':
|
|
82
|
-
pickCallback(e.detail.detail);
|
|
83
|
-
break;
|
|
84
|
-
case 'start':
|
|
85
|
-
ctx.store.captureSync();
|
|
86
|
-
models.forEach(model => model.stash(field));
|
|
87
|
-
break;
|
|
88
|
-
case 'end':
|
|
89
|
-
ctx.store.transact(() => {
|
|
90
|
-
models.forEach(model => model.pop(field));
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
const onPickFillColor = pickColorWrapper('fillColor', palette => {
|
|
95
|
-
const value = palette.value;
|
|
96
|
-
const filled = isTransparent(value);
|
|
97
|
-
const props = packColor('fillColor', value);
|
|
98
|
-
const crud = ctx.std.get(EdgelessCRUDIdentifier);
|
|
99
|
-
models.forEach(model => {
|
|
100
|
-
if (filled && !model.filled) {
|
|
101
|
-
const color = getTextColor(value);
|
|
102
|
-
Object.assign(props, { filled, color });
|
|
103
|
-
}
|
|
104
|
-
crud.updateElement(model.id, props);
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
const onPickStrokeColor = pickColorWrapper('strokeColor', palette => {
|
|
108
|
-
const props = packColor('strokeColor', palette.value);
|
|
109
|
-
const crud = ctx.std.get(EdgelessCRUDIdentifier);
|
|
110
|
-
models.forEach(model => crud.updateElement(model.id, props));
|
|
111
|
-
});
|
|
112
|
-
const onPickStrokeStyle = (e) => {
|
|
113
|
-
e.stopPropagation();
|
|
114
|
-
const { type, value } = e.detail;
|
|
115
|
-
const crud = ctx.std.get(EdgelessCRUDIdentifier);
|
|
116
|
-
const props = type === 'size'
|
|
117
|
-
? { strokeWidth: value }
|
|
118
|
-
: { strokeStyle: value };
|
|
119
|
-
for (const model of models) {
|
|
120
|
-
crud.updateElement(model.id, props);
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
return html `
|
|
124
|
-
<edgeless-shape-color-picker
|
|
125
|
-
@pickFillColor=${onPickFillColor}
|
|
126
|
-
@pickStrokeColor=${onPickStrokeColor}
|
|
127
|
-
@pickStrokeStyle=${onPickStrokeStyle}
|
|
128
|
-
.palettes=${EDGY_PALETTE_LIST}
|
|
129
|
-
.payload=${{
|
|
130
|
-
fillColor,
|
|
131
|
-
strokeColor,
|
|
132
|
-
strokeWidth,
|
|
133
|
-
strokeStyle,
|
|
134
|
-
originalFillColor,
|
|
135
|
-
originalStrokeColor,
|
|
136
|
-
theme,
|
|
137
|
-
enableCustomColor,
|
|
138
|
-
}}
|
|
139
|
-
>
|
|
140
|
-
</edgeless-shape-color-picker>
|
|
141
|
-
`;
|
|
142
|
-
},
|
|
143
|
-
};
|
|
33
|
+
const edgyColorAction = paletteColorAction('e.color', EDGY_PALETTE_LIST);
|
|
144
34
|
/**
|
|
145
35
|
* EDGY nodes are {@link ShapeElementModel} subclasses, so the shape toolbar's
|
|
146
36
|
* actions operate on them directly. We reuse the line-style + text actions, add
|
package/dist/translations.js
CHANGED
|
@@ -3,6 +3,7 @@ import { edgyCommands } from './commands.js';
|
|
|
3
3
|
import { NODE_LABEL, nodeLabelKey } from './node/consts.js';
|
|
4
4
|
import { EDGY_NUDGES } from './nudges.js';
|
|
5
5
|
import { EDGY_PROFILES } from './profiles.js';
|
|
6
|
+
import { EDGY_READING } from './reading.js';
|
|
6
7
|
import { EDGY_ROLES } from './roles.js';
|
|
7
8
|
import { EDGY_RULES } from './rules.js';
|
|
8
9
|
/**
|
|
@@ -41,4 +42,9 @@ Object.entries(NODE_LABEL).map(([kind, label]) => ({
|
|
|
41
42
|
key: nodeLabelKey(kind),
|
|
42
43
|
fallback: label,
|
|
43
44
|
source: 'seed',
|
|
44
|
-
}))
|
|
45
|
+
})),
|
|
46
|
+
// LAST, and the order is load-bearing: a reading profile carries the
|
|
47
|
+
// framework's own `roles`, so walking it reaches every role key the line
|
|
48
|
+
// above already named. `mergeTranslationEntries` keeps the FIRST
|
|
49
|
+
// occurrence, which is what makes each key report the source it comes from.
|
|
50
|
+
collectTranslationKeys('reading', EDGY_READING));
|
package/dist/view.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { QualityNudgeExtension, SpotlightHostExtension, ValidationProfileExtension, ValidationRuleExtension, validationToolbarConfig, } from '@formicoidea/labre-core/blocks/surface';
|
|
1
|
+
import { QualityNudgeExtension, ReadingProfileExtension, SpotlightHostExtension, ValidationProfileExtension, ValidationRuleExtension, validationToolbarConfig, } from '@formicoidea/labre-core/blocks/surface';
|
|
2
2
|
import { ToolbarModuleExtension } from '@formicoidea/labre-core/shared/services';
|
|
3
3
|
import { ViewExtensionProvider, } from '@formicoidea/labre-core/ext-loader';
|
|
4
4
|
import { extendTemplateCategory } from '@formicoidea/labre-core/gfx/template';
|
|
@@ -8,6 +8,7 @@ import { edgyCommandIcons, edgyCommands } from './commands.js';
|
|
|
8
8
|
import { effects } from './effects.js';
|
|
9
9
|
import { EDGY_NUDGES } from './nudges.js';
|
|
10
10
|
import { EDGY_PROFILES } from './profiles.js';
|
|
11
|
+
import { EDGY_READING } from './reading.js';
|
|
11
12
|
import { EdgyRelationResolver } from './relation-resolver.js';
|
|
12
13
|
import { EDGY_ROLES } from './roles.js';
|
|
13
14
|
import { EDGY_RULES } from './rules.js';
|
|
@@ -114,6 +115,13 @@ export class EdgyViewExtension extends ViewExtensionProvider {
|
|
|
114
115
|
// the renderers are always on); with the flag off nothing new is named
|
|
115
116
|
// because nothing new is being armed. See `./relation-resolver.ts`.
|
|
116
117
|
context.register(EdgyRelationResolver);
|
|
118
|
+
// The reversed reading (MF3): what the board says about an element, on
|
|
119
|
+
// demand. One declaration — the roles and the relation edge, both already
|
|
120
|
+
// stated elsewhere in this framework — is the whole of what makes the
|
|
121
|
+
// generic engine able to read an EDGY board. The CLICK that triggers it is
|
|
122
|
+
// registered once by the surface and gated by the presence of this
|
|
123
|
+
// profile, so it goes with the flag without either side naming the other.
|
|
124
|
+
context.register(ReadingProfileExtension(EDGY_READING));
|
|
117
125
|
context.register(edgySeniorTool);
|
|
118
126
|
// The eight EDGY commands: the sub-menu renders them, Settings ›
|
|
119
127
|
// Shortcuts finally lists them, and a host override on an id binds.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formicoidea/labre-framework-edgy",
|
|
3
3
|
"description": "Labre edgy framework for @formicoidea/labre-core.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.37.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"author": "lajola",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"dist"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@formicoidea/labre-core": "0.
|
|
35
|
-
"@formicoidea/labre-ddd-shared": "0.
|
|
34
|
+
"@formicoidea/labre-core": "0.37.0",
|
|
35
|
+
"@formicoidea/labre-ddd-shared": "0.37.0",
|
|
36
36
|
"@preact/signals-core": "^1.8.0",
|
|
37
37
|
"lit": "^3.2.0",
|
|
38
38
|
"yjs": "^13.6.21"
|