orcasvn-react-diagrams 0.2.11 → 0.2.12

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 (45) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +11 -7
  3. package/ai/api-contract.json +43 -1
  4. package/ai/manifest.json +1 -1
  5. package/dist/cjs/examples.js +492 -286
  6. package/dist/cjs/index.js +180 -61
  7. package/dist/cjs/types/api/createDiagramEditor.d.ts +2 -1
  8. package/dist/cjs/types/api/types.d.ts +14 -0
  9. package/dist/cjs/types/displaybox/demos/LinkPortCreationDemoTab.d.ts +3 -0
  10. package/dist/cjs/types/displaybox/demos/linkLabelsDemo.d.ts +4 -0
  11. package/dist/cjs/types/displaybox/types.d.ts +3 -0
  12. package/dist/cjs/types/displaybox/useDemoEditor.d.ts +3 -2
  13. package/dist/cjs/types/engine/DiagramEngine.d.ts +2 -1
  14. package/dist/cjs/types/engine/TextLayoutService.d.ts +1 -0
  15. package/dist/cjs/types/examples/index.d.ts +1 -1
  16. package/dist/cjs/types/renderer/konva/KonvaInteraction.d.ts +10 -1
  17. package/dist/esm/examples.js +492 -286
  18. package/dist/esm/examples.js.map +1 -1
  19. package/dist/esm/index.js +180 -61
  20. package/dist/esm/index.js.map +1 -1
  21. package/dist/esm/types/api/createDiagramEditor.d.ts +2 -1
  22. package/dist/esm/types/api/types.d.ts +14 -0
  23. package/dist/esm/types/displaybox/demos/LinkPortCreationDemoTab.d.ts +3 -0
  24. package/dist/esm/types/displaybox/demos/linkLabelsDemo.d.ts +4 -0
  25. package/dist/esm/types/displaybox/types.d.ts +3 -0
  26. package/dist/esm/types/displaybox/useDemoEditor.d.ts +3 -2
  27. package/dist/esm/types/engine/DiagramEngine.d.ts +2 -1
  28. package/dist/esm/types/engine/TextLayoutService.d.ts +1 -0
  29. package/dist/esm/types/examples/index.d.ts +1 -1
  30. package/dist/esm/types/renderer/konva/KonvaInteraction.d.ts +10 -1
  31. package/dist/examples.d.ts +4 -1
  32. package/dist/index.d.ts +16 -1
  33. package/docs/API_CONTRACT.md +40 -0
  34. package/docs/CAPABILITIES.md +2 -0
  35. package/docs/COMMANDS_EVENTS.md +1 -0
  36. package/docs/DOCUMENTATION_WORKFLOW.md +3 -1
  37. package/docs/INTEGRATION_PLAYBOOK.md +4 -0
  38. package/docs/STATE_INVARIANTS.md +3 -0
  39. package/package.json +1 -1
  40. package/src/displaybox/demos/LinkPortCreationDemoTab.tsx +98 -0
  41. package/src/displaybox/demos/index.tsx +122 -221
  42. package/src/displaybox/demos/linkLabelsDemo.ts +164 -0
  43. package/src/displaybox/demos/linkPortCreationDemo.ts +7 -7
  44. package/src/displaybox/types.ts +21 -11
  45. package/src/examples/index.ts +1 -0
