@miragon/value-chain-renderer 0.7.1 → 0.7.2

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.
Files changed (35) hide show
  1. package/README.md +30 -16
  2. package/dist/bounds/VcBounds.d.ts +6 -4
  3. package/dist/bounds/VcBounds.d.ts.map +1 -1
  4. package/dist/bounds/index.d.ts +1 -1
  5. package/dist/bounds/index.d.ts.map +1 -1
  6. package/dist/collaborative/CollaborativeValueChain.d.ts +5 -4
  7. package/dist/collaborative/CollaborativeValueChain.d.ts.map +1 -1
  8. package/dist/context-pad/VcContextPadProvider.d.ts +1 -1
  9. package/dist/diagram-menu/ShortcutsDialog.d.ts +1 -1
  10. package/dist/diagram-menu/menu.d.ts +3 -3
  11. package/dist/diagram-menu/shortcuts.d.ts +1 -1
  12. package/dist/draw/VcRenderer.d.ts +9 -0
  13. package/dist/draw/VcRenderer.d.ts.map +1 -1
  14. package/dist/draw/canvas2d.d.ts +3 -0
  15. package/dist/draw/canvas2d.d.ts.map +1 -0
  16. package/dist/draw/fill.d.ts +26 -0
  17. package/dist/draw/fill.d.ts.map +1 -0
  18. package/dist/draw/geometry.d.ts +15 -0
  19. package/dist/draw/geometry.d.ts.map +1 -1
  20. package/dist/draw/labelBox.d.ts +15 -0
  21. package/dist/draw/labelBox.d.ts.map +1 -0
  22. package/dist/draw/lucide.d.ts +4 -4
  23. package/dist/draw/styles.d.ts +21 -3
  24. package/dist/draw/styles.d.ts.map +1 -1
  25. package/dist/index.js +712 -487
  26. package/dist/index.js.map +1 -1
  27. package/dist/io/saveSvg.d.ts +1 -1
  28. package/dist/keyboard/VcCanvasKeys.d.ts +19 -0
  29. package/dist/keyboard/VcCanvasKeys.d.ts.map +1 -0
  30. package/dist/keyboard/index.d.ts +4 -1
  31. package/dist/keyboard/index.d.ts.map +1 -1
  32. package/dist/model/VcDiagramElementFactory.d.ts +4 -4
  33. package/dist/model/di-types.d.ts +3 -3
  34. package/dist/popup/VcColorPickerProvider.d.ts.map +1 -1
  35. package/package.json +8 -8
