orcasvn-react-diagrams 0.2.4 → 0.2.6

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 (75) hide show
  1. package/CHANGELOG.md +42 -4
  2. package/README.md +15 -32
  3. package/ai/api-contract.json +88 -3
  4. package/ai/manifest.json +1 -1
  5. package/dist/cjs/examples.js +6519 -4423
  6. package/dist/cjs/index.js +1513 -120
  7. package/dist/cjs/types/api/createDiagramEditor.d.ts +4 -1
  8. package/dist/cjs/types/api/types.d.ts +43 -1
  9. package/dist/cjs/types/displaybox/demos/LinkColorPoolDemoTab.d.ts +3 -0
  10. package/dist/cjs/types/displaybox/demos/OffsetAnchorAvoidanceDemoTab.d.ts +3 -0
  11. package/dist/cjs/types/displaybox/demos/SimpleDemo.d.ts +4 -1
  12. package/dist/cjs/types/displaybox/demos/ZoomToFitElementsDemoTab.d.ts +3 -0
  13. package/dist/cjs/types/displaybox/demos/linkColorPoolDemo.d.ts +2 -0
  14. package/dist/cjs/types/displaybox/demos/offsetAnchorAvoidanceDemo.d.ts +4 -0
  15. package/dist/cjs/types/displaybox/demos/textDemo.d.ts +3 -0
  16. package/dist/cjs/types/displaybox/demos/zoomToFitElementsDemo.d.ts +4 -0
  17. package/dist/cjs/types/displaybox/types.d.ts +3 -1
  18. package/dist/cjs/types/displaybox/useDemoEditor.d.ts +4 -2
  19. package/dist/cjs/types/engine/AutoLayoutService.d.ts +59 -2
  20. package/dist/cjs/types/engine/DiagramEngine.d.ts +20 -1
  21. package/dist/cjs/types/engine/LinkRoutingService.d.ts +9 -0
  22. package/dist/cjs/types/models/TextModel.d.ts +1 -0
  23. package/dist/cjs/types/renderer/konva/KonvaInteraction.d.ts +6 -0
  24. package/dist/cjs/types/strategies/ObstacleRouter.d.ts +2 -0
  25. package/dist/cjs/types/strategies/RouterStrategy.d.ts +10 -0
  26. package/dist/esm/examples.js +6519 -4423
  27. package/dist/esm/examples.js.map +1 -1
  28. package/dist/esm/index.js +1513 -120
  29. package/dist/esm/index.js.map +1 -1
  30. package/dist/esm/types/api/createDiagramEditor.d.ts +4 -1
  31. package/dist/esm/types/api/types.d.ts +43 -1
  32. package/dist/esm/types/displaybox/demos/LinkColorPoolDemoTab.d.ts +3 -0
  33. package/dist/esm/types/displaybox/demos/OffsetAnchorAvoidanceDemoTab.d.ts +3 -0
  34. package/dist/esm/types/displaybox/demos/SimpleDemo.d.ts +4 -1
  35. package/dist/esm/types/displaybox/demos/ZoomToFitElementsDemoTab.d.ts +3 -0
  36. package/dist/esm/types/displaybox/demos/linkColorPoolDemo.d.ts +2 -0
  37. package/dist/esm/types/displaybox/demos/offsetAnchorAvoidanceDemo.d.ts +4 -0
  38. package/dist/esm/types/displaybox/demos/textDemo.d.ts +3 -0
  39. package/dist/esm/types/displaybox/demos/zoomToFitElementsDemo.d.ts +4 -0
  40. package/dist/esm/types/displaybox/types.d.ts +3 -1
  41. package/dist/esm/types/displaybox/useDemoEditor.d.ts +4 -2
  42. package/dist/esm/types/engine/AutoLayoutService.d.ts +59 -2
  43. package/dist/esm/types/engine/DiagramEngine.d.ts +20 -1
  44. package/dist/esm/types/engine/LinkRoutingService.d.ts +9 -0
  45. package/dist/esm/types/models/TextModel.d.ts +1 -0
  46. package/dist/esm/types/renderer/konva/KonvaInteraction.d.ts +6 -0
  47. package/dist/esm/types/strategies/ObstacleRouter.d.ts +2 -0
  48. package/dist/esm/types/strategies/RouterStrategy.d.ts +10 -0
  49. package/dist/examples.d.ts +56 -1
  50. package/dist/index.d.ts +60 -2
  51. package/docs/API_CONTRACT.md +73 -3
  52. package/docs/CAPABILITIES.md +8 -0
  53. package/docs/COMMANDS_EVENTS.md +8 -0
  54. package/docs/DOCUMENTATION_WORKFLOW.md +4 -1
  55. package/docs/INTEGRATION_PLAYBOOK.md +3 -0
  56. package/docs/STATE_INVARIANTS.md +4 -0
  57. package/package.json +1 -1
  58. package/src/displaybox/demos/AutoLayoutDemoTab.tsx +515 -381
  59. package/src/displaybox/demos/EngineEventsDemoTab.tsx +12 -11
  60. package/src/displaybox/demos/LinkColorPoolDemoTab.tsx +49 -0
  61. package/src/displaybox/demos/ObstacleRoutingDemoTab.tsx +52 -31
  62. package/src/displaybox/demos/OffsetAnchorAvoidanceDemoTab.tsx +30 -0
  63. package/src/displaybox/demos/SimpleDemo.tsx +18 -13
  64. package/src/displaybox/demos/TextLayoutDemoTab.tsx +18 -1
  65. package/src/displaybox/demos/ZoomToFitElementsDemoTab.tsx +29 -0
  66. package/src/displaybox/demos/autoLayoutDemo.ts +62 -26
  67. package/src/displaybox/demos/index.tsx +81 -57
  68. package/src/displaybox/demos/linkColorPoolDemo.ts +122 -0
  69. package/src/displaybox/demos/obstacleRoutingDemo.ts +77 -1
  70. package/src/displaybox/demos/offsetAnchorAvoidanceDemo.ts +211 -0
  71. package/src/displaybox/demos/routingDemo.ts +5 -5
  72. package/src/displaybox/demos/shared.ts +17 -12
  73. package/src/displaybox/demos/textDemo.ts +6 -2
  74. package/src/displaybox/demos/zoomToFitElementsDemo.ts +83 -0
  75. package/src/displaybox/types.ts +10 -8