package/dist/cjs/index.js CHANGED
@@ -1881,21 +1881,20 @@ var TextLayoutService = /** @class */ (function () {
1881
1881
  return ids;
1882
1882
  };
1883
1883
  TextLayoutService.prototype.shouldTrackOwnerBoundLayout = function (text) {
1884
- var _a;
1885
1884
  if (!text.layout)
1886
1885
  return false;
1887
- var boundsMode = (_a = text.layout.boundsMode) !== null && _a !== void 0 ? _a : (text.ownerId ? 'owner-width' : undefined);
1886
+ var boundsMode = this.resolveDefaultBoundsMode(text);
1888
1887
  return boundsMode === 'owner-width' || boundsMode === 'owner-box';
1889
1888
  };
1890
1889
  TextLayoutService.prototype.resolveTextLayoutBounds = function (text, padding) {
1891
- var _a, _b, _c;
1890
+ var _a, _b;
1892
1891
  var layout = text.layout;
1893
1892
  if (!layout)
1894
1893
  return {};
1895
- var boundsMode = (_a = layout.boundsMode) !== null && _a !== void 0 ? _a : (text.ownerId ? 'owner-width' : undefined);
1894
+ var boundsMode = this.resolveDefaultBoundsMode(text);
1896
1895
  if (boundsMode === 'fixed') {
1897
- var width = (_b = layout.fixedSize) === null || _b === void 0 ? void 0 : _b.width;
1898
- var height = (_c = layout.fixedSize) === null || _c === void 0 ? void 0 : _c.height;
1896
+ var width = (_a = layout.fixedSize) === null || _a === void 0 ? void 0 : _a.width;
1897
+ var height = (_b = layout.fixedSize) === null || _b === void 0 ? void 0 : _b.height;
1899
1898
  return {
1900
1899
  width: typeof width === 'number' ? Math.max(0, width - padding * 2) : undefined,
1901
1900
  height: typeof height === 'number' ? Math.max(0, height - padding * 2) : undefined,
@@ -1915,6 +1914,14 @@ var TextLayoutService = /** @class */ (function () {
1915
1914
  }
1916
1915
  return {};
1917
1916
  };
1917
+ TextLayoutService.prototype.resolveDefaultBoundsMode = function (text) {
1918
+ var _a;
1919
+ if ((_a = text.layout) === null || _a === void 0 ? void 0 : _a.boundsMode)
1920
+ return text.layout.boundsMode;
1921
+ if (!text.ownerId)
1922
+ return undefined;
1923
+ return this.model.getElement(text.ownerId) ? 'owner-width' : undefined;
1924
+ };
1918
1925
  TextLayoutService.prototype.wrapText = function (content, maxWidth, mode, text) {
1919
1926
  var _this = this;
1920
1927
  if (maxWidth === undefined || !Number.isFinite(maxWidth)) {
@@ -4156,6 +4163,24 @@ var DiagramEngine = /** @class */ (function () {
4156
4163
  var patches = this.commandQueue.run(createAddPortCommand(nextPort), this.model);
4157
4164
  this.emitChange(patches);
4158
4165
  };
4166
+ DiagramEngine.prototype.normalizePortDraftForElement = function (elementId, draft) {
4167
+ var _a;
4168
+ var element = this.model.getElement(elementId);
4169
+ if (!element)
4170
+ return null;
4171
+ var nextDraft = __assign(__assign({}, draft), { position: __assign({}, draft.position), size: draft.size ? __assign({}, draft.size) : undefined, style: draft.style ? __assign({}, draft.style) : undefined, textIds: draft.textIds ? __spreadArray([], draft.textIds, true) : undefined, placementPoint: draft.placementPoint ? __assign({}, draft.placementPoint) : undefined, linkAttachPoint: draft.linkAttachPoint ? __assign({}, draft.linkAttachPoint) : undefined, externalLinkAttachPoint: draft.externalLinkAttachPoint ? __assign({}, draft.externalLinkAttachPoint) : undefined, internalLinkAttachPoint: draft.internalLinkAttachPoint ? __assign({}, draft.internalLinkAttachPoint) : undefined, rotationPivot: draft.rotationPivot ? __assign({}, draft.rotationPivot) : undefined });
4172
+ var constrained = this.resolveConstrainedPortRelativePosition({
4173
+ position: nextDraft.position,
4174
+ size: nextDraft.size,
4175
+ style: nextDraft.style,
4176
+ moveMode: nextDraft.moveMode,
4177
+ anchorCenter: nextDraft.anchorCenter,
4178
+ currentAnchorId: nextDraft.currentAnchorId,
4179
+ }, element, nextDraft.position);
4180
+ nextDraft.position = constrained.position;
4181
+ nextDraft.currentAnchorId = (_a = constrained.currentAnchorId) !== null && _a !== void 0 ? _a : undefined;
4182
+ return nextDraft;
4183
+ };
4159
4184
  DiagramEngine.prototype.movePortTo = function (id, x, y) {
4160
4185
  var snapped = this.snapper.snap({ x: x, y: y });
4161
4186
  var port = this.model.getPort(id);
@@ -6551,6 +6576,7 @@ var KonvaInteraction = /** @class */ (function () {
6551
6576
  this.shapeHoverControls = this.normalizeShapeHoverControls(config.shapeHoverControls);
6552
6577
  this.onShapeHoverControlInteracted = config.onShapeHoverControlInteracted;
6553
6578
  this.onShapeHoverControlActivated = config.onShapeHoverControlActivated;
6579
+ this.onCreateLinkTargetPort = config.onCreateLinkTargetPort;
6554
6580
  }
6555
6581
  KonvaInteraction.prototype.setShapeHoverControls = function (controls) {
6556
6582
  this.shapeHoverControls = this.normalizeShapeHoverControls(controls);
@@ -6567,6 +6593,9 @@ var KonvaInteraction = /** @class */ (function () {
6567
6593
  var sourceElementId = this.engine.getPortElementId(sourcePortId);
6568
6594
  if (!sourceElementId)
6569
6595
  return;
6596
+ var sourcePort = this.getPortById(sourcePortId);
6597
+ if (!sourcePort)
6598
+ return;
6570
6599
  var sourcePoint = (_a = this.engine.getPortLinkWorldPosition(sourcePortId)) !== null && _a !== void 0 ? _a : this.engine.getPortWorldPosition(sourcePortId);
6571
6600
  if (!sourcePoint)
6572
6601
  return;
@@ -6583,6 +6612,7 @@ var KonvaInteraction = /** @class */ (function () {
6583
6612
  this.programmaticLinkSession = {
6584
6613
  sourcePortId: sourcePortId,
6585
6614
  sourceElementId: sourceElementId,
6615
+ sourcePort: this.clonePortData(sourcePort),
6586
6616
  start: start,
6587
6617
  current: start,
6588
6618
  };
@@ -6592,6 +6622,7 @@ var KonvaInteraction = /** @class */ (function () {
6592
6622
  mode: 'link-drag',
6593
6623
  sourcePortId: sourcePortId,
6594
6624
  sourceElementId: sourceElementId,
6625
+ sourcePort: this.clonePortData(sourcePort),
6595
6626
  start: start,
6596
6627
  current: start,
6597
6628
  isMulti: false,
@@ -6607,7 +6638,7 @@ var KonvaInteraction = /** @class */ (function () {
6607
6638
  }
6608
6639
  };
6609
6640
  KonvaInteraction.prototype.updateLinkPreview = function (pointer) {
6610
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
6641
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
6611
6642
  if (this.programmaticLinkSession) {
6612
6643
  this.programmaticLinkSession.current = __assign({}, pointer);
6613
6644
  }
@@ -6619,28 +6650,29 @@ var KonvaInteraction = /** @class */ (function () {
6619
6650
  return;
6620
6651
  }
6621
6652
  var sourcePortId = (_c = (_b = this.programmaticLinkSession) === null || _b === void 0 ? void 0 : _b.sourcePortId) !== null && _c !== void 0 ? _c : (((_d = this.dragState) === null || _d === void 0 ? void 0 : _d.mode) === 'link-drag' ? this.dragState.sourcePortId : null);
6653
+ var sourceElementId = (_f = (_e = this.programmaticLinkSession) === null || _e === void 0 ? void 0 : _e.sourceElementId) !== null && _f !== void 0 ? _f : (((_g = this.dragState) === null || _g === void 0 ? void 0 : _g.mode) === 'link-drag' ? this.dragState.sourceElementId : null);
6622
6654
  if (!sourcePortId)
6623
6655
  return;
6624
6656
  var source = this.resolveLinkPreviewSource(sourcePortId, pointer);
6625
6657
  if (source) {
6626
- (_e = this.renderer) === null || _e === void 0 ? void 0 : _e.renderTempLink([source, pointer]);
6658
+ (_h = this.renderer) === null || _h === void 0 ? void 0 : _h.renderTempLink([source, pointer]);
6627
6659
  }
6628
6660
  var hit = this.resolveHit(pointer);
6629
- if ((hit === null || hit === void 0 ? void 0 : hit.type) === 'element') {
6630
- var placeholder = this.createPlaceholderPort(hit.id, pointer, sourcePortId);
6661
+ if ((hit === null || hit === void 0 ? void 0 : hit.type) === 'element' && sourceElementId) {
6662
+ var placeholder = this.createPlaceholderPort(hit.id, pointer, sourcePortId, sourceElementId);
6631
6663
  if (placeholder) {
6632
6664
  var hostElement = this.getElementById(hit.id);
6633
6665
  if (hostElement) {
6634
- var hostWorld = (_f = this.engine.getElementWorldPosition(hit.id)) !== null && _f !== void 0 ? _f : hostElement.position;
6635
- (_h = (_g = this.renderer) === null || _g === void 0 ? void 0 : _g.renderPortPlaceholder) === null || _h === void 0 ? void 0 : _h.call(_g, placeholder, { id: hostElement.id, position: hostWorld, size: hostElement.size, shapeId: hostElement.shapeId });
6666
+ var hostWorld = (_j = this.engine.getElementWorldPosition(hit.id)) !== null && _j !== void 0 ? _j : hostElement.position;
6667
+ (_l = (_k = this.renderer) === null || _k === void 0 ? void 0 : _k.renderPortPlaceholder) === null || _l === void 0 ? void 0 : _l.call(_k, placeholder, { id: hostElement.id, position: hostWorld, size: hostElement.size, shapeId: hostElement.shapeId });
6636
6668
  }
6637
6669
  else {
6638
- (_k = (_j = this.renderer) === null || _j === void 0 ? void 0 : _j.renderPortPlaceholder) === null || _k === void 0 ? void 0 : _k.call(_j, placeholder);
6670
+ (_o = (_m = this.renderer) === null || _m === void 0 ? void 0 : _m.renderPortPlaceholder) === null || _o === void 0 ? void 0 : _o.call(_m, placeholder);
6639
6671
  }
6640
6672
  }
6641
6673
  return;
6642
6674
  }
6643
- (_m = (_l = this.renderer) === null || _l === void 0 ? void 0 : _l.clearPortPlaceholder) === null || _m === void 0 ? void 0 : _m.call(_l);
6675
+ (_q = (_p = this.renderer) === null || _p === void 0 ? void 0 : _p.clearPortPlaceholder) === null || _q === void 0 ? void 0 : _q.call(_p);
6644
6676
  };
6645
6677
  KonvaInteraction.prototype.completeLinkToPort = function (targetPortId) {
6646
6678
  var _a, _b;
@@ -6802,10 +6834,14 @@ var KonvaInteraction = /** @class */ (function () {
6802
6834
  }
6803
6835
  }
6804
6836
  else {
6837
+ var sourcePort = _this.getPortById(hit.id);
6838
+ if (!sourcePort)
6839
+ return;
6805
6840
  _this.dragState = {
6806
6841
  mode: 'link-drag',
6807
6842
  sourcePortId: hit.id,
6808
6843
  sourceElementId: elementId,
6844
+ sourcePort: _this.clonePortData(sourcePort),
6809
6845
  start: point,
6810
6846
  current: point,
6811
6847
  isMulti: isMulti,
@@ -6987,7 +7023,7 @@ var KonvaInteraction = /** @class */ (function () {
6987
7023
  }
6988
7024
  }
6989
7025
  else if ((hit === null || hit === void 0 ? void 0 : hit.type) === 'element') {
6990
- var placeholder = _this.createPlaceholderPort(hit.id, point, _this.dragState.sourcePortId);
7026
+ var placeholder = _this.createPlaceholderPort(hit.id, point, _this.dragState.sourcePortId, _this.dragState.sourceElementId);
6991
7027
  if (placeholder) {
6992
7028
  var hostElement = _this.getElementById(hit.id);
6993
7029
  if (hostElement) {
@@ -8662,7 +8698,8 @@ var KonvaInteraction = /** @class */ (function () {
8662
8698
  return { createdLinkId: createdLinkId, targetPortId: targetPortId, targetElementId: targetElementId };
8663
8699
  };
8664
8700
  KonvaInteraction.prototype.tryCreateLinkToElement = function (sourcePortId, sourceElementId, targetElementId, worldPoint) {
8665
- var targetPort = this.createPortForLink(targetElementId, worldPoint, sourcePortId);
8701
+ var _a, _b;
8702
+ var targetPort = this.createPortForLink(targetElementId, worldPoint, sourcePortId, sourceElementId);
8666
8703
  if (!targetPort) {
8667
8704
  return { createdLinkId: null, targetPortId: null, targetElementId: null };
8668
8705
  }
@@ -8678,7 +8715,10 @@ var KonvaInteraction = /** @class */ (function () {
8678
8715
  return { createdLinkId: null, targetPortId: targetPort.id, targetElementId: targetElementId };
8679
8716
  }
8680
8717
  this.engine.addPortToElement(targetElementId, targetPort);
8681
- this.engine.movePortTo(targetPort.id, worldPoint.x, worldPoint.y);
8718
+ var targetElementWorld = (_a = this.engine.getElementWorldPosition(targetElementId)) !== null && _a !== void 0 ? _a : (_b = this.getElementById(targetElementId)) === null || _b === void 0 ? void 0 : _b.position;
8719
+ if (targetElementWorld) {
8720
+ this.engine.movePortTo(targetPort.id, targetElementWorld.x + targetPort.position.x, targetElementWorld.y + targetPort.position.y);
8721
+ }
8682
8722
  var createdLinkId = createId();
8683
8723
  this.engine.addLink({
8684
8724
  id: createdLinkId,
@@ -8688,61 +8728,139 @@ var KonvaInteraction = /** @class */ (function () {
8688
8728
  });
8689
8729
  return { createdLinkId: createdLinkId, targetPortId: targetPort.id, targetElementId: targetElementId };
8690
8730
  };
8691
- KonvaInteraction.prototype.createPortForLink = function (elementId, worldPoint, sourcePortId) {
8692
- var _a, _b, _c, _d;
8693
- var element = this.getElementById(elementId);
8694
- if (!element)
8731
+ KonvaInteraction.prototype.createPortForLink = function (elementId, worldPoint, sourcePortId, sourceElementId) {
8732
+ var resolved = this.resolveLinkTargetPortDraft(elementId, worldPoint, sourcePortId, sourceElementId, 'commit');
8733
+ if (!resolved)
8695
8734
  return null;
8696
- var elementPosition = (_a = this.engine.getElementWorldPosition(elementId)) !== null && _a !== void 0 ? _a : element.position;
8697
- var relative = {
8698
- x: worldPoint.x - elementPosition.x,
8699
- y: worldPoint.y - elementPosition.y,
8700
- };
8701
- var sourcePort = this.getPortById(sourcePortId);
8702
- var destinationMoveMode = ((_b = element.portMovement) === null || _b === void 0 ? void 0 : _b.moveMode) && element.portMovement.moveMode !== 'anchors'
8703
- ? element.portMovement.moveMode
8704
- : undefined;
8705
8735
  return {
8706
8736
  id: createId(),
8707
8737
  elementId: elementId,
8708
- position: relative,
8709
- shapeId: sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.shapeId,
8710
- size: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.size) ? __assign({}, sourcePort.size) : undefined,
8711
- style: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.style) ? __assign({}, sourcePort.style) : undefined,
8712
- moveMode: destinationMoveMode !== null && destinationMoveMode !== void 0 ? destinationMoveMode : sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.moveMode,
8713
- anchorCenter: (_c = sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.anchorCenter) !== null && _c !== void 0 ? _c : true,
8714
- orientToHostBorder: (_d = sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.orientToHostBorder) !== null && _d !== void 0 ? _d : true,
8715
- placementPoint: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.placementPoint) ? __assign({}, sourcePort.placementPoint) : undefined,
8716
- linkAttachPoint: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.linkAttachPoint) ? __assign({}, sourcePort.linkAttachPoint) : undefined,
8717
- externalLinkAttachPoint: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.externalLinkAttachPoint) ? __assign({}, sourcePort.externalLinkAttachPoint) : undefined,
8718
- internalLinkAttachPoint: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.internalLinkAttachPoint) ? __assign({}, sourcePort.internalLinkAttachPoint) : undefined,
8719
- rotationPivot: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.rotationPivot) ? __assign({}, sourcePort.rotationPivot) : undefined,
8738
+ position: __assign({}, resolved.draft.position),
8739
+ shapeId: resolved.draft.shapeId,
8740
+ size: resolved.draft.size ? __assign({}, resolved.draft.size) : undefined,
8741
+ style: resolved.draft.style ? __assign({}, resolved.draft.style) : undefined,
8742
+ textIds: resolved.draft.textIds ? __spreadArray([], resolved.draft.textIds, true) : undefined,
8743
+ moveMode: resolved.draft.moveMode,
8744
+ anchorCenter: resolved.draft.anchorCenter,
8745
+ orientToHostBorder: resolved.draft.orientToHostBorder,
8746
+ placementPoint: resolved.draft.placementPoint ? __assign({}, resolved.draft.placementPoint) : undefined,
8747
+ linkAttachPoint: resolved.draft.linkAttachPoint ? __assign({}, resolved.draft.linkAttachPoint) : undefined,
8748
+ externalLinkAttachPoint: resolved.draft.externalLinkAttachPoint ? __assign({}, resolved.draft.externalLinkAttachPoint) : undefined,
8749
+ internalLinkAttachPoint: resolved.draft.internalLinkAttachPoint ? __assign({}, resolved.draft.internalLinkAttachPoint) : undefined,
8750
+ rotationPivot: resolved.draft.rotationPivot ? __assign({}, resolved.draft.rotationPivot) : undefined,
8751
+ currentAnchorId: resolved.draft.currentAnchorId,
8720
8752
  };
8721
8753
  };
8722
- KonvaInteraction.prototype.createPlaceholderPort = function (elementId, worldPoint, sourcePortId) {
8723
- var _a, _b, _c;
8724
- var element = this.getElementById(elementId);
8725
- var sourcePort = this.getPortById(sourcePortId);
8726
- var destinationMoveMode = ((_a = element === null || element === void 0 ? void 0 : element.portMovement) === null || _a === void 0 ? void 0 : _a.moveMode) && element.portMovement.moveMode !== 'anchors'
8727
- ? element.portMovement.moveMode
8728
- : undefined;
8754
+ KonvaInteraction.prototype.createPlaceholderPort = function (elementId, worldPoint, sourcePortId, sourceElementId) {
8755
+ var _a;
8756
+ var resolved = this.resolveLinkTargetPortDraft(elementId, worldPoint, sourcePortId, sourceElementId, 'preview');
8757
+ if (!resolved)
8758
+ return null;
8759
+ var hostWorld = (_a = this.engine.getElementWorldPosition(elementId)) !== null && _a !== void 0 ? _a : resolved.targetElement.position;
8729
8760
  return {
8730
8761
  id: "port-placeholder:".concat(sourcePortId),
8731
8762
  elementId: elementId,
8732
- position: { x: worldPoint.x, y: worldPoint.y },
8733
- shapeId: sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.shapeId,
8734
- size: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.size) ? __assign({}, sourcePort.size) : undefined,
8735
- style: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.style) ? __assign({}, sourcePort.style) : undefined,
8736
- moveMode: destinationMoveMode !== null && destinationMoveMode !== void 0 ? destinationMoveMode : sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.moveMode,
8737
- anchorCenter: (_b = sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.anchorCenter) !== null && _b !== void 0 ? _b : true,
8738
- orientToHostBorder: (_c = sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.orientToHostBorder) !== null && _c !== void 0 ? _c : true,
8739
- placementPoint: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.placementPoint) ? __assign({}, sourcePort.placementPoint) : undefined,
8740
- linkAttachPoint: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.linkAttachPoint) ? __assign({}, sourcePort.linkAttachPoint) : undefined,
8741
- externalLinkAttachPoint: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.externalLinkAttachPoint) ? __assign({}, sourcePort.externalLinkAttachPoint) : undefined,
8742
- internalLinkAttachPoint: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.internalLinkAttachPoint) ? __assign({}, sourcePort.internalLinkAttachPoint) : undefined,
8743
- rotationPivot: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.rotationPivot) ? __assign({}, sourcePort.rotationPivot) : undefined,
8763
+ position: {
8764
+ x: hostWorld.x + resolved.draft.position.x,
8765
+ y: hostWorld.y + resolved.draft.position.y,
8766
+ },
8767
+ shapeId: resolved.draft.shapeId,
8768
+ size: resolved.draft.size ? __assign({}, resolved.draft.size) : undefined,
8769
+ style: resolved.draft.style ? __assign({}, resolved.draft.style) : undefined,
8770
+ textIds: resolved.draft.textIds ? __spreadArray([], resolved.draft.textIds, true) : undefined,
8771
+ moveMode: resolved.draft.moveMode,
8772
+ anchorCenter: resolved.draft.anchorCenter,
8773
+ orientToHostBorder: resolved.draft.orientToHostBorder,
8774
+ placementPoint: resolved.draft.placementPoint ? __assign({}, resolved.draft.placementPoint) : undefined,
8775
+ linkAttachPoint: resolved.draft.linkAttachPoint ? __assign({}, resolved.draft.linkAttachPoint) : undefined,
8776
+ externalLinkAttachPoint: resolved.draft.externalLinkAttachPoint ? __assign({}, resolved.draft.externalLinkAttachPoint) : undefined,
8777
+ internalLinkAttachPoint: resolved.draft.internalLinkAttachPoint ? __assign({}, resolved.draft.internalLinkAttachPoint) : undefined,
8778
+ rotationPivot: resolved.draft.rotationPivot ? __assign({}, resolved.draft.rotationPivot) : undefined,
8779
+ currentAnchorId: resolved.draft.currentAnchorId,
8780
+ };
8781
+ };
8782
+ KonvaInteraction.prototype.resolveLinkTargetPortDraft = function (elementId, worldPoint, sourcePortId, sourceElementId, phase) {
8783
+ var _a;
8784
+ var targetElement = this.getElementById(elementId);
8785
+ var sourcePort = this.resolveLinkSourcePort(sourcePortId);
8786
+ if (!targetElement || !sourcePort)
8787
+ return null;
8788
+ var defaultDraft = this.buildDefaultLinkTargetPortDraft(targetElement, worldPoint, sourcePort);
8789
+ var override = (_a = this.onCreateLinkTargetPort) === null || _a === void 0 ? void 0 : _a.call(this, {
8790
+ phase: phase,
8791
+ pointer: __assign({}, worldPoint),
8792
+ sourcePortId: sourcePortId,
8793
+ sourceElementId: sourceElementId,
8794
+ targetElementId: elementId,
8795
+ sourcePort: this.clonePortData(sourcePort),
8796
+ targetElement: this.cloneElementData(targetElement),
8797
+ defaultPort: this.cloneLinkTargetPortDraft(defaultDraft),
8798
+ });
8799
+ var mergedDraft = this.mergeLinkTargetPortDraft(defaultDraft, override);
8800
+ var normalizedDraft = this.engine.normalizePortDraftForElement(elementId, mergedDraft);
8801
+ if (!normalizedDraft)
8802
+ return null;
8803
+ return {
8804
+ draft: normalizedDraft,
8805
+ targetElement: this.cloneElementData(targetElement),
8806
+ };
8807
+ };
8808
+ KonvaInteraction.prototype.buildDefaultLinkTargetPortDraft = function (element, worldPoint, sourcePort) {
8809
+ var _a, _b, _c, _d;
8810
+ var elementPosition = (_a = this.engine.getElementWorldPosition(element.id)) !== null && _a !== void 0 ? _a : element.position;
8811
+ var destinationMoveMode = ((_b = element.portMovement) === null || _b === void 0 ? void 0 : _b.moveMode) && element.portMovement.moveMode !== 'anchors'
8812
+ ? element.portMovement.moveMode
8813
+ : undefined;
8814
+ return {
8815
+ position: {
8816
+ x: worldPoint.x - elementPosition.x,
8817
+ y: worldPoint.y - elementPosition.y,
8818
+ },
8819
+ shapeId: sourcePort.shapeId,
8820
+ size: sourcePort.size ? __assign({}, sourcePort.size) : undefined,
8821
+ style: sourcePort.style ? __assign({}, sourcePort.style) : undefined,
8822
+ moveMode: destinationMoveMode !== null && destinationMoveMode !== void 0 ? destinationMoveMode : sourcePort.moveMode,
8823
+ anchorCenter: (_c = sourcePort.anchorCenter) !== null && _c !== void 0 ? _c : true,
8824
+ orientToHostBorder: (_d = sourcePort.orientToHostBorder) !== null && _d !== void 0 ? _d : true,
8825
+ placementPoint: sourcePort.placementPoint ? __assign({}, sourcePort.placementPoint) : undefined,
8826
+ linkAttachPoint: sourcePort.linkAttachPoint ? __assign({}, sourcePort.linkAttachPoint) : undefined,
8827
+ externalLinkAttachPoint: sourcePort.externalLinkAttachPoint ? __assign({}, sourcePort.externalLinkAttachPoint) : undefined,
8828
+ internalLinkAttachPoint: sourcePort.internalLinkAttachPoint ? __assign({}, sourcePort.internalLinkAttachPoint) : undefined,
8829
+ rotationPivot: sourcePort.rotationPivot ? __assign({}, sourcePort.rotationPivot) : undefined,
8744
8830
  };
8745
8831
  };
8832
+ KonvaInteraction.prototype.mergeLinkTargetPortDraft = function (defaultDraft, override) {
8833
+ return this.cloneLinkTargetPortDraft(__assign(__assign({}, defaultDraft), (override !== null && override !== void 0 ? override : {})));
8834
+ };
8835
+ KonvaInteraction.prototype.resolveLinkSourcePort = function (sourcePortId) {
8836
+ var _a, _b;
8837
+ if (((_a = this.programmaticLinkSession) === null || _a === void 0 ? void 0 : _a.sourcePortId) === sourcePortId) {
8838
+ return this.clonePortData(this.programmaticLinkSession.sourcePort);
8839
+ }
8840
+ if (((_b = this.dragState) === null || _b === void 0 ? void 0 : _b.mode) === 'link-drag' && this.dragState.sourcePortId === sourcePortId) {
8841
+ return this.clonePortData(this.dragState.sourcePort);
8842
+ }
8843
+ var sourcePort = this.getPortById(sourcePortId);
8844
+ return sourcePort ? this.clonePortData(sourcePort) : null;
8845
+ };
8846
+ KonvaInteraction.prototype.clonePortData = function (port) {
8847
+ return __assign(__assign({}, port), { position: __assign({}, port.position), size: port.size ? __assign({}, port.size) : undefined, style: port.style ? __assign({}, port.style) : undefined, textIds: port.textIds ? __spreadArray([], port.textIds, true) : undefined, placementPoint: port.placementPoint ? __assign({}, port.placementPoint) : undefined, linkAttachPoint: port.linkAttachPoint ? __assign({}, port.linkAttachPoint) : undefined, externalLinkAttachPoint: port.externalLinkAttachPoint ? __assign({}, port.externalLinkAttachPoint) : undefined, internalLinkAttachPoint: port.internalLinkAttachPoint ? __assign({}, port.internalLinkAttachPoint) : undefined, rotationPivot: port.rotationPivot ? __assign({}, port.rotationPivot) : undefined });
8848
+ };
8849
+ KonvaInteraction.prototype.cloneLinkTargetPortDraft = function (draft) {
8850
+ return __assign(__assign({}, draft), { position: __assign({}, draft.position), size: draft.size ? __assign({}, draft.size) : undefined, style: draft.style ? __assign({}, draft.style) : undefined, textIds: draft.textIds ? __spreadArray([], draft.textIds, true) : undefined, placementPoint: draft.placementPoint ? __assign({}, draft.placementPoint) : undefined, linkAttachPoint: draft.linkAttachPoint ? __assign({}, draft.linkAttachPoint) : undefined, externalLinkAttachPoint: draft.externalLinkAttachPoint ? __assign({}, draft.externalLinkAttachPoint) : undefined, internalLinkAttachPoint: draft.internalLinkAttachPoint ? __assign({}, draft.internalLinkAttachPoint) : undefined, rotationPivot: draft.rotationPivot ? __assign({}, draft.rotationPivot) : undefined });
8851
+ };
8852
+ KonvaInteraction.prototype.cloneElementData = function (element) {
8853
+ return __assign(__assign({}, element), { position: __assign({}, element.position), size: __assign({}, element.size), style: element.style ? __assign({}, element.style) : undefined, portIds: element.portIds ? __spreadArray([], element.portIds, true) : undefined, textIds: element.textIds ? __spreadArray([], element.textIds, true) : undefined, layout: element.layout ? __assign({}, element.layout) : undefined, childElementInteraction: element.childElementInteraction ? __assign({}, element.childElementInteraction) : undefined, portMovement: element.portMovement
8854
+ ? __assign(__assign({}, element.portMovement), { anchorConstraint: element.portMovement.anchorConstraint
8855
+ ? __assign({}, element.portMovement.anchorConstraint) : undefined, positionLimits: element.portMovement.positionLimits
8856
+ ? {
8857
+ x: element.portMovement.positionLimits.x
8858
+ ? __assign({}, element.portMovement.positionLimits.x) : undefined,
8859
+ y: element.portMovement.positionLimits.y
8860
+ ? __assign({}, element.portMovement.positionLimits.y) : undefined,
8861
+ }
8862
+ : undefined }) : undefined });
8863
+ };
8746
8864
  KonvaInteraction.prototype.getElementById = function (id) {
8747
8865
  return this.engine.getState().elements.find(function (element) { return element.id === id; });
8748
8866
  };
@@ -9859,6 +9977,7 @@ var createDiagramEditor = function (config) {
9859
9977
  shapeHoverControls: config.elementShapeHoverControls,
9860
9978
  onShapeHoverControlInteracted: config.onElementShapeHoverControlInteraction,
9861
9979
  onShapeHoverControlActivated: config.onElementShapeHoverControlActivated,
9980
+ onCreateLinkTargetPort: config.onCreateLinkTargetPort,
9862
9981
  });
9863
9982
  interaction.bind();
9864
9983
  if (config.initialState) {
@@ -1,4 +1,4 @@
1
- import { DiagramEngineHandle, Point, DiagramState, ElementShapeHoverControlActivationEvent, ElementShapeHoverControlInteractionEvent, ElementShapeHoverControls, EngineChangeEvent, EngineSelectionEvent, LinkColorPoolPolicy, LinkRouteRefreshPolicy, ViewportFitOptions } from './types';
1
+ import { DiagramEngineHandle, Point, DiagramState, ElementShapeHoverControlActivationEvent, ElementShapeHoverControlInteractionEvent, ElementShapeHoverControls, EngineChangeEvent, EngineSelectionEvent, LinkTargetPortCreationHandler, LinkColorPoolPolicy, LinkRouteRefreshPolicy, ViewportFitOptions } from './types';
2
2
  import { type BuiltInShapeKind } from '../shapes';
3
3
  export type SimpleShape = {
4
4
  id: string;
@@ -16,6 +16,7 @@ export type DiagramEditorConfig = {
16
16
  elementShapeHoverControls?: ElementShapeHoverControls;
17
17
  onElementShapeHoverControlInteraction?: (event: ElementShapeHoverControlInteractionEvent) => void;
18
18
  onElementShapeHoverControlActivated?: (event: ElementShapeHoverControlActivationEvent) => void;
19
+ onCreateLinkTargetPort?: LinkTargetPortCreationHandler;
19
20
  onChange?: (event: EngineChangeEvent) => void;
20
21
  onSelection?: (event: EngineSelectionEvent) => void;
21
22
  linkRouteRefreshPolicy?: LinkRouteRefreshPolicy;
@@ -297,6 +297,20 @@ export type PortData = {
297
297
  rotationPivot?: Point;
298
298
  currentAnchorId?: string;
299
299
  };
300
+ export type LinkTargetPortCreationPhase = 'preview' | 'commit';
301
+ export type LinkTargetPortDraft = Omit<PortData, 'id' | 'elementId'>;
302
+ export type LinkTargetPortCreationContext = {
303
+ phase: LinkTargetPortCreationPhase;
304
+ pointer: Point;
305
+ sourcePortId: string;
306
+ sourceElementId: string;
307
+ targetElementId: string;
308
+ sourcePort: PortData;
309
+ targetElement: ElementData;
310
+ defaultPort: LinkTargetPortDraft;
311
+ };
312
+ export type LinkTargetPortCreationResult = Partial<LinkTargetPortDraft> | void;
313
+ export type LinkTargetPortCreationHandler = (context: LinkTargetPortCreationContext) => LinkTargetPortCreationResult;
300
314
  export type ShapeDrawContext = {
301
315
  ctx: CanvasRenderingContext2D;
302
316
  model: ElementData | PortData;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const LinkPortCreationDemo: () => React.JSX.Element;
3
+ export default LinkPortCreationDemo;
@@ -0,0 +1,4 @@
1
+ import type { DiagramState } from '../../api';
2
+ import type { DemoConfig } from '../types';
3
+ export declare const createLinkLabelsState: () => DiagramState;
4
+ export declare const linkLabelsDemoConfig: DemoConfig;
@@ -25,11 +25,14 @@ export type DemoConfig = {
25
25
  stageStyle?: CSSProperties;
26
26
  actions: DemoAction[];
27
27
  };
28
+ export type DemoMenuGroup = 'basics' | 'layoutText' | 'shapes' | 'portsAnchors' | 'linksRouting' | 'eventsIntegration';
28
29
  export type DemoDefinition = {
29
30
  id: string;
30
31
  title: string;
31
32
  description: string;
32
33
  Component: React.ComponentType;
34
+ menuGroup: DemoMenuGroup;
35
+ menuOrder: number;
33
36
  };
34
37
  export type ToolboxItem = {
35
38
  id: string;
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import type { DiagramEditorHandle, DiagramState, ElementShapeHoverControlActivationEvent, ElementShapeHoverControlInteractionEvent, ElementShapeHoverControls, LinkColorPoolPolicy, LinkRouteRefreshPolicy, SimpleShape } from '../api';
2
+ import type { DiagramEditorHandle, DiagramState, ElementShapeHoverControlActivationEvent, ElementShapeHoverControlInteractionEvent, ElementShapeHoverControls, LinkColorPoolPolicy, LinkTargetPortCreationHandler, LinkRouteRefreshPolicy, SimpleShape } from '../api';
3
3
  import type { RouterStrategy } from '../strategies/RouterStrategy';
4
4
  import type { ViewportSnapshot } from './types';
5
5
  type DemoEditorConfig = {
@@ -13,8 +13,9 @@ type DemoEditorConfig = {
13
13
  elementShapeHoverControls?: ElementShapeHoverControls;
14
14
  onElementShapeHoverControlInteraction?: (event: ElementShapeHoverControlInteractionEvent) => void;
15
15
  onElementShapeHoverControlActivated?: (event: ElementShapeHoverControlActivationEvent) => void;
16
+ onCreateLinkTargetPort?: LinkTargetPortCreationHandler;
16
17
  };
17
- declare const useDemoEditor: ({ createState, elementShapes, portShapes, router, snapDefault, linkRouteRefreshPolicy, linkColorPoolPolicy, elementShapeHoverControls, onElementShapeHoverControlInteraction, onElementShapeHoverControlActivated, }: DemoEditorConfig) => {
18
+ declare const useDemoEditor: ({ createState, elementShapes, portShapes, router, snapDefault, linkRouteRefreshPolicy, linkColorPoolPolicy, elementShapeHoverControls, onElementShapeHoverControlInteraction, onElementShapeHoverControlActivated, onCreateLinkTargetPort, }: DemoEditorConfig) => {
18
19
  containerRef: import("react").MutableRefObject<HTMLDivElement | null>;
19
20
  editorRef: import("react").MutableRefObject<DiagramEditorHandle | null>;
20
21
  diagramState: DiagramState | null;
@@ -1,4 +1,4 @@
1
- import { DiagramEngineHandle, DiagramState, ElementData, EngineEventMap, ElementDropEvent, EnginePointerInfo, LinkData, LinkColorPoolPolicy, ElementLinkConnectingEvent, LinkRoutingMode, LinkRouteRefreshPolicy, OverlayShapeConfig, OverlayShapeHandle, Point, PortData, RerouteLinksOptions, TextData, PortMouseEvent } from '../api/types';
1
+ import { DiagramEngineHandle, DiagramState, ElementData, EngineEventMap, ElementDropEvent, EnginePointerInfo, LinkData, LinkColorPoolPolicy, ElementLinkConnectingEvent, LinkRoutingMode, LinkRouteRefreshPolicy, LinkTargetPortDraft, 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';
@@ -61,6 +61,7 @@ export default class DiagramEngine {
61
61
  setElementLayout(id: string, layout: ElementData['layout']): void;
62
62
  removeElement(id: string): void;
63
63
  addPortToElement(elementId: string, port: PortData): void;
64
+ normalizePortDraftForElement(elementId: string, draft: LinkTargetPortDraft): LinkTargetPortDraft | null;
64
65
  movePortTo(id: string, x: number, y: number): void;
65
66
  removePort(id: string): void;
66
67
  addLink(link: LinkData): void;
@@ -29,6 +29,7 @@ export default class TextLayoutService {
29
29
  private collectResizedElementIds;
30
30
  private shouldTrackOwnerBoundLayout;
31
31
  private resolveTextLayoutBounds;
32
+ private resolveDefaultBoundsMode;
32
33
  private wrapText;
33
34
  private wrapByWord;
34
35
  private wrapByChar;
@@ -1,2 +1,2 @@
1
1
  export { demoTabs, baseElementShapes, basePortShapes, customGalleryShapes, defaultGhostSize, defaultSvgPath, defaultSvgPathSize, externalToolboxItems, } from '../displaybox/demos';
2
- export type { DemoAction, DemoActionHelpers, DemoConfig, DemoDefinition, ToolboxItem, DiagramCounts, ViewportSnapshot, DisplayBoxMetrics, } from '../displaybox/types';
2
+ export type { DemoAction, DemoActionHelpers, DemoConfig, DemoDefinition, DemoMenuGroup, ToolboxItem, DiagramCounts, ViewportSnapshot, DisplayBoxMetrics, } from '../displaybox/types';
@@ -1,4 +1,4 @@
1
- import { ElementShapeHoverControlActivationEvent, ElementShapeHoverControlInteractionEvent, ElementShapeHoverControls, Point, PortData } from '../../api/types';
1
+ import { ElementShapeHoverControlActivationEvent, ElementShapeHoverControlInteractionEvent, ElementShapeHoverControls, LinkTargetPortCreationHandler, Point, PortData } from '../../api/types';
2
2
  import DiagramEngine from '../../engine/DiagramEngine';
3
3
  import KonvaHitTester from './KonvaHitTester';
4
4
  import { KonvaStageLike, ShapeHoverControlRenderConfig } from './KonvaRenderer';
@@ -11,6 +11,7 @@ export type InteractionConfig = {
11
11
  shapeHoverControls?: ElementShapeHoverControls;
12
12
  onShapeHoverControlInteracted?: (event: ElementShapeHoverControlInteractionEvent) => void;
13
13
  onShapeHoverControlActivated?: (event: ElementShapeHoverControlActivationEvent) => void;
14
+ onCreateLinkTargetPort?: LinkTargetPortCreationHandler;
14
15
  renderer?: {
15
16
  renderResizeHandles: (elementId: string, position: Point, size: {
16
17
  width: number;
@@ -55,6 +56,7 @@ export default class KonvaInteraction {
55
56
  private shapeHoverControls?;
56
57
  private onShapeHoverControlInteracted?;
57
58
  private onShapeHoverControlActivated?;
59
+ private onCreateLinkTargetPort?;
58
60
  private linkDragContext;
59
61
  private programmaticLinkSession;
60
62
  private bound;
@@ -142,6 +144,13 @@ export default class KonvaInteraction {
142
144
  private tryCreateLinkToElement;
143
145
  private createPortForLink;
144
146
  private createPlaceholderPort;
147
+ private resolveLinkTargetPortDraft;
148
+ private buildDefaultLinkTargetPortDraft;
149
+ private mergeLinkTargetPortDraft;
150
+ private resolveLinkSourcePort;
151
+ private clonePortData;
152
+ private cloneLinkTargetPortDraft;
153
+ private cloneElementData;
145
154
  private getElementById;
146
155
  private getPortById;
147
156
  private getTextById;