package/README.md CHANGED
@@ -1,17 +1,17 @@
1
1
  # @miragon/value-chain-renderer
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/@miragon/value-chain-renderer)](https://www.npmjs.com/package/@miragon/value-chain-renderer)
4
- [![License: MIT](https://img.shields.io/github/license/Miragon/value-chain-modeler)](https://github.com/Miragon/value-chain-modeler/blob/main/LICENSE)
4
+ [![License: MIT](https://img.shields.io/github/license/Miragon/modeler-suite)](https://github.com/Miragon/modeler-suite/blob/main/modelers/value-chain/LICENSE)
5
5
 
6
6
  Viewer and editor for value chain diagrams (ARIS-style _Wertschöpfungskettendiagramme_), built on
7
7
  [diagram-js](https://github.com/bpmn-io/diagram-js) and styled by the Miragon design system.
8
8
  Framework-agnostic: mount it into any element. The
9
- [Value Chain Modeler](https://github.com/Miragon/value-chain-modeler) web app and VS Code extension
9
+ [Value Chain Modeler](https://github.com/Miragon/modeler-suite/tree/main/modelers/value-chain) web app and VS Code extension
10
10
  both wrap this package, and it implements the
11
11
  [`@miragon/modeler-api`](https://www.npmjs.com/package/@miragon/modeler-api) contract for
12
12
  collaborative hosts.
13
13
 
14
- ![Modeler](https://raw.githubusercontent.com/Miragon/value-chain-modeler/main/docs/screenshot.png)
14
+ ![Modeler](https://raw.githubusercontent.com/Miragon/modeler-suite/main/modelers/value-chain/docs/screenshot.png)
15
15
 
16
16
  ## Install
17
17
 
@@ -26,14 +26,14 @@ diagram-js or Zod breaks the dependency injection and `instanceof` checks.
26
26
  ## Quick start
27
27
 
28
28
  ```ts
29
- import { Modeler } from '@miragon/value-chain-renderer';
30
- import '@miragon/value-chain-renderer/assets/value-chain.css';
31
- import { createEmptyDocument } from '@miragon/value-chain-schema-model';
29
+ import { Modeler } from "@miragon/value-chain-renderer";
30
+ import "@miragon/value-chain-renderer/assets/value-chain.css";
31
+ import { createEmptyDocument } from "@miragon/value-chain-schema-model";
32
32
 
33
- const modeler = new Modeler({ container: document.querySelector('#canvas')! });
34
- modeler.importDocument(createEmptyDocument('My value chain'));
33
+ const modeler = new Modeler({ container: document.querySelector("#canvas")! });
34
+ modeler.importDocument(createEmptyDocument("My value chain"));
35
35
 
36
- modeler.on('commandStack.changed', () => {
36
+ modeler.on("commandStack.changed", () => {
37
37
  const doc = modeler.exportDocument(); // ValueChainDocument
38
38
  });
39
39
 
@@ -45,7 +45,7 @@ The stylesheet is required. It loads, in this order, the design-system tokens
45
45
  diagram-js' own CSS and `cd-canvas.css`, which maps diagram-js' chrome onto the `--cd-ui-*` roles;
46
46
  then it styles the canvas surround, the context pad, the label editor and the shortcuts dialog on
47
47
  those roles only. The three design-system files are vendored unchanged from the
48
- `miragon-brand:modeler-tool-design` skill (design system 1.13.0) into `src/theme/`. The diagram
48
+ `miragon-brand:modeler-tool-design` skill (design system 1.20.1) into `src/theme/`. The diagram
49
49
  itself is drawn with SVG presentation values in the light roles of those tokens, so SVG and PNG
50
50
  exports stay light in every mode.
51
51
 
@@ -99,6 +99,18 @@ Cmd/Ctrl+A select all, the arrows move the selection (Shift: in large steps), Cm
99
99
  the canvas, Delete/Backspace, copy, cut, paste and duplicate, and undo/redo unless `undoRedoKeys` is
100
100
  false. `diagramShortcuts()` lists them for a dialog.
101
101
 
102
+ - The keys act only while the canvas itself has the focus, as diagram-js 15's keyboard binds them
103
+ to the canvas `<svg>`. Keys with nothing focused (`<body>`), on a host's chrome, on the palette,
104
+ the context pad or an editor pass, and so do keys someone already handled (`defaultPrevented`),
105
+ keys of an IME composition and a `keydown` without a key.
106
+ - A pointer on a palette or context-pad entry hands the focus to the canvas before the entry runs,
107
+ so Delete and `Cmd/Ctrl+Z` act at once; a label editor or menu the entry opens takes it from
108
+ there. Enter or Space on an entry leave the focus on it, unless the entry's action left it on
109
+ `<body>`.
110
+ - A host that hides the canvas without destroying the modeler makes its container `inert` or
111
+ `display: none`, not only transparent: a hidden or inert canvas cannot hold the focus, so no key
112
+ reaches it.
113
+
102
114
  ## Edit lock
103
115
 
104
116
  `modeler.get('vcReadOnly').setReadOnly(true)` locks every edit while the document behind the canvas
@@ -112,7 +124,7 @@ lasso, hand, zoom, copy and export keep working.
112
124
  import {
113
125
  createCollaborativeModeler,
114
126
  createCollaborativeViewer,
115
- } from '@miragon/value-chain-renderer';
127
+ } from "@miragon/value-chain-renderer";
116
128
 
117
129
  const modeler = createCollaborativeModeler({ additionalModules: [] });
118
130
  modeler.attachTo(host); // in the document, with a size
@@ -126,10 +138,12 @@ contract 1.3 (`meta.notation` `"value-chain"`): blank text opens as an empty dia
126
138
  diagram-js viewbox, a host's `setViewState` or fit never commits a label being typed, the
127
139
  `elements` surface lists steps and organizational units (name = label) with `reveal`, selection and
128
140
  `bounds(id)`, the live box of a step or an organizational unit in diagram coordinates, and
129
- `contentBounds()` is the live, tight box around every step, organizational unit and connection in
130
- diagram coordinates (`undefined` while the diagram is empty): what a host that fits the view itself
131
- fits to, as `connectDiagramJs(shell, diagram, { modeler, isEmpty })` of `@miragon/modeler-shell`
132
- does. Label text that overflows its shape is not part of the box, as in the SVG export. Both take
141
+ `contentBounds()` is the live, tight box around every step, organizational unit and connection and
142
+ every label, also where a long label runs past a small shape, in diagram coordinates (`undefined`
143
+ while the diagram is empty): what a host that fits the view itself fits to, as
144
+ `connectDiagramJs(shell, diagram, { modeler, isEmpty })` of `@miragon/modeler-shell` does, and what
145
+ the SVG export frames. The renderer measures each label once per content change, so zoom and
146
+ scroll leave the box alone. Both take
133
147
  the contract's factory options `freeArea`, `fitOnImport` and `undoRedoKeys` (the viewer ignores
134
148
  the two that need editing) and the deprecated `freeRectCenter`. The browser test suite runs the
135
149
  contract's conformance kit on every law, with no case skipped and no advisory. `diagram` is the
@@ -156,7 +170,7 @@ shell's empty-file hint.
156
170
 
157
171
  ## License
158
172
 
159
- [MIT](https://github.com/Miragon/value-chain-modeler/blob/main/LICENSE). The inlined
173
+ [MIT](https://github.com/Miragon/modeler-suite/blob/main/modelers/value-chain/LICENSE). The inlined
160
174
  [Lucide](https://lucide.dev) icons are ISC (© Lucide Icons and Contributors); `trash` and `x` derive
161
175
  from Feather, MIT (© Cole Bemis), as Lucide's LICENSE lists them. The bundle keeps both notices as a
162
176
  legal comment.
@@ -1,14 +1,16 @@
1
1
  import { default as ElementRegistry } from 'diagram-js/lib/core/ElementRegistry';
2
2
  import { Bounds } from '@miragon/value-chain-schema-model';
3
+ import { default as VcRenderer } from '../draw/VcRenderer.js';
3
4
  /**
4
- * The extent of the diagram's content: every step, org unit and connection (waypoints included).
5
- * One source for the import's fit, the SVG export's frame and a host's fit, which pass their own
6
- * margin.
5
+ * The extent of the diagram's content: every step, org unit and connection (waypoints included)
6
+ * and every label, also where its text runs past its shape. One source for the import's fit, the
7
+ * SVG export's frame and a host's fit, which pass their own margin.
7
8
  */
8
9
  export default class VcBounds {
9
10
  private readonly elementRegistry;
11
+ private readonly vcRenderer;
10
12
  static $inject: string[];
11
- constructor(elementRegistry: ElementRegistry);
13
+ constructor(elementRegistry: ElementRegistry, vcRenderer: VcRenderer);
12
14
  /** No step and no org unit on the canvas. */
13
15
  isEmpty(): boolean;
14
16
  /** The tight bounds of the content grown by `padding` on every side; undefined while empty. */
@@ -1 +1 @@
1
- {"version":3,"file":"VcBounds.d.ts","sourceRoot":"","sources":["../../src/bounds/VcBounds.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,eAAe,MAAM,qCAAqC,CAAC;AAGvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAGhE;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,QAAQ;IAGf,OAAO,CAAC,QAAQ,CAAC,eAAe;IAF5C,MAAM,CAAC,OAAO,WAAuB;gBAER,eAAe,EAAE,eAAe;IAE7D,6CAA6C;IAC7C,OAAO,IAAI,OAAO;IAIlB,+FAA+F;IAC/F,aAAa,CAAC,OAAO,SAAI,GAAG,MAAM,GAAG,SAAS;CAa/C"}
1
+ {"version":3,"file":"VcBounds.d.ts","sourceRoot":"","sources":["../../src/bounds/VcBounds.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,eAAe,MAAM,qCAAqC,CAAC;AAGvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AAGpD;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,QAAQ;IAIzB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAJ7B,MAAM,CAAC,OAAO,WAAqC;gBAGhC,eAAe,EAAE,eAAe,EAChC,UAAU,EAAE,UAAU;IAGzC,6CAA6C;IAC7C,OAAO,IAAI,OAAO;IAIlB,+FAA+F;IAC/F,aAAa,CAAC,OAAO,SAAI,GAAG,MAAM,GAAG,SAAS;CAiB/C"}
@@ -1,5 +1,5 @@
1
1
  import { ModuleDeclaration } from 'didi';
2
- /** Content bounds of the diagram (import fit, SVG export, a host's fit). */
2
+ /** Content bounds of the diagram (import fit, SVG export, a host's fit), labels included. */
3
3
  export declare const vcBoundsModule: ModuleDeclaration;
4
4
  export { default as VcBounds } from './VcBounds.js';
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bounds/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAG9C,4EAA4E;AAC5E,eAAO,MAAM,cAAc,EAAE,iBAE5B,CAAC;AAEF,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bounds/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAI9C,6FAA6F;AAC7F,eAAO,MAAM,cAAc,EAAE,iBAG5B,CAAC;AAEF,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC"}
@@ -22,11 +22,12 @@ export interface CollaborativeValueChainOptions extends CollaborativeModelerOpti
22
22
  }
23
23
  /** The contract surface plus the wrapped diagram for host-specific wiring. */
24
24
  export interface CollaborativeValueChainModeler extends CollaborativeModeler {
25
- readonly elements: ElementsSurface & Required<Pick<ElementsSurface, 'bounds'>>;
25
+ readonly elements: ElementsSurface & Required<Pick<ElementsSurface, "bounds">>;
26
26
  /**
27
- * The tight box around every step, org unit and connection (waypoints included) in diagram
28
- * coordinates, without a margin of its own; undefined while the diagram has no element. Label
29
- * text that overflows its shape is not part of the box, as in the SVG export.
27
+ * The tight box around every step, org unit and connection (waypoints included) and every label,
28
+ * also where its text runs past its shape, in diagram coordinates, without a margin of its own;
29
+ * undefined while the diagram has no element. The SVG export frames the same box. Labels are
30
+ * measured once per content change, so zoom and scroll leave the box alone.
30
31
  */
31
32
  contentBounds(): ElementBounds | undefined;
32
33
  readonly diagram: Modeler | NavigatedViewer;
@@ -1 +1 @@
1
- {"version":3,"file":"CollaborativeValueChain.d.ts","sourceRoot":"","sources":["../../src/collaborative/CollaborativeValueChain.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAChC,KAAK,aAAa,EAElB,KAAK,eAAe,EAGrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAK9C,OAAO,EAIL,KAAK,KAAK,EAEX,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAKxD,mFAAmF;AACnF,eAAO,MAAM,oBAAoB,gBAAgB,CAAC;AAElD,wEAAwE;AACxE,eAAO,MAAM,mBAAmB,oBAAoB,CAAC;AAErD;;;GAGG;AACH,MAAM,WAAW,8BAA+B,SAAQ,2BAA2B;IACjF,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,iBAAiB,EAAE,GAAG,SAAS,CAAC;IACpD;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;CACxD;AAED,8EAA8E;AAC9E,MAAM,WAAW,8BAA+B,SAAQ,oBAAoB;IAC1E,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC/E;;;;OAIG;IACH,aAAa,IAAI,aAAa,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,CAAC;CAC7C;AASD,uFAAuF;AACvF,wBAAgB,0BAA0B,CACxC,OAAO,GAAE,8BAAmC,GAC3C,8BAA8B,CAUhC;AAED,+FAA+F;AAC/F,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,8BAAmC,GAC3C,8BAA8B,CAEhC"}
1
+ {"version":3,"file":"CollaborativeValueChain.d.ts","sourceRoot":"","sources":["../../src/collaborative/CollaborativeValueChain.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAChC,KAAK,aAAa,EAElB,KAAK,eAAe,EAGrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAK9C,OAAO,EAIL,KAAK,KAAK,EAEX,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAKxD,mFAAmF;AACnF,eAAO,MAAM,oBAAoB,gBAAgB,CAAC;AAElD,wEAAwE;AACxE,eAAO,MAAM,mBAAmB,oBAAoB,CAAC;AAErD;;;GAGG;AACH,MAAM,WAAW,8BAA+B,SAAQ,2BAA2B;IACjF,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,iBAAiB,EAAE,GAAG,SAAS,CAAC;IACpD;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;CACxD;AAED,8EAA8E;AAC9E,MAAM,WAAW,8BAA+B,SAAQ,oBAAoB;IAC1E,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC/E;;;;;OAKG;IACH,aAAa,IAAI,aAAa,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,CAAC;CAC7C;AASD,uFAAuF;AACvF,wBAAgB,0BAA0B,CACxC,OAAO,GAAE,8BAAmC,GAC3C,8BAA8B,CAUhC;AAED,+FAA+F;AAC/F,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,8BAAmC,GAC3C,8BAA8B,CAEhC"}
@@ -21,7 +21,7 @@ export default class VcContextPadProvider {
21
21
  private readonly vcModeling;
22
22
  private readonly readOnly;
23
23
  static $inject: string[];
24
- constructor(contextPad: ContextPad, modeling: Modeling, popupMenu: PopupMenu, vcAppend: VcAppend, vcConnect: VcConnect, vcModeling: VcModeling, readOnly: Pick<VcReadOnly, 'isReadOnly'>);
24
+ constructor(contextPad: ContextPad, modeling: Modeling, popupMenu: PopupMenu, vcAppend: VcAppend, vcConnect: VcConnect, vcModeling: VcModeling, readOnly: Pick<VcReadOnly, "isReadOnly">);
25
25
  getContextPadEntries(element: Element): Entries;
26
26
  getMultiElementContextPadEntries(elements: Element[]): Entries;
27
27
  private addStepEntries;
@@ -3,7 +3,7 @@ import { DiagramShortcutOptions, ShortcutsChrome } from './shortcuts.js';
3
3
  export interface ShortcutsDialogChrome extends ShortcutsChrome {
4
4
  /** Where the dialog lives (the shell root), so it shares the chrome's mode and fonts. */
5
5
  readonly root: HTMLElement;
6
- readonly messages: ShortcutsChrome['messages'] & {
6
+ readonly messages: ShortcutsChrome["messages"] & {
7
7
  readonly close: string;
8
8
  };
9
9
  /** The control the focus returns to once the dialog closes. */
@@ -1,17 +1,17 @@
1
1
  /** The icons the guide gives these entries (guide §5.14, the shell's common set). */
2
- export type DiagramMenuIcon = 'file-image' | 'file-code-corner' | 'keyboard';
2
+ export type DiagramMenuIcon = "file-image" | "file-code-corner" | "keyboard";
3
3
  interface DiagramMenuItem {
4
4
  readonly id: string;
5
5
  readonly label: string;
6
6
  readonly icon?: DiagramMenuIcon;
7
7
  }
8
8
  export interface DiagramMenuAction extends DiagramMenuItem {
9
- readonly kind: 'action';
9
+ readonly kind: "action";
10
10
  readonly shortcut?: string;
11
11
  onSelect(): void;
12
12
  }
13
13
  export interface DiagramMenuDialog extends DiagramMenuItem {
14
- readonly kind: 'dialog';
14
+ readonly kind: "dialog";
15
15
  onSelect(): void;
16
16
  }
17
17
  export interface DiagramMenu {
@@ -1,4 +1,4 @@
1
- export type ShortcutPlatform = 'mac' | 'other';
1
+ export type ShortcutPlatform = "mac" | "other";
2
2
  export interface ShortcutKeyNames {
3
3
  readonly ctrl: string;
4
4
  readonly shift: string;
@@ -3,6 +3,7 @@ import { default as ElementRegistry } from 'diagram-js/lib/core/ElementRegistry'
3
3
  import { default as EventBus } from 'diagram-js/lib/core/EventBus';
4
4
  import { default as GraphicsFactory } from 'diagram-js/lib/core/GraphicsFactory';
5
5
  import { Connection, Element, Shape } from 'diagram-js/lib/model/Types';
6
+ import { Bounds } from '@miragon/value-chain-schema-model';
6
7
  export default class VcRenderer extends BaseRenderer {
7
8
  private readonly elementRegistry;
8
9
  private readonly graphicsFactory;
@@ -10,6 +11,8 @@ export default class VcRenderer extends BaseRenderer {
10
11
  private readonly textUtil;
11
12
  /** Unique per instance so marker ids never collide across diagrams on one page. */
12
13
  private readonly markerSuffix;
14
+ /** Each shape's label box as last drawn, relative to the shape. */
15
+ private readonly labelBoxes;
13
16
  constructor(eventBus: EventBus, elementRegistry: ElementRegistry, graphicsFactory: GraphicsFactory);
14
17
  /**
15
18
  * A label drawn before the web font arrived was measured in the fallback font: its lines sit off
@@ -18,6 +21,12 @@ export default class VcRenderer extends BaseRenderer {
18
21
  private relayoutLabelsWhenTheFontArrives;
19
22
  canRender(element: Element): boolean;
20
23
  drawShape(visuals: SVGElement, element: Shape): SVGElement;
24
+ /**
25
+ * The box the shape's label covers in diagram coordinates, a long label on a small shape well
26
+ * past the shape; undefined without a label. Measured when the shape was last drawn, that is once
27
+ * per content change, so zoom and scroll leave it alone.
28
+ */
29
+ labelBounds(shape: Shape): Bounds | undefined;
21
30
  drawConnection(visuals: SVGElement, element: Connection): SVGElement;
22
31
  getShapePath(shape: Shape): string;
23
32
  getConnectionPath(connection: Connection): string;
@@ -1 +1 @@
1
- {"version":3,"file":"VcRenderer.d.ts","sourceRoot":"","sources":["../../src/draw/VcRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,kCAAkC,CAAC;AAG5D,OAAO,KAAK,eAAe,MAAM,qCAAqC,CAAC;AACvE,OAAO,KAAK,QAAQ,MAAM,8BAA8B,CAAC;AACzD,OAAO,KAAK,eAAe,MAAM,qCAAqC,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAoB7E,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,YAAY;IAiBhD,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAjBlC,MAAM,CAAC,OAAO,WAAsD;IAEpE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAOtB;IAEH,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiC;gBAG5D,QAAQ,EAAE,QAAQ,EACD,eAAe,EAAE,eAAe,EAChC,eAAe,EAAE,eAAe;IAMnD;;;OAGG;IACH,OAAO,CAAC,gCAAgC;IA6B/B,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAIpC,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,GAAG,UAAU;IAqC1D,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,UAAU;IA2BpE,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;IAOlC,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM;IAQ1D,OAAO,CAAC,WAAW;CA+BpB"}
1
+ {"version":3,"file":"VcRenderer.d.ts","sourceRoot":"","sources":["../../src/draw/VcRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,kCAAkC,CAAC;AAG5D,OAAO,KAAK,eAAe,MAAM,qCAAqC,CAAC;AACvE,OAAO,KAAK,QAAQ,MAAM,8BAA8B,CAAC;AACzD,OAAO,KAAK,eAAe,MAAM,qCAAqC,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAE7E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AA2BhE,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,YAAY;IAoBhD,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe;IApBlC,MAAM,CAAC,OAAO,WAAsD;IAEpE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAOtB;IAEH,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiC;IAE9D,mEAAmE;IACnE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgC;gBAGzD,QAAQ,EAAE,QAAQ,EACD,eAAe,EAAE,eAAe,EAChC,eAAe,EAAE,eAAe;IAMnD;;;OAGG;IACH,OAAO,CAAC,gCAAgC;IA6B/B,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAIpC,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,GAAG,UAAU;IAoDnE;;;;OAIG;IACH,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS;IAMpC,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,UAAU;IA2BpE,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;IAOlC,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM;IAQ1D,OAAO,CAAC,WAAW;CA+BpB"}
@@ -0,0 +1,3 @@
1
+ /** One detached 2D canvas context for measuring text and reading colours; null outside a browser. */
2
+ export declare function canvasContext(): CanvasRenderingContext2D | null;
3
+ //# sourceMappingURL=canvas2d.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canvas2d.d.ts","sourceRoot":"","sources":["../../src/draw/canvas2d.ts"],"names":[],"mappings":"AAEA,qGAAqG;AACrG,wBAAgB,aAAa,IAAI,wBAAwB,GAAG,IAAI,CAO/D"}
@@ -0,0 +1,26 @@
1
+ export interface ShapeColors {
2
+ fill: string;
3
+ label: string;
4
+ /**
5
+ * Opaque, the fill as it shows over the plot: a translucent halo would tint the fill a second
6
+ * time around every glyph.
7
+ */
8
+ halo: string;
9
+ }
10
+ /**
11
+ * How a shape with the stored `color` is drawn (guide §10.6): the colour fills the shape and its
12
+ * label is black or white, whichever contrasts more with that fill. The stored value never
13
+ * changes, so a value from an older document (an `hsl()` accent, a colour name) fills the shape
14
+ * too. Without a colour, or with a value that is no CSS colour, the shape takes the plot and ink
15
+ * roles. The contour stays ink either way, and the label's halo is the fill (guide §10.1).
16
+ */
17
+ export declare function shapeColors(color: string | undefined): ShapeColors;
18
+ /**
19
+ * A label line that runs past its shape stands on the surround, not on the fill: ink with the
20
+ * surround's halo (guide §10.1), whatever colour the shape has.
21
+ */
22
+ export declare const SURROUND_LABEL: {
23
+ readonly label: string;
24
+ readonly halo: string;
25
+ };
26
+ //# sourceMappingURL=fill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fill.d.ts","sourceRoot":"","sources":["../../src/draw/fill.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,CAKlE;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc;;;CAAwD,CAAC"}
@@ -15,4 +15,19 @@ export declare function labelInset(width: number, height: number): number;
15
15
  export declare function chevronPathAt(x: number, y: number, width: number, height: number): string;
16
16
  /** Ellipse path (organizational unit), arc-based so cropping intersects exactly. */
17
17
  export declare function ellipsePathAt(x: number, y: number, width: number, height: number): string;
18
+ /** The shape-local span `[left, right]` a step's chevron covers at the height `y`. */
19
+ export declare function chevronSpanAt(width: number, height: number, y: number): [number, number] | undefined;
20
+ /** The shape-local span `[left, right]` an organizational unit's ellipse covers at the height `y`. */
21
+ export declare function ellipseSpanAt(width: number, height: number, y: number): [number, number] | undefined;
22
+ /**
23
+ * Whether a label line, in shape-local coordinates, sits on its shape: whether the shape covers at
24
+ * least half of the line's middle. A line that crosses the shape's edge can take only one colour,
25
+ * so it takes that of the surface under most of it.
26
+ */
27
+ export declare function shapeHoldsLine(orgUnit: boolean, width: number, height: number, line: {
28
+ x: number;
29
+ y: number;
30
+ width: number;
31
+ height: number;
32
+ }): boolean;
18
33
  //# sourceMappingURL=geometry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../src/draw/geometry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED,6DAA6D;AAC7D,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGhE;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAYzF;AAED,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAUzF"}
1
+ {"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../src/draw/geometry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED,6DAA6D;AAC7D,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGhE;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAYzF;AAED,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAUzF;AAED,sFAAsF;AACtF,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,CAAC,EAAE,MAAM,GACR,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAM9B;AAED,sGAAsG;AACtG,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,CAAC,EAAE,MAAM,GACR,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAQ9B;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC5D,OAAO,CAQT"}
@@ -0,0 +1,15 @@
1
+ import { Bounds } from '@miragon/value-chain-schema-model';
2
+ export interface LabelLine {
3
+ element: SVGTSpanElement;
4
+ box: Bounds;
5
+ }
6
+ /**
7
+ * The lines of a laid-out label and the box each covers, in the coordinates of the shape it
8
+ * labels: from its `tspan`'s start and baseline, as wide and as high as a 2D canvas measures it in
9
+ * the label font, which is the measure diagram-js wrapped it by. Never read from the live SVG:
10
+ * Chromium lays SVG text out at the zoomed font size, so that box would change with the zoom.
11
+ * Empty where nothing can be measured.
12
+ */
13
+ export declare function labelLines(text: SVGTextElement): LabelLine[];
14
+ export declare function linesBox(lines: readonly LabelLine[]): Bounds | undefined;
15
+ //# sourceMappingURL=labelBox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"labelBox.d.ts","sourceRoot":"","sources":["../../src/draw/labelBox.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAOhE,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,eAAe,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,SAAS,EAAE,CAsB5D;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,GAAG,SAAS,CAOxE"}
@@ -4,14 +4,14 @@
4
4
  * Derived from Feather, as Lucide's LICENSE lists them: trash and x. Feather @license MIT
5
5
  * Copyright (c) 2013-present Cole Bemis */
6
6
  export declare const LUCIDE: {
7
- readonly 'square-dashed-mouse-pointer': string;
7
+ readonly "square-dashed-mouse-pointer": string;
8
8
  readonly hand: string;
9
- readonly 'unfold-horizontal': string;
9
+ readonly "unfold-horizontal": string;
10
10
  readonly workflow: string;
11
11
  readonly palette: string;
12
12
  readonly trash: string;
13
- readonly 'arrow-left-right': "<path d=\"M8 3 4 7l4 4\"/><path d=\"M4 7h16\"/><path d=\"m16 21 4-4-4-4\"/><path d=\"M20 17H4\"/>";
14
- readonly 'align-start-vertical': string;
13
+ readonly "arrow-left-right": "<path d=\"M8 3 4 7l4 4\"/><path d=\"M4 7h16\"/><path d=\"m16 21 4-4-4-4\"/><path d=\"M20 17H4\"/>";
14
+ readonly "align-start-vertical": string;
15
15
  readonly x: "<path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/>";
16
16
  };
17
17
  export type LucideIconName = keyof typeof LUCIDE;
@@ -1,11 +1,13 @@
1
1
  /**
2
2
  * Canvas colours, the light roles of the vendored design tokens (guide §10.1): contours,
3
- * connections and labels in the text role, element fills in the plot role. The renderer writes
4
- * them as presentation values, so exports look the same everywhere and stay light in every mode.
3
+ * connections and labels in the text role, element fills in the plot role, the surround around the
4
+ * shapes in the grund role. The renderer writes them as presentation values, so exports look the
5
+ * same everywhere and stay light in every mode.
5
6
  */
6
7
  export declare const COLORS: {
7
8
  readonly ink: string;
8
9
  readonly fill: string;
10
+ readonly surround: string;
9
11
  };
10
12
  /**
11
13
  * The family goes onto every SVG text node, since SVG text does not inherit the container's font
@@ -19,9 +21,25 @@ export declare const FONT: {
19
21
  };
20
22
  export declare const STROKE_WIDTH = 2;
21
23
  export declare const LABEL_PADDING = 7;
22
- /** Accent colors offered by the color picker (stroke + label tint; fill stays white). */
24
+ /**
25
+ * The label halo (guide §10.1), 1.5px around every glyph in the surface behind the line: a label
26
+ * line that runs past its shape stays readable where it crosses a neighbour or a connection.
27
+ */
28
+ export declare const LABEL_HALO_WIDTH = 3;
29
+ /**
30
+ * The colour picker (guide §10.6): "Default" stores no colour and follows the roles, then the
31
+ * palette and the status colours as fill colours, each once (success is gruen, info is blau).
32
+ * Blau-link and blau-hell are the link and focus tones of blau, no fill colours (guide §3.1).
33
+ * White is a fixed fill: it looks like Default on the light canvas, not once Default follows a
34
+ * dark plot.
35
+ */
23
36
  export declare const COLOR_OPTIONS: ReadonlyArray<{
24
37
  label: string;
25
38
  color?: string;
26
39
  }>;
40
+ /** Label colours on a fill of the shape's own (guide §10.6), whichever contrasts more. */
41
+ export declare const LABEL_ON_FILL: {
42
+ readonly dark: string;
43
+ readonly light: string;
44
+ };
27
45
  //# sourceMappingURL=styles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/draw/styles.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,MAAM;;;CAGT,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,IAAI;;;;CAIP,CAAC;AAEX,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,eAAO,MAAM,aAAa,IAAI,CAAC;AAE/B,yFAAyF;AACzF,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAO1E,CAAC"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/draw/styles.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,MAAM;;;;CAIT,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,IAAI;;;;CAIP,CAAC;AAEX,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,eAAO,MAAM,aAAa,IAAI,CAAC;AAE/B;;;GAGG;AACH,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAS1E,CAAC;AAEF,0FAA0F;AAC1F,eAAO,MAAM,aAAa;;;CAGhB,CAAC"}