@formicoidea/labre-framework-ddd-core-domain 0.25.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.
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Visual constants for the Core Domain Chart background (DDD Crew). Authored in
3
+ * a fixed reference space (900 × 820) and scaled uniformly to the element bounds
4
+ * by the renderer. Reproduces the supplied template: two axes (Complexity ×
5
+ * Business differentiation), Low/High ticks and the translucent Generic /
6
+ * Supporting / Core zone bands. The "Notation" legend is a separate prefab group.
7
+ */
8
+ export declare const REF_W = 900;
9
+ export declare const REF_H = 820;
10
+ export declare const COLORS: {
11
+ readonly axis: "#000000";
12
+ readonly zoneLabel: "#ffffff";
13
+ readonly tick: "#777777";
14
+ readonly title: "#000000";
15
+ };
16
+ /** Translucent zone bands (drawn at 0.6 alpha), back-to-front. */
17
+ export declare const ZONES: ReadonlyArray<{
18
+ x: number;
19
+ y: number;
20
+ w: number;
21
+ h: number;
22
+ fill: string;
23
+ }>;
24
+ /** Zone names (centred): [text, x, y, fontSize]. */
25
+ export declare const ZONE_LABELS: ReadonlyArray<readonly [string, number, number, number]>;
26
+ /** Axis frame: origin (ox, oy) bottom-left, up to `top`, right to `right`. */
27
+ export declare const AXIS: {
28
+ readonly ox: 60;
29
+ readonly oy: 770;
30
+ readonly top: 24;
31
+ readonly right: 846;
32
+ };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Visual constants for the Core Domain Chart background (DDD Crew). Authored in
3
+ * a fixed reference space (900 × 820) and scaled uniformly to the element bounds
4
+ * by the renderer. Reproduces the supplied template: two axes (Complexity ×
5
+ * Business differentiation), Low/High ticks and the translucent Generic /
6
+ * Supporting / Core zone bands. The "Notation" legend is a separate prefab group.
7
+ */
8
+ export const REF_W = 900;
9
+ export const REF_H = 820;
10
+ export const COLORS = {
11
+ axis: '#000000',
12
+ zoneLabel: '#ffffff',
13
+ tick: '#777777',
14
+ title: '#000000',
15
+ };
16
+ /** Translucent zone bands (drawn at 0.6 alpha), back-to-front. */
17
+ export const ZONES = [
18
+ { x: 70, y: 30, w: 150, h: 720, fill: '#b3b3b3' },
19
+ { x: 220, y: 30, w: 220, h: 720, fill: '#9933ff' },
20
+ { x: 440, y: 30, w: 400, h: 360, fill: '#4d9900' },
21
+ { x: 440, y: 390, w: 400, h: 360, fill: '#9933ff' },
22
+ ];
23
+ /** Zone names (centred): [text, x, y, fontSize]. */
24
+ export const ZONE_LABELS = [
25
+ ['Core', 640, 214, 26],
26
+ ['Supporting', 340, 474, 20],
27
+ ['Generic', 150, 474, 20],
28
+ ];
29
+ /** Axis frame: origin (ox, oy) bottom-left, up to `top`, right to `right`. */
30
+ export const AXIS = { ox: 60, oy: 770, top: 24, right: 846 };
@@ -0,0 +1,12 @@
1
+ import { type ElementRenderer } from '@formicoidea/labre-core/blocks/surface';
2
+ import type { CoreDomainChartElementModel } from '@formicoidea/labre-core/model';
3
+ /**
4
+ * Canvas renderer for the Core Domain Chart background — the translucent
5
+ * Generic / Supporting / Core zone bands, the two axes with arrow heads and the
6
+ * Low/High ticks + zone names. Drawn in the fixed reference space and scaled
7
+ * uniformly to the element bounds.
8
+ */
9
+ export declare const coreDomain: ElementRenderer<CoreDomainChartElementModel>;
10
+ export declare const CoreDomainRendererExtension: import("@formicoidea/labre-core/store").ExtensionType & {
11
+ identifier: import("@formicoidea/labre-core/_pkgs/global/di").ServiceIdentifier<ElementRenderer<CoreDomainChartElementModel>>;
12
+ };
@@ -0,0 +1,93 @@
1
+ import { ElementRendererExtension, } from '@formicoidea/labre-core/blocks/surface';
2
+ import { FONT_FAMILY, refScale } from '@formicoidea/labre-ddd-shared';
3
+ import { AXIS, COLORS, REF_H, REF_W, ZONE_LABELS, ZONES } from './consts';
4
+ /**
5
+ * Canvas renderer for the Core Domain Chart background — the translucent
6
+ * Generic / Supporting / Core zone bands, the two axes with arrow heads and the
7
+ * Low/High ticks + zone names. Drawn in the fixed reference space and scaled
8
+ * uniformly to the element bounds.
9
+ */
10
+ export const coreDomain = (model, ctx, matrix) => {
11
+ const [, , w, h] = model.deserializedXYWH;
12
+ const cx = w / 2;
13
+ const cy = h / 2;
14
+ ctx.setTransform(matrix.translateSelf(cx, cy).rotateSelf(model.rotate).translateSelf(-cx, -cy));
15
+ const { s, ox, oy } = refScale(w, h, REF_W, REF_H);
16
+ ctx.translate(ox, oy);
17
+ ctx.scale(s, s);
18
+ // ── Translucent zone bands ──────────────────────────────────────────
19
+ if (model.showZones) {
20
+ ctx.globalAlpha = 0.6;
21
+ for (const z of ZONES) {
22
+ ctx.fillStyle = z.fill;
23
+ ctx.fillRect(z.x, z.y, z.w, z.h);
24
+ }
25
+ ctx.globalAlpha = 1;
26
+ }
27
+ // ── Axes with arrow heads ───────────────────────────────────────────
28
+ ctx.strokeStyle = COLORS.axis;
29
+ ctx.fillStyle = COLORS.axis;
30
+ ctx.lineWidth = 2;
31
+ ctx.lineJoin = 'round';
32
+ // Y axis (up)
33
+ ctx.beginPath();
34
+ ctx.moveTo(AXIS.ox, AXIS.oy);
35
+ ctx.lineTo(AXIS.ox, AXIS.top + 6);
36
+ ctx.stroke();
37
+ arrow(ctx, AXIS.ox, AXIS.top, 0);
38
+ // X axis (right)
39
+ ctx.beginPath();
40
+ ctx.moveTo(AXIS.ox, AXIS.oy);
41
+ ctx.lineTo(AXIS.right - 6, AXIS.oy);
42
+ ctx.stroke();
43
+ arrow(ctx, AXIS.right, AXIS.oy, 90);
44
+ ctx.textBaseline = 'alphabetic';
45
+ // ── Zone names ──────────────────────────────────────────────────────
46
+ ctx.textAlign = 'center';
47
+ for (const [text, x, y, size] of ZONE_LABELS) {
48
+ ctx.fillStyle = COLORS.zoneLabel;
49
+ ctx.font = `700 ${size}px ${FONT_FAMILY}`;
50
+ ctx.fillText(text, x, y);
51
+ }
52
+ // ── Axis titles + Low/High ticks ────────────────────────────────────
53
+ if (model.showLabels) {
54
+ ctx.fillStyle = COLORS.title;
55
+ ctx.font = `600 14px ${FONT_FAMILY}`;
56
+ ctx.save();
57
+ ctx.translate(28, 400);
58
+ ctx.rotate(-Math.PI / 2);
59
+ ctx.fillText('Complexity', 0, 0);
60
+ ctx.restore();
61
+ ctx.fillText('Business differentiation', 450, 800);
62
+ ctx.fillStyle = COLORS.tick;
63
+ ctx.font = `12px ${FONT_FAMILY}`;
64
+ // X ticks
65
+ ctx.fillText('Low', 84, 792);
66
+ ctx.fillText('High', 838, 792);
67
+ // Y ticks
68
+ ctx.save();
69
+ ctx.translate(48, 758);
70
+ ctx.rotate(-Math.PI / 2);
71
+ ctx.fillText('Low', 0, 0);
72
+ ctx.restore();
73
+ ctx.save();
74
+ ctx.translate(38, 44);
75
+ ctx.rotate(-Math.PI / 2);
76
+ ctx.fillText('High', 0, 0);
77
+ ctx.restore();
78
+ }
79
+ };
80
+ /** Filled triangular arrow head at (x, y); `deg` rotates it (0 = pointing up). */
81
+ function arrow(ctx, x, y, deg) {
82
+ ctx.save();
83
+ ctx.translate(x, y);
84
+ ctx.rotate((deg * Math.PI) / 180);
85
+ ctx.beginPath();
86
+ ctx.moveTo(0, 0);
87
+ ctx.lineTo(-5, 9);
88
+ ctx.lineTo(5, 9);
89
+ ctx.closePath();
90
+ ctx.fill();
91
+ ctx.restore();
92
+ }
93
+ export const CoreDomainRendererExtension = ElementRendererExtension('coreDomain', coreDomain);
@@ -0,0 +1,11 @@
1
+ import type { CoreDomainChartElementModel } from '@formicoidea/labre-core/model';
2
+ import { GfxElementModelView } from '@formicoidea/labre-core/std/gfx';
3
+ /**
4
+ * View for the Core Domain Chart background. Registering it ensures
5
+ * `gfx.view.get(model)` returns a view (required so move / select work).
6
+ */
7
+ export declare class CoreDomainView extends GfxElementModelView<CoreDomainChartElementModel> {
8
+ static type: string;
9
+ }
10
+ /** Resize gating: handles hidden unless `model.resizeEnabled` (toolbar toggle). */
11
+ export declare const CoreDomainInteraction: import("@formicoidea/labre-core/store").ExtensionType;
@@ -0,0 +1,20 @@
1
+ import { GfxElementModelView, GfxViewInteractionExtension, } from '@formicoidea/labre-core/std/gfx';
2
+ /**
3
+ * View for the Core Domain Chart background. Registering it ensures
4
+ * `gfx.view.get(model)` returns a view (required so move / select work).
5
+ */
6
+ export class CoreDomainView extends GfxElementModelView {
7
+ static { this.type = 'coreDomain'; }
8
+ }
9
+ /** Resize gating: handles hidden unless `model.resizeEnabled` (toolbar toggle). */
10
+ export const CoreDomainInteraction = GfxViewInteractionExtension(CoreDomainView.type, {
11
+ handleResize({ model }) {
12
+ return {
13
+ beforeResize({ set }) {
14
+ if (!model.resizeEnabled) {
15
+ set({ allowedHandlers: [] });
16
+ }
17
+ },
18
+ };
19
+ },
20
+ });
@@ -0,0 +1,18 @@
1
+ import { type LegendSection } from '@formicoidea/labre-ddd-shared';
2
+ import { type CoreDomainChartElementModel } from '@formicoidea/labre-core/model';
3
+ import type { BlockStdScope } from '@formicoidea/labre-core/std';
4
+ /**
5
+ * Build the Notation legend sections. When `present` is given (a content-aware
6
+ * scan of the background), only the sub-domain types / team-topology modes /
7
+ * movement actually used are listed; otherwise the full notation is shown.
8
+ */
9
+ export declare function coreDomainLegendSections(present?: {
10
+ fills: Set<string>;
11
+ movement: boolean;
12
+ }): LegendSection[];
13
+ /**
14
+ * Insert a content-aware legend next to a Core Domain background: scans the
15
+ * shapes/connectors inside the background's perimeter and lists only the
16
+ * notation actually present. Triggered from the element's contextual toolbar.
17
+ */
18
+ export declare function createCoreDomainLegend(std: BlockStdScope, bg: CoreDomainChartElementModel): void;
@@ -0,0 +1,68 @@
1
+ import { addLegend, CD_SUBDOMAINS, MOVEMENT_COLOR, TEAM_TOPOLOGIES, } from '@formicoidea/labre-ddd-shared';
2
+ import { ConnectorElementModel, ShapeElementModel, StrokeStyle, } from '@formicoidea/labre-core/model';
3
+ import { Bound } from '@formicoidea/labre-core/global/gfx';
4
+ import { GfxControllerIdentifier } from '@formicoidea/labre-core/std/gfx';
5
+ /**
6
+ * Build the Notation legend sections. When `present` is given (a content-aware
7
+ * scan of the background), only the sub-domain types / team-topology modes /
8
+ * movement actually used are listed; otherwise the full notation is shown.
9
+ */
10
+ export function coreDomainLegendSections(present) {
11
+ const has = (c) => !present || present.fills.has(c.toLowerCase());
12
+ const subRows = CD_SUBDOMAINS.filter(s => has(s.fill)).map(s => ({
13
+ swatch: 'dot',
14
+ color: s.fill,
15
+ label: s.label,
16
+ }));
17
+ const ttRows = TEAM_TOPOLOGIES.filter(t => has(t.fill)).map(t => ({
18
+ swatch: 'square',
19
+ color: t.fill,
20
+ letter: t.letter,
21
+ label: t.label,
22
+ }));
23
+ const sections = [];
24
+ if (subRows.length)
25
+ sections.push({ title: 'Sub-domains', rows: subRows });
26
+ if (ttRows.length)
27
+ sections.push({ title: 'Team topologies', rows: ttRows });
28
+ if (!present || present.movement) {
29
+ sections.push({
30
+ title: 'Movement',
31
+ rows: [{ swatch: 'line', color: MOVEMENT_COLOR, label: 'Movement over time' }],
32
+ });
33
+ }
34
+ // Content-aware scan found nothing recognizable → fall back to the full legend.
35
+ if (present && sections.length === 0)
36
+ return coreDomainLegendSections();
37
+ return sections;
38
+ }
39
+ /**
40
+ * Insert a content-aware legend next to a Core Domain background: scans the
41
+ * shapes/connectors inside the background's perimeter and lists only the
42
+ * notation actually present. Triggered from the element's contextual toolbar.
43
+ */
44
+ export function createCoreDomainLegend(std, bg) {
45
+ const gfx = std.get(GfxControllerIdentifier);
46
+ const surface = gfx.surface;
47
+ if (!surface)
48
+ return;
49
+ const fills = new Set();
50
+ let movement = false;
51
+ for (const el of gfx.getElementsByBound(Bound.deserialize(bg.xywh), {
52
+ type: 'canvas',
53
+ })) {
54
+ if (el instanceof ConnectorElementModel) {
55
+ if (el.strokeStyle === StrokeStyle.Dash)
56
+ movement = true;
57
+ }
58
+ else if (el instanceof ShapeElementModel) {
59
+ if (typeof el.fillColor === 'string')
60
+ fills.add(el.fillColor.toLowerCase());
61
+ }
62
+ }
63
+ const [bx, by, bw] = bg.deserializedXYWH;
64
+ addLegend(surface, std, bx + bw + 30, by, {
65
+ title: 'Légende',
66
+ sections: coreDomainLegendSections({ fills, movement }),
67
+ });
68
+ }
@@ -0,0 +1 @@
1
+ export declare const coreDomainToolbarExtension: import("@formicoidea/labre-core/store").ExtensionType;
@@ -0,0 +1,45 @@
1
+ import { CoreDomainChartElementModel } from '@formicoidea/labre-core/model';
2
+ import { TelemetryProvider, ToolbarModuleExtension, } from '@formicoidea/labre-core/shared/services';
3
+ import { BlockFlavourIdentifier } from '@formicoidea/labre-core/std';
4
+ import { html } from 'lit';
5
+ import { createCoreDomainLegend } from './legend';
6
+ const legendIcon = html `<svg
7
+ width="24"
8
+ height="24"
9
+ viewBox="0 0 24 24"
10
+ fill="none"
11
+ xmlns="http://www.w3.org/2000/svg"
12
+ >
13
+ <rect x="3" y="4" width="18" height="16" rx="2" stroke="currentColor" stroke-width="1.6" />
14
+ <circle cx="7" cy="9" r="1.6" fill="currentColor" />
15
+ <circle cx="7" cy="14" r="1.6" fill="currentColor" />
16
+ <path d="M11 9 H18 M11 14 H18" stroke="currentColor" stroke-width="1.4" />
17
+ </svg>`;
18
+ /** Contextual toolbar for a selected Core Domain background: insert its legend. */
19
+ const coreDomainToolbarConfig = {
20
+ actions: [
21
+ {
22
+ id: 'a.legend',
23
+ tooltip: 'Insert legend (notation present in the chart)',
24
+ icon: legendIcon,
25
+ run(ctx) {
26
+ const bg = ctx.getSurfaceModelsByType(CoreDomainChartElementModel)[0];
27
+ if (!bg)
28
+ return;
29
+ createCoreDomainLegend(ctx.std, bg);
30
+ ctx.std.getOptional(TelemetryProvider)?.track('FrameworkLegendCreated', {
31
+ framework: 'core-domain',
32
+ element: 'legend',
33
+ page: 'whiteboard editor',
34
+ segment: 'element toolbar',
35
+ module: 'core-domain toolbar',
36
+ });
37
+ },
38
+ },
39
+ ],
40
+ when: ctx => ctx.getSurfaceModelsByType(CoreDomainChartElementModel).length > 0,
41
+ };
42
+ export const coreDomainToolbarExtension = ToolbarModuleExtension({
43
+ id: BlockFlavourIdentifier('affine:surface:coreDomain'),
44
+ config: coreDomainToolbarConfig,
45
+ });
@@ -0,0 +1,11 @@
1
+ import { DddCoreDomainRenderViewExtension, DddCoreDomainViewExtension } from './view.js';
2
+ /** Host wiring for the ddd-core-domain framework. */
3
+ export declare const dddCoreDomainFramework: {
4
+ readonly telemetry: "ddd-core-domain";
5
+ readonly extensions: readonly [{
6
+ readonly viewExtension: typeof DddCoreDomainRenderViewExtension;
7
+ }, {
8
+ readonly flag: "ddd-core-domain";
9
+ readonly viewExtension: typeof DddCoreDomainViewExtension;
10
+ }];
11
+ };
@@ -0,0 +1,9 @@
1
+ import { DddCoreDomainRenderViewExtension, DddCoreDomainViewExtension } from './view.js';
2
+ /** Host wiring for the ddd-core-domain framework. */
3
+ export const dddCoreDomainFramework = {
4
+ telemetry: 'ddd-core-domain',
5
+ extensions: [
6
+ { viewExtension: DddCoreDomainRenderViewExtension },
7
+ { flag: 'ddd-core-domain', viewExtension: DddCoreDomainViewExtension },
8
+ ],
9
+ };
@@ -0,0 +1,9 @@
1
+ import { EdgelessDddCoreDomainMenu } from './toolbar/core-domain-menu';
2
+ import { EdgelessDddCoreDomainSeniorButton } from './toolbar/senior-button';
3
+ export declare function coreDomainEffects(): void;
4
+ declare global {
5
+ interface HTMLElementTagNameMap {
6
+ 'edgeless-ddd-core-domain-menu': EdgelessDddCoreDomainMenu;
7
+ 'edgeless-ddd-core-domain-senior-button': EdgelessDddCoreDomainSeniorButton;
8
+ }
9
+ }
@@ -0,0 +1,11 @@
1
+ import { EdgelessDddCoreDomainMenu } from './toolbar/core-domain-menu';
2
+ import { EdgelessDddCoreDomainSeniorButton } from './toolbar/senior-button';
3
+ /** Define a custom element once (each tool's effect may run more than once). */
4
+ function define(tag, ctor) {
5
+ if (!customElements.get(tag))
6
+ customElements.define(tag, ctor);
7
+ }
8
+ export function coreDomainEffects() {
9
+ define('edgeless-ddd-core-domain-menu', EdgelessDddCoreDomainMenu);
10
+ define('edgeless-ddd-core-domain-senior-button', EdgelessDddCoreDomainSeniorButton);
11
+ }
@@ -0,0 +1,5 @@
1
+ export { coreDomain } from './core-domain/element-renderer.js';
2
+ export { coreDomainTemplateCategory } from './templates.js';
3
+ export { coreDomainSeniorTool } from './toolbar/senior-tool.js';
4
+ export { EdgelessDddCoreDomainSeniorButton } from './toolbar/senior-button.js';
5
+ export { DddCoreDomainRenderViewExtension, DddCoreDomainViewExtension, } from './view.js';
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { coreDomain } from './core-domain/element-renderer.js';
2
+ export { coreDomainTemplateCategory } from './templates.js';
3
+ export { coreDomainSeniorTool } from './toolbar/senior-tool.js';
4
+ export { EdgelessDddCoreDomainSeniorButton } from './toolbar/senior-button.js';
5
+ export { DddCoreDomainRenderViewExtension, DddCoreDomainViewExtension, } from './view.js';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Core Domain Chart Templates-panel category. The builder lives in the shared
3
+ * package so the aggregate package can register all DDD categories under the
4
+ * single `ddd-templates` flag; re-exported here for a stable per-package API.
5
+ */
6
+ export { coreDomainTemplateCategory } from '@formicoidea/labre-ddd-shared';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Core Domain Chart Templates-panel category. The builder lives in the shared
3
+ * package so the aggregate package can register all DDD categories under the
4
+ * single `ddd-templates` flag; re-exported here for a stable per-package API.
5
+ */
6
+ export { coreDomainTemplateCategory } from '@formicoidea/labre-ddd-shared';
@@ -0,0 +1,11 @@
1
+ import { DddMenuBase } from '@formicoidea/labre-ddd-shared';
2
+ /** Core Domain Chart palette: the background, sub-domain dots, movement arrow, Notation legend. */
3
+ export declare class EdgelessDddCoreDomainMenu extends DddMenuBase {
4
+ protected framework: "core-domain";
5
+ private _createBackground;
6
+ private _createDot;
7
+ private _createMarker;
8
+ private _createMovement;
9
+ private _createLegend;
10
+ render(): import("lit-html").TemplateResult<1>;
11
+ }
@@ -0,0 +1,116 @@
1
+ import { addConnector, addDot, addLegend, addMarker, CD_SUBDOMAINS, DddMenuBase, MOVEMENT_COLOR, TEAM_TOPOLOGIES, } from '@formicoidea/labre-ddd-shared';
2
+ import { Bound } from '@formicoidea/labre-core/global/gfx';
3
+ import { html, svg } from 'lit';
4
+ import { REF_H, REF_W } from '../core-domain/consts';
5
+ import { coreDomainLegendSections } from '../core-domain/legend';
6
+ const chartSwatch = svg `<svg viewBox="0 0 24 24" fill="none"><rect x="4" y="3" width="17" height="17" fill="#4d9900" fill-opacity="0.5"/><rect x="4" y="3" width="6" height="17" fill="#9933ff" fill-opacity="0.5"/><path d="M4 20 V3 M4 20 H21" stroke="currentColor" stroke-width="1.8"/></svg>`;
7
+ const dotSwatch = (color) => svg `<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="7" fill="${color}" stroke="#1f2328" stroke-width="1.2"/></svg>`;
8
+ const movementSwatch = svg `<svg viewBox="0 0 24 24" fill="none"><path d="M3 18 L16 7" stroke="${MOVEMENT_COLOR}" stroke-width="2" stroke-dasharray="3 3"/><path d="M12 6 L18 5 L17 11" stroke="${MOVEMENT_COLOR}" stroke-width="2" fill="none"/></svg>`;
9
+ const legendSwatch = svg `<svg viewBox="0 0 24 24" fill="none"><rect x="3" y="4" width="18" height="16" rx="2" stroke="currentColor" stroke-width="1.6"/><circle cx="7" cy="9" r="1.6" fill="currentColor"/><circle cx="7" cy="14" r="1.6" fill="currentColor"/><path d="M11 9 H18 M11 14 H18" stroke="currentColor" stroke-width="1.4"/></svg>`;
10
+ const markerSwatch = (fill, letter) => svg `<svg viewBox="0 0 24 24"><rect x="4" y="4" width="16" height="16" rx="3" fill="${fill}" stroke="#1f2328" stroke-width="1.2"/><text x="12" y="16" text-anchor="middle" font-size="11" font-family="sans-serif" fill="#1f2328">${letter}</text></svg>`;
11
+ /** Core Domain Chart palette: the background, sub-domain dots, movement arrow, Notation legend. */
12
+ export class EdgelessDddCoreDomainMenu extends DddMenuBase {
13
+ constructor() {
14
+ super(...arguments);
15
+ this.framework = 'core-domain';
16
+ }
17
+ _createBackground() {
18
+ const surface = this.surface;
19
+ if (!surface)
20
+ return;
21
+ const { cx, cy } = this.center;
22
+ const id = surface.addElement({
23
+ type: 'coreDomain',
24
+ xywh: new Bound(cx - REF_W / 2, cy - REF_H / 2, REF_W, REF_H).serialize(),
25
+ });
26
+ this.track('FrameworkElementAdded', 'background');
27
+ this.finish(id);
28
+ }
29
+ _createDot(preset) {
30
+ const surface = this.surface;
31
+ if (!surface)
32
+ return;
33
+ const { cx, cy } = this.center;
34
+ const id = addDot(surface, this.edgeless.std, cx, cy, preset.fill, preset.label);
35
+ this.track('FrameworkElementAdded', `subdomain:${preset.kind}`);
36
+ this.finish(id);
37
+ }
38
+ _createMarker(preset) {
39
+ const surface = this.surface;
40
+ if (!surface)
41
+ return;
42
+ const { cx, cy } = this.center;
43
+ const id = addMarker(surface, this.edgeless.std, cx, cy, {
44
+ fill: preset.fill,
45
+ letter: preset.letter,
46
+ label: preset.label,
47
+ });
48
+ this.track('FrameworkElementAdded', `team-topology:${preset.kind}`);
49
+ this.finish(id);
50
+ }
51
+ _createMovement() {
52
+ const surface = this.surface;
53
+ if (!surface)
54
+ return;
55
+ const { cx, cy } = this.center;
56
+ const id = addConnector(surface, cx - 80, cy + 60, cx + 80, cy - 60, {
57
+ rearArrow: true,
58
+ dashed: true,
59
+ stroke: MOVEMENT_COLOR,
60
+ });
61
+ this.track('FrameworkElementAdded', 'movement');
62
+ this.finish(id);
63
+ }
64
+ _createLegend() {
65
+ const surface = this.surface;
66
+ if (!surface)
67
+ return;
68
+ const { cx, cy } = this.center;
69
+ const id = addLegend(surface, this.edgeless.std, cx - 130, cy - 170, {
70
+ title: 'Légende',
71
+ sections: coreDomainLegendSections(),
72
+ });
73
+ this.track('FrameworkElementAdded', 'legend');
74
+ this.finish(id);
75
+ }
76
+ render() {
77
+ return html `
78
+ <edgeless-slide-menu>
79
+ <div class="menu-content">
80
+ <div class="button-group-container">
81
+ <edgeless-tool-icon-button
82
+ .tooltip=${'Core Domain Chart'}
83
+ @click=${() => this._createBackground()}
84
+ >
85
+ ${chartSwatch}
86
+ </edgeless-tool-icon-button>
87
+ ${CD_SUBDOMAINS.map(preset => html `<edgeless-tool-icon-button
88
+ .tooltip=${preset.label}
89
+ @click=${() => this._createDot(preset)}
90
+ >
91
+ ${dotSwatch(preset.fill)}
92
+ </edgeless-tool-icon-button>`)}
93
+ ${TEAM_TOPOLOGIES.map(preset => html `<edgeless-tool-icon-button
94
+ .tooltip=${preset.label}
95
+ @click=${() => this._createMarker(preset)}
96
+ >
97
+ ${markerSwatch(preset.fill, preset.letter)}
98
+ </edgeless-tool-icon-button>`)}
99
+ <edgeless-tool-icon-button
100
+ .tooltip=${'Movement over time'}
101
+ @click=${() => this._createMovement()}
102
+ >
103
+ ${movementSwatch}
104
+ </edgeless-tool-icon-button>
105
+ <edgeless-tool-icon-button
106
+ .tooltip=${'Notation legend'}
107
+ @click=${() => this._createLegend()}
108
+ >
109
+ ${legendSwatch}
110
+ </edgeless-tool-icon-button>
111
+ </div>
112
+ </div>
113
+ </edgeless-slide-menu>
114
+ `;
115
+ }
116
+ }
@@ -0,0 +1,6 @@
1
+ import { DddSeniorButtonBase } from '@formicoidea/labre-ddd-shared';
2
+ export declare class EdgelessDddCoreDomainSeniorButton extends DddSeniorButtonBase {
3
+ protected menuTag: "edgeless-ddd-core-domain-menu";
4
+ protected label: string;
5
+ protected icon: import("lit-html").TemplateResult<2>;
6
+ }
@@ -0,0 +1,9 @@
1
+ import { coreDomainToolbarIcon, DddSeniorButtonBase, } from '@formicoidea/labre-ddd-shared';
2
+ export class EdgelessDddCoreDomainSeniorButton extends DddSeniorButtonBase {
3
+ constructor() {
4
+ super(...arguments);
5
+ this.menuTag = 'edgeless-ddd-core-domain-menu';
6
+ this.label = 'Core Domain Chart';
7
+ this.icon = coreDomainToolbarIcon;
8
+ }
9
+ }
@@ -0,0 +1,2 @@
1
+ /** Independent senior tool — Core Domain Chart. */
2
+ export declare const coreDomainSeniorTool: import("@formicoidea/labre-core/store").ExtensionType;
@@ -0,0 +1,9 @@
1
+ import { SeniorToolExtension } from '@formicoidea/labre-core/widgets/edgeless-toolbar';
2
+ import { html } from 'lit';
3
+ /** Independent senior tool — Core Domain Chart. */
4
+ export const coreDomainSeniorTool = SeniorToolExtension('ddd-core-domain', ({ block }) => ({
5
+ name: 'Core Domain Chart',
6
+ content: html `<edgeless-ddd-core-domain-senior-button
7
+ .edgeless=${block}
8
+ ></edgeless-ddd-core-domain-senior-button>`,
9
+ }));
package/dist/view.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ import { type ViewExtensionContext, ViewExtensionProvider } from '@formicoidea/labre-core/ext-loader';
2
+ /**
3
+ * Core Domain Chart rendering — ALWAYS registered, independent of any flag.
4
+ * Disabling `ddd-core-domain` hides only the senior toolbar button (see
5
+ * {@link DddCoreDomainViewExtension}); placed `coreDomain` elements must still
6
+ * paint, stay selectable, and keep their contextual toolbar, and Templates-
7
+ * panel insertion must still render them.
8
+ */
9
+ export declare class DddCoreDomainRenderViewExtension extends ViewExtensionProvider {
10
+ name: string;
11
+ setup(context: ViewExtensionContext): void;
12
+ }
13
+ /**
14
+ * Core Domain Chart senior button — independently flag-gated (`ddd-core-domain`).
15
+ *
16
+ * Note: its Templates-panel category is registered by the aggregate package's
17
+ * {@link DddTemplatesViewExtension} (gated by `ddd-templates`), so templates
18
+ * stay available even when this senior button is disabled.
19
+ */
20
+ export declare class DddCoreDomainViewExtension extends ViewExtensionProvider {
21
+ name: string;
22
+ effect(): void;
23
+ setup(context: ViewExtensionContext): void;
24
+ }
package/dist/view.js ADDED
@@ -0,0 +1,51 @@
1
+ import { ViewExtensionProvider, } from '@formicoidea/labre-core/ext-loader';
2
+ import { CoreDomainRendererExtension } from './core-domain/element-renderer';
3
+ import { CoreDomainInteraction, CoreDomainView } from './core-domain/element-view';
4
+ import { coreDomainToolbarExtension } from './core-domain/toolbar-config';
5
+ import { coreDomainEffects } from './effects';
6
+ import { coreDomainSeniorTool } from './toolbar/senior-tool';
7
+ /**
8
+ * Core Domain Chart rendering — ALWAYS registered, independent of any flag.
9
+ * Disabling `ddd-core-domain` hides only the senior toolbar button (see
10
+ * {@link DddCoreDomainViewExtension}); placed `coreDomain` elements must still
11
+ * paint, stay selectable, and keep their contextual toolbar, and Templates-
12
+ * panel insertion must still render them.
13
+ */
14
+ export class DddCoreDomainRenderViewExtension extends ViewExtensionProvider {
15
+ constructor() {
16
+ super(...arguments);
17
+ this.name = 'affine-ddd-core-domain-render-gfx';
18
+ }
19
+ setup(context) {
20
+ super.setup(context);
21
+ context.register(CoreDomainView);
22
+ context.register(CoreDomainRendererExtension);
23
+ if (this.isEdgeless(context.scope)) {
24
+ context.register(CoreDomainInteraction);
25
+ context.register(coreDomainToolbarExtension);
26
+ }
27
+ }
28
+ }
29
+ /**
30
+ * Core Domain Chart senior button — independently flag-gated (`ddd-core-domain`).
31
+ *
32
+ * Note: its Templates-panel category is registered by the aggregate package's
33
+ * {@link DddTemplatesViewExtension} (gated by `ddd-templates`), so templates
34
+ * stay available even when this senior button is disabled.
35
+ */
36
+ export class DddCoreDomainViewExtension extends ViewExtensionProvider {
37
+ constructor() {
38
+ super(...arguments);
39
+ this.name = 'affine-ddd-core-domain-gfx';
40
+ }
41
+ effect() {
42
+ super.effect();
43
+ coreDomainEffects();
44
+ }
45
+ setup(context) {
46
+ super.setup(context);
47
+ if (this.isEdgeless(context.scope)) {
48
+ context.register(coreDomainSeniorTool);
49
+ }
50
+ }
51
+ }
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@formicoidea/labre-framework-ddd-core-domain",
3
+ "description": "Labre ddd-core-domain framework for @formicoidea/labre-core.",
4
+ "version": "0.25.0",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "author": "lajola",
8
+ "contributors": [
9
+ "toeverything"
10
+ ],
11
+ "license": "MPL-2.0",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ },
17
+ "./view": {
18
+ "types": "./dist/view.d.ts",
19
+ "import": "./dist/view.js"
20
+ },
21
+ "./descriptor": {
22
+ "types": "./dist/descriptor.d.ts",
23
+ "import": "./dist/descriptor.js"
24
+ }
25
+ },
26
+ "files": [
27
+ "dist"
28
+ ],
29
+ "dependencies": {
30
+ "@formicoidea/labre-core": "0.25.0",
31
+ "@formicoidea/labre-ddd-shared": "0.25.0",
32
+ "lit": "^3.2.0"
33
+ }
34
+ }