@@ -1,4 +1,4 @@
1
- import { DiagramEngineHandle, Point, DiagramState, ElementShapeHoverControlActivationEvent, ElementShapeHoverControlInteractionEvent, ElementShapeHoverControls, EngineChangeEvent, EngineSelectionEvent } from './types';
1
+ import { DiagramEngineHandle, Point, DiagramState, ElementShapeHoverControlActivationEvent, ElementShapeHoverControlInteractionEvent, ElementShapeHoverControls, EngineChangeEvent, EngineSelectionEvent, LinkColorPoolPolicy, LinkRouteRefreshPolicy, ViewportFitOptions } from './types';
2
2
  import { type BuiltInShapeKind } from '../shapes';
3
3
  export type SimpleShape = {
4
4
  id: string;
@@ -18,6 +18,8 @@ export type DiagramEditorConfig = {
18
18
  onElementShapeHoverControlActivated?: (event: ElementShapeHoverControlActivationEvent) => void;
19
19
  onChange?: (event: EngineChangeEvent) => void;
20
20
  onSelection?: (event: EngineSelectionEvent) => void;
21
+ linkRouteRefreshPolicy?: LinkRouteRefreshPolicy;
22
+ linkColorPoolPolicy?: LinkColorPoolPolicy;
21
23
  };
22
24
  export type DiagramImageExportOptions = {
23
25
  mimeType?: string;
@@ -37,6 +39,7 @@ export type DiagramEditorHandle = DiagramEngineHandle & {
37
39
  completeLinkToPort: (targetPortId: string) => void;
38
40
  completeLinkToElement: (targetElementId: string, pointer: Point) => void;
39
41
  cancelLink: () => void;
42
+ zoomToFitElements: (options?: ViewportFitOptions) => void;
40
43
  exportImage: (options?: DiagramImageExportOptions) => string;
41
44
  resize: (width: number, height: number) => void;
42
45
  setElementShapeHoverControls: (controls?: ElementShapeHoverControls) => void;
@@ -19,7 +19,16 @@ export type ClientRectLike = {
19
19
  export type DiagramContainer = {
20
20
  getBoundingClientRect: () => ClientRectLike;
21
21
  };
22
+ export type ViewportFitOptions = {
23
+ padding?: number;
24
+ minZoom?: number;
25
+ maxZoom?: number;
26
+ };
22
27
  export type MoveConstraint = 'free' | 'inside' | 'border';
28
+ export type TextInteractionPolicy = {
29
+ movable?: boolean;
30
+ editable?: boolean;
31
+ };
23
32
  export type BorderSide = 'left' | 'right' | 'top' | 'bottom';
24
33
  export type HostAnchorPreset = 'vertices' | 'cardinal';
25
34
  export type PortLinkAttachMode = 'external' | 'internal';
@@ -173,10 +182,21 @@ export type AnchorReference = 'top-left' | 'center';
173
182
  export type RerouteLinksOptions = {
174
183
  includeManual?: boolean;
175
184
  };
176
- export type ElementLayoutMode = 'manual' | 'horizontal' | 'vertical';
185
+ export type LinkRouteRefreshMode = 'mutation-only' | 'redraw-two-endpoint-change';
186
+ export type LinkRouteRefreshPolicy = {
187
+ mode?: LinkRouteRefreshMode;
188
+ includeManual?: boolean;
189
+ };
190
+ export type LinkColorPoolPolicy = {
191
+ enabled?: boolean;
192
+ colors?: string[];
193
+ };
194
+ export type ElementLayoutMode = 'manual' | 'horizontal' | 'vertical' | 'grid';
177
195
  export type ElementLayoutAlign = 'start' | 'center' | 'end';
178
196
  export type ElementLayoutChildFitMainAxis = 'none' | 'distribute';
179
197
  export type ElementLayoutChildFitCrossAxis = 'none' | 'stretch';
198
+ export type ElementLayoutAutoResizeMode = 'grow' | 'grow-shrink';
199
+ export type ElementLayoutGridRowTemplate = number;
180
200
  export type ElementLayoutLabelReservedSpaceMode = 'none' | 'fixed' | 'flexible';
181
201
  export type ElementLayoutLabelReservedSpacePlacement = 'top';
182
202
  export type ElementLayoutLabelReservedSpace = {
@@ -197,8 +217,15 @@ export type ElementLayout = {
197
217
  };
198
218
  gap?: number;
199
219
  align?: ElementLayoutAlign;
220
+ autoResize?: ElementLayoutAutoResizeMode;
221
+ gridTemplate?: ElementLayoutGridRowTemplate[];
222
+ gridChildWidthResizeEnabled?: boolean;
200
223
  childFitMainAxis?: ElementLayoutChildFitMainAxis;
201
224
  childFitCrossAxis?: ElementLayoutChildFitCrossAxis;
225
+ childMinWidth?: number;
226
+ childMaxWidth?: number;
227
+ childMinHeight?: number;
228
+ childMaxHeight?: number;
202
229
  childFitMinSize?: Partial<Size>;
203
230
  childFitMaxSize?: Partial<Size>;
204
231
  labelReservedSpace?: ElementLayoutLabelReservedSpace;
@@ -283,6 +310,7 @@ export type TextData = {
283
310
  size?: Size;
284
311
  style?: Record<string, unknown>;
285
312
  ownerId?: string | null;
313
+ interaction?: TextInteractionPolicy;
286
314
  layout?: TextLayout;
287
315
  displayContent?: string;
288
316
  displayOffset?: Point;
@@ -356,6 +384,19 @@ export type ElementResizedEvent = {
356
384
  oldSize: Size;
357
385
  newSize: Size;
358
386
  };
387
+ export type GridLayoutChangedReason = 'child-resize-split' | 'child-resize-redistribute';
388
+ export type GridRowSnapshot = {
389
+ childIds: string[];
390
+ };
391
+ export type GridLayoutChangedEvent = {
392
+ parentId: string;
393
+ triggerChildId: string;
394
+ reason: GridLayoutChangedReason;
395
+ beforeRows: GridRowSnapshot[];
396
+ afterRows: GridRowSnapshot[];
397
+ beforeGridTemplate?: ElementLayoutGridRowTemplate[];
398
+ afterGridTemplate: ElementLayoutGridRowTemplate[];
399
+ };
359
400
  export type ElementDeletedEvent = {
360
401
  elementId: string;
361
402
  };
@@ -424,6 +465,7 @@ export type EngineEventMap = {
424
465
  elementDragged: ElementDropEvent;
425
466
  elementMoved: ElementMovedEvent;
426
467
  elementResized: ElementResizedEvent;
468
+ gridLayoutChanged: GridLayoutChangedEvent;
427
469
  elementDeleted: ElementDeletedEvent;
428
470
  portDeleted: PortDeletedEvent;
429
471
  linkDeleted: LinkDeletedEvent;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const LinkColorPoolDemo: () => React.JSX.Element;
3
+ export default LinkColorPoolDemo;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const OffsetAnchorAvoidanceDemo: () => React.JSX.Element;
3
+ export default OffsetAnchorAvoidanceDemo;
@@ -1,7 +1,10 @@
1
1
  import React from 'react';
2
+ import type { LinkColorPoolPolicy, LinkRouteRefreshPolicy } from '../../api';
2
3
  import type { DemoConfig } from '../types';
3
4
  type SimpleDemoProps = {
4
5
  demo: DemoConfig;
6
+ linkRouteRefreshPolicy?: LinkRouteRefreshPolicy;
7
+ linkColorPoolPolicy?: LinkColorPoolPolicy;
5
8
  beforeStage?: React.ReactNode;
6
9
  stageHandlers?: {
7
10
  onDragOver?: (event: React.DragEvent<HTMLDivElement>) => void;
@@ -9,5 +12,5 @@ type SimpleDemoProps = {
9
12
  onDrop?: (event: React.DragEvent<HTMLDivElement>) => void;
10
13
  };
11
14
  };
12
- declare const SimpleDemo: ({ demo, beforeStage, stageHandlers }: SimpleDemoProps) => React.JSX.Element;
15
+ declare const SimpleDemo: ({ demo, linkRouteRefreshPolicy, linkColorPoolPolicy, beforeStage, stageHandlers }: SimpleDemoProps) => React.JSX.Element;
13
16
  export default SimpleDemo;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const ZoomToFitElementsDemo: () => React.JSX.Element;
3
+ export default ZoomToFitElementsDemo;
@@ -0,0 +1,2 @@
1
+ import type { DemoConfig } from '../types';
2
+ export declare const linkColorPoolDemoConfig: DemoConfig;
@@ -0,0 +1,4 @@
1
+ import type { DiagramState } from '../../api';
2
+ import type { DemoConfig } from '../types';
3
+ export declare const createOffsetAnchorAvoidanceState: () => DiagramState;
4
+ export declare const offsetAnchorAvoidanceDemoConfig: DemoConfig;
@@ -1,6 +1,9 @@
1
+ import type { TextInteractionPolicy } from '../../api';
1
2
  import type { DemoConfig } from '../types';
2
3
  export declare const textDemoOwnerId = "text-layout-owner";
3
4
  export declare const textDemoOwnedTextId = "text-owned-overflow";
4
5
  export declare const textDemoFloatingTextId = "text-floating-overflow";
5
6
  export declare const textDemoLongSample = "Long diagram label: middle ellipsis should keep the beginning and end visible while preserving the full canonical content in model state.";
7
+ export declare const textDemoOwnedInteraction: TextInteractionPolicy;
8
+ export declare const textDemoFloatingInteraction: TextInteractionPolicy;
6
9
  export declare const textDemoConfig: DemoConfig;
@@ -0,0 +1,4 @@
1
+ import type { DiagramState } from '../../api';
2
+ import type { DemoConfig } from '../types';
3
+ export declare const createZoomToFitElementsState: () => DiagramState;
4
+ export declare const zoomToFitElementsDemoConfig: DemoConfig;
@@ -1,5 +1,5 @@
1
1
  import type { CSSProperties } from 'react';
2
- import type { DiagramEditorHandle, DiagramState, SimpleShape } from '../api';
2
+ import type { DiagramEditorHandle, DiagramState, LinkColorPoolPolicy, LinkRouteRefreshPolicy, SimpleShape } from '../api';
3
3
  import type { RouterStrategy } from '../strategies/RouterStrategy';
4
4
  export type DemoActionHelpers = {
5
5
  nextOffset: () => number;
@@ -20,6 +20,8 @@ export type DemoConfig = {
20
20
  defaultPortShapeId?: string;
21
21
  router?: RouterStrategy;
22
22
  snapDefault?: boolean;
23
+ linkRouteRefreshPolicy?: LinkRouteRefreshPolicy;
24
+ linkColorPoolPolicy?: LinkColorPoolPolicy;
23
25
  stageStyle?: CSSProperties;
24
26
  actions: DemoAction[];
25
27
  };
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import type { DiagramEditorHandle, DiagramState, ElementShapeHoverControlActivationEvent, ElementShapeHoverControlInteractionEvent, ElementShapeHoverControls, SimpleShape } from '../api';
2
+ import type { DiagramEditorHandle, DiagramState, ElementShapeHoverControlActivationEvent, ElementShapeHoverControlInteractionEvent, ElementShapeHoverControls, LinkColorPoolPolicy, LinkRouteRefreshPolicy, SimpleShape } from '../api';
3
3
  import type { RouterStrategy } from '../strategies/RouterStrategy';
4
4
  import type { ViewportSnapshot } from './types';
5
5
  type DemoEditorConfig = {
@@ -8,11 +8,13 @@ type DemoEditorConfig = {
8
8
  portShapes?: SimpleShape[];
9
9
  router?: RouterStrategy;
10
10
  snapDefault?: boolean;
11
+ linkRouteRefreshPolicy?: LinkRouteRefreshPolicy;
12
+ linkColorPoolPolicy?: LinkColorPoolPolicy;
11
13
  elementShapeHoverControls?: ElementShapeHoverControls;
12
14
  onElementShapeHoverControlInteraction?: (event: ElementShapeHoverControlInteractionEvent) => void;
13
15
  onElementShapeHoverControlActivated?: (event: ElementShapeHoverControlActivationEvent) => void;
14
16
  };
15
- declare const useDemoEditor: ({ createState, elementShapes, portShapes, router, snapDefault, elementShapeHoverControls, onElementShapeHoverControlInteraction, onElementShapeHoverControlActivated, }: DemoEditorConfig) => {
17
+ declare const useDemoEditor: ({ createState, elementShapes, portShapes, router, snapDefault, linkRouteRefreshPolicy, linkColorPoolPolicy, elementShapeHoverControls, onElementShapeHoverControlInteraction, onElementShapeHoverControlActivated, }: DemoEditorConfig) => {
16
18
  containerRef: import("react").MutableRefObject<HTMLDivElement | null>;
17
19
  editorRef: import("react").MutableRefObject<DiagramEditorHandle | null>;
18
20
  diagramState: DiagramState | null;
@@ -1,26 +1,83 @@
1
- import { DiagramPatch } from '../api/types';
1
+ import { DiagramPatch, ElementData, GridLayoutChangedReason, GridRowSnapshot } from '../api/types';
2
2
  import DiagramModel from '../models/DiagramModel';
3
3
  import CommandQueue from './CommandQueue';
4
4
  export type AutoLayoutResult = {
5
5
  patches: DiagramPatch[];
6
6
  movedPortIds: string[];
7
7
  };
8
+ export type GridChildResizeTopologyChange = {
9
+ parentId: string;
10
+ triggerChildId: string;
11
+ reason: GridLayoutChangedReason;
12
+ beforeRows: GridRowSnapshot[];
13
+ afterRows: GridRowSnapshot[];
14
+ nextLayout: NonNullable<ElementData['layout']>;
15
+ };
8
16
  export type AutoLayoutServiceConfig = {
9
17
  model: DiagramModel;
10
18
  commandQueue: CommandQueue;
11
19
  collectElementPortIds: (elementId: string) => string[];
12
20
  };
21
+ type ParentLayoutOptions = {
22
+ preserveParentSize?: boolean;
23
+ preserveParentWidth?: boolean;
24
+ preserveParentHeight?: boolean;
25
+ };
13
26
  export default class AutoLayoutService {
14
27
  private model;
15
28
  private commandQueue;
16
29
  private collectElementPortIds;
17
30
  constructor(config: AutoLayoutServiceConfig);
18
- applyLayoutForParent(parentId: string): AutoLayoutResult;
31
+ applyLayoutForParent(parentId: string, options?: ParentLayoutOptions): AutoLayoutResult;
19
32
  applyLayoutCascade(startParentId: string | null): AutoLayoutResult;
20
33
  applyAllLayouts(): AutoLayoutResult;
34
+ describeGridRows(parentId: string): GridRowSnapshot[];
35
+ describeGridSlotState(parentId: string): {
36
+ orderedChildIds: string[];
37
+ slotWeights: number[];
38
+ } | null;
39
+ resolveGridReorderedLayout(parentId: string, previousState: {
40
+ orderedChildIds: string[];
41
+ slotWeights: number[];
42
+ }): NonNullable<ElementData['layout']> | null;
43
+ resolveGridChildResizeTopologyChange(parentId: string, childId: string, requestedWidth: number): GridChildResizeTopologyChange | null;
44
+ snapGridChildRequestedWidth(parentId: string, childId: string, requestedWidth: number): number;
45
+ canGridChildGrowRightward(parentId: string, childId: string): boolean;
46
+ private applyAxisLayoutForParent;
47
+ private applyGridLayoutForParent;
48
+ private resolveGridCellWidths;
49
+ private applyResolvedLayout;
21
50
  private resolveLayoutPadding;
51
+ private resolveAutoResizeMode;
52
+ private resolveAutoResizedDimension;
53
+ private resolveChildSizeConstraints;
54
+ private resolveAssignedGridRows;
55
+ private repartitionAssignedGridRows;
56
+ private fitGridRowWeights;
57
+ private gridRowSnapshotsEqual;
58
+ private normalizeGridTemplate;
59
+ private assignChildrenToGridRows;
60
+ private resolveGridChildSlotState;
61
+ private packGridRowsFromSlots;
62
+ private resolveRequestedGridUnits;
63
+ private sortGridChildrenForLayout;
64
+ private resolveRightwardGridOverflowChange;
65
+ private resolveSameRowGridUnitResizeChange;
66
+ private splitGridRowIntoTwelveUnits;
67
+ private reflowTrailingGridRows;
68
+ private flattenAssignedRowsToGridTemplate;
69
+ private buildEqualGridUnits;
70
+ private normalizeRowWeightsToTwelveUnits;
71
+ private normalizeGridSlotUnits;
72
+ private clampGridUnits;
73
+ private distributeUnitsWithMinimums;
74
+ private gridWeightsEqual;
75
+ private resolveGridRowUnitWidth;
22
76
  private resolveLabelReservedTopLane;
23
77
  private resolveFlexibleLabelLaneFromText;
78
+ private resolveAlignmentOffset;
24
79
  private clampLayoutSize;
80
+ private distributeWeightedSizes;
25
81
  private distributeLayoutSizes;
26
82
  }
83
+ export {};
@@ -1,4 +1,4 @@
1
- import { DiagramEngineHandle, DiagramState, ElementData, EngineEventMap, ElementDropEvent, EnginePointerInfo, LinkData, ElementLinkConnectingEvent, LinkRoutingMode, OverlayShapeConfig, OverlayShapeHandle, Point, PortData, RerouteLinksOptions, TextData, PortMouseEvent } from '../api/types';
1
+ import { DiagramEngineHandle, DiagramState, ElementData, EngineEventMap, ElementDropEvent, EnginePointerInfo, LinkData, LinkColorPoolPolicy, ElementLinkConnectingEvent, LinkRoutingMode, LinkRouteRefreshPolicy, OverlayShapeConfig, OverlayShapeHandle, Point, PortData, RerouteLinksOptions, TextData, PortMouseEvent } from '../api/types';
2
2
  import { Renderer } from '../renderer/Renderer';
3
3
  import RenderScheduler from '../renderer/RenderScheduler';
4
4
  import { RouterStrategy } from '../strategies/RouterStrategy';
@@ -12,6 +12,8 @@ export type DiagramEngineConfig = {
12
12
  snapper?: SnapStrategy;
13
13
  shapeRegistry?: ShapeRegistry;
14
14
  textMeasurer?: TextMeasurer;
15
+ linkRouteRefreshPolicy?: LinkRouteRefreshPolicy;
16
+ linkColorPoolPolicy?: LinkColorPoolPolicy;
15
17
  };
16
18
  export default class DiagramEngine {
17
19
  private model;
@@ -27,6 +29,8 @@ export default class DiagramEngine {
27
29
  private autoLayoutService;
28
30
  private linkRoutingService;
29
31
  private mutationPipeline;
32
+ private linkRouteRefreshPolicy;
33
+ private linkColorPoolPolicy;
30
34
  constructor(config: DiagramEngineConfig);
31
35
  static create(config: DiagramEngineConfig): DiagramEngine;
32
36
  load(state: DiagramState): void;
@@ -44,7 +48,15 @@ export default class DiagramEngine {
44
48
  createOverlayShape(config: OverlayShapeConfig): OverlayShapeHandle;
45
49
  on<TEvent extends keyof EngineEventMap>(event: TEvent, handler: (payload: EngineEventMap[TEvent]) => void): () => void;
46
50
  addElement(element: ElementData): void;
51
+ private resolveElementMovePosition;
52
+ private buildChildMutationLayoutSteps;
47
53
  moveElementTo(id: string, x: number, y: number): void;
54
+ resizeElementBounds(id: string, bounds: {
55
+ x: number;
56
+ y: number;
57
+ width: number;
58
+ height: number;
59
+ }): void;
48
60
  resizeElement(id: string, width: number, height: number): void;
49
61
  setElementLayout(id: string, layout: ElementData['layout']): void;
50
62
  removeElement(id: string): void;
@@ -77,6 +89,11 @@ export default class DiagramEngine {
77
89
  width: number;
78
90
  height: number;
79
91
  };
92
+ private shouldLockAutoLayoutChildHorizontalResize;
93
+ private shouldAnchorAutoLayoutGridChildWidthToLeft;
94
+ private shouldRestrictAutoLayoutChildRightGrowth;
95
+ private resolveSnappedGridChildWidth;
96
+ private resolveGridChildWidthResizeTopologyChange;
80
97
  getPortWorldPosition(id: string): Point | null;
81
98
  getPortLinkWorldPosition(id: string, options?: {
82
99
  oppositePortId?: string;
@@ -137,6 +154,8 @@ export default class DiagramEngine {
137
154
  private constrainPortToHostBorder;
138
155
  private projectPointToHostBorder;
139
156
  private routeLinksWithEmptyPoints;
157
+ private applyOptionalLinkColor;
158
+ private refreshLinksForRenderCycle;
140
159
  private normalizePortsForHostPolicies;
141
160
  private computeRemovalDiff;
142
161
  private emitEntityDeletionEvents;
@@ -9,6 +9,9 @@ export type LinkRoutingServiceConfig = {
9
9
  router: RouterStrategy;
10
10
  shapeRegistry: ShapeRegistry;
11
11
  };
12
+ export type RedrawLinkRefreshOptions = {
13
+ includeManual?: boolean;
14
+ };
12
15
  export default class LinkRoutingService {
13
16
  private model;
14
17
  private commandQueue;
@@ -18,6 +21,7 @@ export default class LinkRoutingService {
18
21
  setRouter(router: RouterStrategy): void;
19
22
  updateLinksForPorts(portIds: string[]): DiagramPatch[];
20
23
  routeLinksWithEmptyPoints(): DiagramPatch[];
24
+ refreshLinksForRedraw(options?: RedrawLinkRefreshOptions): DiagramPatch[];
21
25
  getPortLinkWorldPosition(portId: string, options?: {
22
26
  oppositePortId?: string;
23
27
  attachMode?: PortLinkAttachMode;
@@ -26,7 +30,9 @@ export default class LinkRoutingService {
26
30
  private resolveLinkPointsForUpdate;
27
31
  private resolveLinkEndpoints;
28
32
  private updateManualRoute;
33
+ private pointsEqual;
29
34
  private buildRouteContext;
35
+ private resolveCommonAncestorCorridorHint;
30
36
  private resolveEndpointGeometry;
31
37
  private resolveCornerTieBreakSide;
32
38
  private resolveElementShape;
@@ -36,8 +42,11 @@ export default class LinkRoutingService {
36
42
  private resolveAttachModeForPorts;
37
43
  private isAncestorOf;
38
44
  private getAncestorChain;
45
+ private getFirstCommonAncestorId;
46
+ private resolveImmediateChildUnderAncestor;
39
47
  private getAncestorExclusions;
40
48
  private resolveRouteBounds;
41
49
  private isPointOnRectEdge;
50
+ private isPointInsideRect;
42
51
  private resolveEdgeSide;
43
52
  }
@@ -6,6 +6,7 @@ export default class TextModel {
6
6
  size?: Size;
7
7
  style?: Record<string, unknown>;
8
8
  ownerId?: string | null;
9
+ interaction?: TextData['interaction'];
9
10
  layout?: TextData['layout'];
10
11
  displayContent?: string;
11
12
  displayOffset?: Point;
@@ -72,6 +72,7 @@ export default class KonvaInteraction {
72
72
  private readonly dragThreshold;
73
73
  private readonly panSpeed;
74
74
  private readonly occupiedVertexTolerance;
75
+ private readonly nestedHoverElementPadding;
75
76
  private emittingElementLinkEnded;
76
77
  private panKey;
77
78
  constructor(engine: DiagramEngine, config?: InteractionConfig);
@@ -106,6 +107,9 @@ export default class KonvaInteraction {
106
107
  private emitShapeHoverControlInteraction;
107
108
  private emitLegacyShapeHoverControlActivation;
108
109
  private updateShapeHoverControl;
110
+ private resolveNestedHoverElementCandidates;
111
+ private isDescendantOrSelf;
112
+ private isPointWithinElementHoverBounds;
109
113
  private resolveShapeHoverControl;
110
114
  private resolveTargetHoverCandidate;
111
115
  private resolveElementHoverCandidate;
@@ -142,6 +146,8 @@ export default class KonvaInteraction {
142
146
  private getElementById;
143
147
  private getPortById;
144
148
  private getTextById;
149
+ private isTextMovable;
150
+ private isTextEditable;
145
151
  private getLinkById;
146
152
  private resolveTextScreenPosition;
147
153
  private applyViewportPatch;
@@ -23,5 +23,7 @@ export default class ObstacleRouter implements RouterStrategy {
23
23
  private distanceToObstacles;
24
24
  private ensureEndpoints;
25
25
  private compactPreservingStubs;
26
+ private buildCommonAncestorCorridorCandidate;
27
+ private scoreCommonAncestorCorridor;
26
28
  }
27
29
  export {};
@@ -8,6 +8,15 @@ export type RouteEndpoint = {
8
8
  rect?: Rect;
9
9
  onEdgeSide?: 'left' | 'right' | 'top' | 'bottom';
10
10
  };
11
+ export type CommonAncestorCorridorHint = {
12
+ ancestorId: string;
13
+ bounds: Rect;
14
+ sourceBranchId: string;
15
+ targetBranchId: string;
16
+ sourceBranchRect: Rect;
17
+ targetBranchRect: Rect;
18
+ axis: 'horizontal' | 'vertical';
19
+ };
11
20
  export type RouteContext = {
12
21
  linkId: string;
13
22
  sourcePortId: string;
@@ -16,6 +25,7 @@ export type RouteContext = {
16
25
  bounds?: Rect;
17
26
  sourceEndpoint?: RouteEndpoint;
18
27
  targetEndpoint?: RouteEndpoint;
28
+ commonAncestorCorridor?: CommonAncestorCorridorHint;
19
29
  };
20
30
  export interface RouterStrategy {
21
31
  route(source: Point, target: Point, context?: RouteContext): Point[];
@@ -21,7 +21,16 @@ type ClientRectLike = {
21
21
  type DiagramContainer = {
22
22
  getBoundingClientRect: () => ClientRectLike;
23
23
  };
24
+ type ViewportFitOptions = {
25
+ padding?: number;
26
+ minZoom?: number;
27
+ maxZoom?: number;
28
+ };
24
29
  type MoveConstraint = 'free' | 'inside' | 'border';
30
+ type TextInteractionPolicy = {
31
+ movable?: boolean;
32
+ editable?: boolean;
33
+ };
25
34
  type BorderSide = 'left' | 'right' | 'top' | 'bottom';
26
35
  type HostAnchorPreset = 'vertices' | 'cardinal';
27
36
  type PortLinkAttachMode = 'external' | 'internal';
@@ -146,10 +155,21 @@ type AnchorReference = 'top-left' | 'center';
146
155
  type RerouteLinksOptions = {
147
156
  includeManual?: boolean;
148
157
  };
149
- type ElementLayoutMode = 'manual' | 'horizontal' | 'vertical';
158
+ type LinkRouteRefreshMode = 'mutation-only' | 'redraw-two-endpoint-change';
159
+ type LinkRouteRefreshPolicy = {
160
+ mode?: LinkRouteRefreshMode;
161
+ includeManual?: boolean;
162
+ };
163
+ type LinkColorPoolPolicy = {
164
+ enabled?: boolean;
165
+ colors?: string[];
166
+ };
167
+ type ElementLayoutMode = 'manual' | 'horizontal' | 'vertical' | 'grid';
150
168
  type ElementLayoutAlign = 'start' | 'center' | 'end';
151
169
  type ElementLayoutChildFitMainAxis = 'none' | 'distribute';
152
170
  type ElementLayoutChildFitCrossAxis = 'none' | 'stretch';
171
+ type ElementLayoutAutoResizeMode = 'grow' | 'grow-shrink';
172
+ type ElementLayoutGridRowTemplate = number;
153
173
  type ElementLayoutLabelReservedSpaceMode = 'none' | 'fixed' | 'flexible';
154
174
  type ElementLayoutLabelReservedSpacePlacement = 'top';
155
175
  type ElementLayoutLabelReservedSpace = {
@@ -170,8 +190,15 @@ type ElementLayout = {
170
190
  };
171
191
  gap?: number;
172
192
  align?: ElementLayoutAlign;
193
+ autoResize?: ElementLayoutAutoResizeMode;
194
+ gridTemplate?: ElementLayoutGridRowTemplate[];
195
+ gridChildWidthResizeEnabled?: boolean;
173
196
  childFitMainAxis?: ElementLayoutChildFitMainAxis;
174
197
  childFitCrossAxis?: ElementLayoutChildFitCrossAxis;
198
+ childMinWidth?: number;
199
+ childMaxWidth?: number;
200
+ childMinHeight?: number;
201
+ childMaxHeight?: number;
175
202
  childFitMinSize?: Partial<Size>;
176
203
  childFitMaxSize?: Partial<Size>;
177
204
  labelReservedSpace?: ElementLayoutLabelReservedSpace;
@@ -256,6 +283,7 @@ type TextData = {
256
283
  size?: Size;
257
284
  style?: Record<string, unknown>;
258
285
  ownerId?: string | null;
286
+ interaction?: TextInteractionPolicy;
259
287
  layout?: TextLayout;
260
288
  displayContent?: string;
261
289
  displayOffset?: Point;
@@ -329,6 +357,19 @@ type ElementResizedEvent = {
329
357
  oldSize: Size;
330
358
  newSize: Size;
331
359
  };
360
+ type GridLayoutChangedReason = 'child-resize-split' | 'child-resize-redistribute';
361
+ type GridRowSnapshot = {
362
+ childIds: string[];
363
+ };
364
+ type GridLayoutChangedEvent = {
365
+ parentId: string;
366
+ triggerChildId: string;
367
+ reason: GridLayoutChangedReason;
368
+ beforeRows: GridRowSnapshot[];
369
+ afterRows: GridRowSnapshot[];
370
+ beforeGridTemplate?: ElementLayoutGridRowTemplate[];
371
+ afterGridTemplate: ElementLayoutGridRowTemplate[];
372
+ };
332
373
  type ElementDeletedEvent = {
333
374
  elementId: string;
334
375
  };
@@ -397,6 +438,7 @@ type EngineEventMap = {
397
438
  elementDragged: ElementDropEvent;
398
439
  elementMoved: ElementMovedEvent;
399
440
  elementResized: ElementResizedEvent;
441
+ gridLayoutChanged: GridLayoutChangedEvent;
400
442
  elementDeleted: ElementDeletedEvent;
401
443
  portDeleted: PortDeletedEvent;
402
444
  linkDeleted: LinkDeletedEvent;
@@ -471,6 +513,15 @@ type RouteEndpoint = {
471
513
  rect?: Rect;
472
514
  onEdgeSide?: 'left' | 'right' | 'top' | 'bottom';
473
515
  };
516
+ type CommonAncestorCorridorHint = {
517
+ ancestorId: string;
518
+ bounds: Rect;
519
+ sourceBranchId: string;
520
+ targetBranchId: string;
521
+ sourceBranchRect: Rect;
522
+ targetBranchRect: Rect;
523
+ axis: 'horizontal' | 'vertical';
524
+ };
474
525
  type RouteContext = {
475
526
  linkId: string;
476
527
  sourcePortId: string;
@@ -479,6 +530,7 @@ type RouteContext = {
479
530
  bounds?: Rect;
480
531
  sourceEndpoint?: RouteEndpoint;
481
532
  targetEndpoint?: RouteEndpoint;
533
+ commonAncestorCorridor?: CommonAncestorCorridorHint;
482
534
  };
483
535
  interface RouterStrategy {
484
536
  route(source: Point, target: Point, context?: RouteContext): Point[];
@@ -509,6 +561,7 @@ type DiagramEditorHandle = DiagramEngineHandle & {
509
561
  completeLinkToPort: (targetPortId: string) => void;
510
562
  completeLinkToElement: (targetElementId: string, pointer: Point) => void;
511
563
  cancelLink: () => void;
564
+ zoomToFitElements: (options?: ViewportFitOptions) => void;
512
565
  exportImage: (options?: DiagramImageExportOptions) => string;
513
566
  resize: (width: number, height: number) => void;
514
567
  setElementShapeHoverControls: (controls?: ElementShapeHoverControls) => void;
@@ -534,6 +587,8 @@ type DemoConfig = {
534
587
  defaultPortShapeId?: string;
535
588
  router?: RouterStrategy;
536
589
  snapDefault?: boolean;
590
+ linkRouteRefreshPolicy?: LinkRouteRefreshPolicy;
591
+ linkColorPoolPolicy?: LinkColorPoolPolicy;
537
592
  stageStyle?: CSSProperties;
538
593
  actions: DemoAction[];
539
594
  };