orcasvn-react-diagrams 0.2.11 → 0.2.13

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 (55) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +15 -7
  3. package/ai/api-contract.json +90 -1
  4. package/ai/invariants.json +6 -2
  5. package/ai/manifest.json +1 -1
  6. package/dist/cjs/examples.js +916 -331
  7. package/dist/cjs/index.js +406 -97
  8. package/dist/cjs/types/api/createDiagramEditor.d.ts +3 -1
  9. package/dist/cjs/types/api/types.d.ts +64 -0
  10. package/dist/cjs/types/displaybox/demos/LinkPortCreationDemoTab.d.ts +3 -0
  11. package/dist/cjs/types/displaybox/demos/deletionEventsDemo.d.ts +2 -0
  12. package/dist/cjs/types/displaybox/demos/focusElementDemo.d.ts +4 -0
  13. package/dist/cjs/types/displaybox/demos/linkLabelsDemo.d.ts +4 -0
  14. package/dist/cjs/types/displaybox/types.d.ts +3 -0
  15. package/dist/cjs/types/displaybox/useDemoEditor.d.ts +3 -2
  16. package/dist/cjs/types/engine/DiagramEngine.d.ts +11 -1
  17. package/dist/cjs/types/engine/TextLayoutService.d.ts +1 -0
  18. package/dist/cjs/types/examples/index.d.ts +1 -1
  19. package/dist/cjs/types/renderer/konva/KonvaInteraction.d.ts +10 -1
  20. package/dist/esm/examples.js +916 -331
  21. package/dist/esm/examples.js.map +1 -1
  22. package/dist/esm/index.js +406 -97
  23. package/dist/esm/index.js.map +1 -1
  24. package/dist/esm/types/api/createDiagramEditor.d.ts +3 -1
  25. package/dist/esm/types/api/types.d.ts +64 -0
  26. package/dist/esm/types/displaybox/demos/LinkPortCreationDemoTab.d.ts +3 -0
  27. package/dist/esm/types/displaybox/demos/deletionEventsDemo.d.ts +2 -0
  28. package/dist/esm/types/displaybox/demos/focusElementDemo.d.ts +4 -0
  29. package/dist/esm/types/displaybox/demos/linkLabelsDemo.d.ts +4 -0
  30. package/dist/esm/types/displaybox/types.d.ts +3 -0
  31. package/dist/esm/types/displaybox/useDemoEditor.d.ts +3 -2
  32. package/dist/esm/types/engine/DiagramEngine.d.ts +11 -1
  33. package/dist/esm/types/engine/TextLayoutService.d.ts +1 -0
  34. package/dist/esm/types/examples/index.d.ts +1 -1
  35. package/dist/esm/types/renderer/konva/KonvaInteraction.d.ts +10 -1
  36. package/dist/examples.d.ts +55 -1
  37. package/dist/index.d.ts +67 -1
  38. package/docs/API_CONTRACT.md +88 -1
  39. package/docs/ARCHITECTURE.md +9 -7
  40. package/docs/CAPABILITIES.md +5 -0
  41. package/docs/COMMANDS_EVENTS.md +16 -6
  42. package/docs/DOCUMENTATION_WORKFLOW.md +5 -1
  43. package/docs/INTEGRATION_PLAYBOOK.md +8 -0
  44. package/docs/PORTING_CHECKLIST.md +4 -1
  45. package/docs/STATE_INVARIANTS.md +3 -0
  46. package/package.json +1 -1
  47. package/src/displaybox/demos/DeletionEventsDemoTab.tsx +167 -9
  48. package/src/displaybox/demos/LinkPortCreationDemoTab.tsx +98 -0
  49. package/src/displaybox/demos/deletionEventsDemo.ts +2 -2
  50. package/src/displaybox/demos/focusElementDemo.ts +91 -0
  51. package/src/displaybox/demos/index.tsx +124 -221
  52. package/src/displaybox/demos/linkLabelsDemo.ts +164 -0
  53. package/src/displaybox/demos/linkPortCreationDemo.ts +7 -7
  54. package/src/displaybox/types.ts +21 -11
  55. 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)) {
@@ -4130,8 +4137,15 @@ var DiagramEngine = /** @class */ (function () {
4130
4137
  var _this = this;
4131
4138
  var _a;
4132
4139
  var existing = this.model.getElement(id);
4133
- var parentId = (_a = existing === null || existing === void 0 ? void 0 : existing.parentId) !== null && _a !== void 0 ? _a : null;
4140
+ if (!existing)
4141
+ return;
4142
+ var parentId = (_a = existing.parentId) !== null && _a !== void 0 ? _a : null;
4134
4143
  var before = this.model.toState();
4144
+ var root = { entity: 'element', id: id };
4145
+ var plannedRemoval = this.planRemoval(before, root);
4146
+ if (!plannedRemoval || this.emitDeletionLifecycleEvents(plannedRemoval.removed, root, 'direct')) {
4147
+ return;
4148
+ }
4135
4149
  this.commandQueue.run(createRemoveElementCommand(id), this.model);
4136
4150
  var removal = this.computeRemovalDiff(before);
4137
4151
  var allPatches = this.mutationPipeline.run({
@@ -4139,9 +4153,6 @@ var DiagramEngine = /** @class */ (function () {
4139
4153
  layoutSteps: [function () { return _this.applyLayoutCascade(parentId); }],
4140
4154
  });
4141
4155
  this.emitChange(allPatches);
4142
- if (existing) {
4143
- this.events.emit('elementDeleted', { elementId: id });
4144
- }
4145
4156
  this.emitEntityDeletionEvents(removal.removed);
4146
4157
  };
4147
4158
  DiagramEngine.prototype.addPortToElement = function (elementId, port) {
@@ -4156,6 +4167,24 @@ var DiagramEngine = /** @class */ (function () {
4156
4167
  var patches = this.commandQueue.run(createAddPortCommand(nextPort), this.model);
4157
4168
  this.emitChange(patches);
4158
4169
  };
4170
+ DiagramEngine.prototype.normalizePortDraftForElement = function (elementId, draft) {
4171
+ var _a;
4172
+ var element = this.model.getElement(elementId);
4173
+ if (!element)
4174
+ return null;
4175
+ 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 });
4176
+ var constrained = this.resolveConstrainedPortRelativePosition({
4177
+ position: nextDraft.position,
4178
+ size: nextDraft.size,
4179
+ style: nextDraft.style,
4180
+ moveMode: nextDraft.moveMode,
4181
+ anchorCenter: nextDraft.anchorCenter,
4182
+ currentAnchorId: nextDraft.currentAnchorId,
4183
+ }, element, nextDraft.position);
4184
+ nextDraft.position = constrained.position;
4185
+ nextDraft.currentAnchorId = (_a = constrained.currentAnchorId) !== null && _a !== void 0 ? _a : undefined;
4186
+ return nextDraft;
4187
+ };
4159
4188
  DiagramEngine.prototype.movePortTo = function (id, x, y) {
4160
4189
  var snapped = this.snapper.snap({ x: x, y: y });
4161
4190
  var port = this.model.getPort(id);
@@ -4204,7 +4233,14 @@ var DiagramEngine = /** @class */ (function () {
4204
4233
  }
4205
4234
  };
4206
4235
  DiagramEngine.prototype.removePort = function (id) {
4236
+ if (!this.model.getPort(id))
4237
+ return;
4207
4238
  var before = this.model.toState();
4239
+ var root = { entity: 'port', id: id };
4240
+ var plannedRemoval = this.planRemoval(before, root);
4241
+ if (!plannedRemoval || this.emitDeletionLifecycleEvents(plannedRemoval.removed, root, 'direct')) {
4242
+ return;
4243
+ }
4208
4244
  this.commandQueue.run(createRemovePortCommand(id), this.model);
4209
4245
  var removal = this.computeRemovalDiff(before);
4210
4246
  this.emitChange(removal.patches);
@@ -4298,7 +4334,14 @@ var DiagramEngine = /** @class */ (function () {
4298
4334
  }
4299
4335
  };
4300
4336
  DiagramEngine.prototype.removeLink = function (id) {
4337
+ if (!this.model.getLink(id))
4338
+ return;
4301
4339
  var before = this.model.toState();
4340
+ var root = { entity: 'link', id: id };
4341
+ var plannedRemoval = this.planRemoval(before, root);
4342
+ if (!plannedRemoval || this.emitDeletionLifecycleEvents(plannedRemoval.removed, root, 'direct')) {
4343
+ return;
4344
+ }
4302
4345
  this.commandQueue.run(createRemoveLinkCommand(id), this.model);
4303
4346
  var removal = this.computeRemovalDiff(before);
4304
4347
  this.emitChange(removal.patches);
@@ -4383,7 +4426,14 @@ var DiagramEngine = /** @class */ (function () {
4383
4426
  this.emitChange(patches);
4384
4427
  };
4385
4428
  DiagramEngine.prototype.removeText = function (id) {
4429
+ if (!this.model.getText(id))
4430
+ return;
4386
4431
  var before = this.model.toState();
4432
+ var root = { entity: 'text', id: id };
4433
+ var plannedRemoval = this.planRemoval(before, root);
4434
+ if (!plannedRemoval || this.emitDeletionLifecycleEvents(plannedRemoval.removed, root, 'direct')) {
4435
+ return;
4436
+ }
4387
4437
  this.commandQueue.run(createRemoveTextCommand(id), this.model);
4388
4438
  var removal = this.computeRemovalDiff(before);
4389
4439
  this.emitChange(removal.patches);
@@ -4578,40 +4628,22 @@ var DiagramEngine = /** @class */ (function () {
4578
4628
  if (selected.length === 0)
4579
4629
  return;
4580
4630
  var before = this.model.toState();
4581
- var elementIds = [];
4582
- selected.forEach(function (id) {
4583
- if (_this.model.getElement(id))
4584
- elementIds.push(id);
4585
- else if (_this.model.getPort(id))
4586
- ;
4587
- else if (_this.model.getLink(id))
4588
- ;
4589
- else if (_this.model.getText(id))
4590
- ;
4591
- });
4592
4631
  selected.forEach(function (id) {
4593
- if (_this.model.getElement(id)) {
4594
- _this.commandQueue.run(createRemoveElementCommand(id), _this.model);
4632
+ var root = _this.resolveDeletionRoot(id);
4633
+ if (!root)
4595
4634
  return;
4596
- }
4597
- if (_this.model.getPort(id)) {
4598
- _this.commandQueue.run(createRemovePortCommand(id), _this.model);
4635
+ var currentState = _this.model.toState();
4636
+ var plannedRemoval = _this.planRemoval(currentState, root);
4637
+ if (!plannedRemoval || _this.emitDeletionLifecycleEvents(plannedRemoval.removed, root, 'selection')) {
4599
4638
  return;
4600
4639
  }
4601
- if (_this.model.getLink(id)) {
4602
- _this.commandQueue.run(createRemoveLinkCommand(id), _this.model);
4603
- return;
4604
- }
4605
- if (_this.model.getText(id)) {
4606
- _this.commandQueue.run(createRemoveTextCommand(id), _this.model);
4607
- }
4640
+ _this.applyRemovalCommand(root);
4608
4641
  });
4609
4642
  var removal = this.computeRemovalDiff(before);
4643
+ if (removal.patches.length === 0)
4644
+ return;
4610
4645
  this.emitChange(removal.patches);
4611
4646
  this.emitEntityDeletionEvents(removal.removed);
4612
- elementIds.forEach(function (elementId) { return _this.events.emit('elementDeleted', { elementId: elementId }); });
4613
- this.selection.clear();
4614
- this.emitSelection();
4615
4647
  };
4616
4648
  DiagramEngine.prototype.setViewport = function (pan, zoom) {
4617
4649
  var hasPanChange = this.viewport.pan.x !== pan.x || this.viewport.pan.y !== pan.y;
@@ -4664,6 +4696,9 @@ var DiagramEngine = /** @class */ (function () {
4664
4696
  DiagramEngine.prototype.emitElementClick = function (elementId, pointer, isMulti) {
4665
4697
  this.events.emit('elementClick', { elementId: elementId, pointer: pointer, isMulti: isMulti });
4666
4698
  };
4699
+ DiagramEngine.prototype.emitElementDoubleClick = function (elementId, pointer, isMulti) {
4700
+ this.events.emit('elementDoubleClick', { elementId: elementId, pointer: pointer, isMulti: isMulti });
4701
+ };
4667
4702
  DiagramEngine.prototype.emitElementLinkStarted = function (event) {
4668
4703
  this.events.emit('elementLinkStarted', event);
4669
4704
  };
@@ -5307,8 +5342,8 @@ var DiagramEngine = /** @class */ (function () {
5307
5342
  });
5308
5343
  return { patches: normalizedPatches, movedPortIds: Array.from(movedPortIds) };
5309
5344
  };
5310
- DiagramEngine.prototype.computeRemovalDiff = function (before) {
5311
- var after = this.model.toState();
5345
+ DiagramEngine.prototype.computeRemovalDiff = function (before, after) {
5346
+ if (after === void 0) { after = this.model.toState(); }
5312
5347
  var removedPatches = [];
5313
5348
  var beforeElements = new Set(before.elements.map(function (element) { return element.id; }));
5314
5349
  var beforePorts = new Set(before.ports.map(function (port) { return port.id; }));
@@ -5318,9 +5353,13 @@ var DiagramEngine = /** @class */ (function () {
5318
5353
  var afterPorts = new Set(after.ports.map(function (port) { return port.id; }));
5319
5354
  var afterLinks = new Set(after.links.map(function (link) { return link.id; }));
5320
5355
  var afterTexts = new Set(after.texts.map(function (text) { return text.id; }));
5356
+ var removedElements = [];
5321
5357
  beforeElements.forEach(function (id) {
5322
5358
  if (!afterElements.has(id))
5323
5359
  removedPatches.push(patchRemove('element', id));
5360
+ var removedElement = before.elements.find(function (element) { return element.id === id; });
5361
+ if (!afterElements.has(id) && removedElement)
5362
+ removedElements.push(removedElement);
5324
5363
  });
5325
5364
  var removedPorts = [];
5326
5365
  beforePorts.forEach(function (id) {
@@ -5351,11 +5390,144 @@ var DiagramEngine = /** @class */ (function () {
5351
5390
  });
5352
5391
  return {
5353
5392
  patches: removedPatches,
5354
- removed: { ports: removedPorts, links: removedLinks, texts: removedTexts },
5393
+ removed: { elements: removedElements, ports: removedPorts, links: removedLinks, texts: removedTexts },
5355
5394
  };
5356
5395
  };
5396
+ DiagramEngine.prototype.resolveDeletionRoot = function (id) {
5397
+ if (this.model.getElement(id))
5398
+ return { entity: 'element', id: id };
5399
+ if (this.model.getPort(id))
5400
+ return { entity: 'port', id: id };
5401
+ if (this.model.getLink(id))
5402
+ return { entity: 'link', id: id };
5403
+ if (this.model.getText(id))
5404
+ return { entity: 'text', id: id };
5405
+ return null;
5406
+ };
5407
+ DiagramEngine.prototype.applyRemovalCommand = function (root) {
5408
+ if (root.entity === 'element') {
5409
+ this.commandQueue.run(createRemoveElementCommand(root.id), this.model);
5410
+ return;
5411
+ }
5412
+ if (root.entity === 'port') {
5413
+ this.commandQueue.run(createRemovePortCommand(root.id), this.model);
5414
+ return;
5415
+ }
5416
+ if (root.entity === 'link') {
5417
+ this.commandQueue.run(createRemoveLinkCommand(root.id), this.model);
5418
+ return;
5419
+ }
5420
+ this.commandQueue.run(createRemoveTextCommand(root.id), this.model);
5421
+ };
5422
+ DiagramEngine.prototype.planRemoval = function (before, root) {
5423
+ var tempModel = new DiagramModel();
5424
+ tempModel.load(before);
5425
+ if (root.entity === 'element') {
5426
+ tempModel.removeElement(root.id);
5427
+ }
5428
+ else if (root.entity === 'port') {
5429
+ tempModel.removePort(root.id);
5430
+ }
5431
+ else if (root.entity === 'link') {
5432
+ tempModel.removeLink(root.id);
5433
+ }
5434
+ else {
5435
+ tempModel.removeText(root.id);
5436
+ }
5437
+ return this.computeRemovalDiff(before, tempModel.toState());
5438
+ };
5439
+ DiagramEngine.prototype.emitDeletionLifecycleEvents = function (removed, root, rootTrigger) {
5440
+ for (var _i = 0, _a = removed.elements; _i < _a.length; _i++) {
5441
+ var element = _a[_i];
5442
+ var trigger = root.entity === 'element' && element.id === root.id ? rootTrigger : 'cascade';
5443
+ if (this.emitElementDeleting({
5444
+ elementId: element.id,
5445
+ trigger: trigger,
5446
+ root: root,
5447
+ })) {
5448
+ return true;
5449
+ }
5450
+ }
5451
+ for (var _b = 0, _c = removed.ports; _b < _c.length; _b++) {
5452
+ var port = _c[_b];
5453
+ var trigger = root.entity === 'port' && port.id === root.id ? rootTrigger : 'cascade';
5454
+ if (this.emitPortDeleting({
5455
+ portId: port.id,
5456
+ elementId: port.elementId,
5457
+ trigger: trigger,
5458
+ root: root,
5459
+ })) {
5460
+ return true;
5461
+ }
5462
+ }
5463
+ for (var _d = 0, _e = removed.links; _d < _e.length; _d++) {
5464
+ var link = _e[_d];
5465
+ var trigger = root.entity === 'link' && link.id === root.id ? rootTrigger : 'cascade';
5466
+ if (this.emitLinkDeleting({
5467
+ linkId: link.id,
5468
+ sourcePortId: link.sourcePortId,
5469
+ targetPortId: link.targetPortId,
5470
+ trigger: trigger,
5471
+ root: root,
5472
+ })) {
5473
+ return true;
5474
+ }
5475
+ }
5476
+ for (var _f = 0, _g = removed.texts; _f < _g.length; _f++) {
5477
+ var text = _g[_f];
5478
+ var trigger = root.entity === 'text' && text.id === root.id ? rootTrigger : 'cascade';
5479
+ if (this.emitTextDeleting({
5480
+ textId: text.id,
5481
+ ownerId: text.ownerId,
5482
+ trigger: trigger,
5483
+ root: root,
5484
+ })) {
5485
+ return true;
5486
+ }
5487
+ }
5488
+ return false;
5489
+ };
5490
+ DiagramEngine.prototype.emitElementDeleting = function (event) {
5491
+ var cancelled = false;
5492
+ var payload = __assign(__assign({}, event), { cancelled: false, cancel: function () {
5493
+ cancelled = true;
5494
+ payload.cancelled = true;
5495
+ } });
5496
+ this.events.emit('elementDeleting', payload);
5497
+ return cancelled || payload.cancelled;
5498
+ };
5499
+ DiagramEngine.prototype.emitPortDeleting = function (event) {
5500
+ var cancelled = false;
5501
+ var payload = __assign(__assign({}, event), { cancelled: false, cancel: function () {
5502
+ cancelled = true;
5503
+ payload.cancelled = true;
5504
+ } });
5505
+ this.events.emit('portDeleting', payload);
5506
+ return cancelled || payload.cancelled;
5507
+ };
5508
+ DiagramEngine.prototype.emitLinkDeleting = function (event) {
5509
+ var cancelled = false;
5510
+ var payload = __assign(__assign({}, event), { cancelled: false, cancel: function () {
5511
+ cancelled = true;
5512
+ payload.cancelled = true;
5513
+ } });
5514
+ this.events.emit('linkDeleting', payload);
5515
+ return cancelled || payload.cancelled;
5516
+ };
5517
+ DiagramEngine.prototype.emitTextDeleting = function (event) {
5518
+ var cancelled = false;
5519
+ var payload = __assign(__assign({}, event), { cancelled: false, cancel: function () {
5520
+ cancelled = true;
5521
+ payload.cancelled = true;
5522
+ } });
5523
+ this.events.emit('textDeleting', payload);
5524
+ return cancelled || payload.cancelled;
5525
+ };
5357
5526
  DiagramEngine.prototype.emitEntityDeletionEvents = function (removed) {
5358
5527
  var _this = this;
5528
+ removed.elements.forEach(function (element) {
5529
+ _this.events.emit('elementDeleted', { elementId: element.id });
5530
+ });
5359
5531
  removed.ports.forEach(function (port) {
5360
5532
  _this.events.emit('portDeleted', { portId: port.id, elementId: port.elementId });
5361
5533
  });
@@ -6551,6 +6723,7 @@ var KonvaInteraction = /** @class */ (function () {
6551
6723
  this.shapeHoverControls = this.normalizeShapeHoverControls(config.shapeHoverControls);
6552
6724
  this.onShapeHoverControlInteracted = config.onShapeHoverControlInteracted;
6553
6725
  this.onShapeHoverControlActivated = config.onShapeHoverControlActivated;
6726
+ this.onCreateLinkTargetPort = config.onCreateLinkTargetPort;
6554
6727
  }
6555
6728
  KonvaInteraction.prototype.setShapeHoverControls = function (controls) {
6556
6729
  this.shapeHoverControls = this.normalizeShapeHoverControls(controls);
@@ -6567,6 +6740,9 @@ var KonvaInteraction = /** @class */ (function () {
6567
6740
  var sourceElementId = this.engine.getPortElementId(sourcePortId);
6568
6741
  if (!sourceElementId)
6569
6742
  return;
6743
+ var sourcePort = this.getPortById(sourcePortId);
6744
+ if (!sourcePort)
6745
+ return;
6570
6746
  var sourcePoint = (_a = this.engine.getPortLinkWorldPosition(sourcePortId)) !== null && _a !== void 0 ? _a : this.engine.getPortWorldPosition(sourcePortId);
6571
6747
  if (!sourcePoint)
6572
6748
  return;
@@ -6583,6 +6759,7 @@ var KonvaInteraction = /** @class */ (function () {
6583
6759
  this.programmaticLinkSession = {
6584
6760
  sourcePortId: sourcePortId,
6585
6761
  sourceElementId: sourceElementId,
6762
+ sourcePort: this.clonePortData(sourcePort),
6586
6763
  start: start,
6587
6764
  current: start,
6588
6765
  };
@@ -6592,6 +6769,7 @@ var KonvaInteraction = /** @class */ (function () {
6592
6769
  mode: 'link-drag',
6593
6770
  sourcePortId: sourcePortId,
6594
6771
  sourceElementId: sourceElementId,
6772
+ sourcePort: this.clonePortData(sourcePort),
6595
6773
  start: start,
6596
6774
  current: start,
6597
6775
  isMulti: false,
@@ -6607,7 +6785,7 @@ var KonvaInteraction = /** @class */ (function () {
6607
6785
  }
6608
6786
  };
6609
6787
  KonvaInteraction.prototype.updateLinkPreview = function (pointer) {
6610
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
6788
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
6611
6789
  if (this.programmaticLinkSession) {
6612
6790
  this.programmaticLinkSession.current = __assign({}, pointer);
6613
6791
  }
@@ -6619,28 +6797,29 @@ var KonvaInteraction = /** @class */ (function () {
6619
6797
  return;
6620
6798
  }
6621
6799
  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);
6800
+ 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
6801
  if (!sourcePortId)
6623
6802
  return;
6624
6803
  var source = this.resolveLinkPreviewSource(sourcePortId, pointer);
6625
6804
  if (source) {
6626
- (_e = this.renderer) === null || _e === void 0 ? void 0 : _e.renderTempLink([source, pointer]);
6805
+ (_h = this.renderer) === null || _h === void 0 ? void 0 : _h.renderTempLink([source, pointer]);
6627
6806
  }
6628
6807
  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);
6808
+ if ((hit === null || hit === void 0 ? void 0 : hit.type) === 'element' && sourceElementId) {
6809
+ var placeholder = this.createPlaceholderPort(hit.id, pointer, sourcePortId, sourceElementId);
6631
6810
  if (placeholder) {
6632
6811
  var hostElement = this.getElementById(hit.id);
6633
6812
  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 });
6813
+ var hostWorld = (_j = this.engine.getElementWorldPosition(hit.id)) !== null && _j !== void 0 ? _j : hostElement.position;
6814
+ (_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
6815
  }
6637
6816
  else {
6638
- (_k = (_j = this.renderer) === null || _j === void 0 ? void 0 : _j.renderPortPlaceholder) === null || _k === void 0 ? void 0 : _k.call(_j, placeholder);
6817
+ (_o = (_m = this.renderer) === null || _m === void 0 ? void 0 : _m.renderPortPlaceholder) === null || _o === void 0 ? void 0 : _o.call(_m, placeholder);
6639
6818
  }
6640
6819
  }
6641
6820
  return;
6642
6821
  }
6643
- (_m = (_l = this.renderer) === null || _l === void 0 ? void 0 : _l.clearPortPlaceholder) === null || _m === void 0 ? void 0 : _m.call(_l);
6822
+ (_q = (_p = this.renderer) === null || _p === void 0 ? void 0 : _p.clearPortPlaceholder) === null || _q === void 0 ? void 0 : _q.call(_p);
6644
6823
  };
6645
6824
  KonvaInteraction.prototype.completeLinkToPort = function (targetPortId) {
6646
6825
  var _a, _b;
@@ -6802,10 +6981,14 @@ var KonvaInteraction = /** @class */ (function () {
6802
6981
  }
6803
6982
  }
6804
6983
  else {
6984
+ var sourcePort = _this.getPortById(hit.id);
6985
+ if (!sourcePort)
6986
+ return;
6805
6987
  _this.dragState = {
6806
6988
  mode: 'link-drag',
6807
6989
  sourcePortId: hit.id,
6808
6990
  sourceElementId: elementId,
6991
+ sourcePort: _this.clonePortData(sourcePort),
6809
6992
  start: point,
6810
6993
  current: point,
6811
6994
  isMulti: isMulti,
@@ -6987,7 +7170,7 @@ var KonvaInteraction = /** @class */ (function () {
6987
7170
  }
6988
7171
  }
6989
7172
  else if ((hit === null || hit === void 0 ? void 0 : hit.type) === 'element') {
6990
- var placeholder = _this.createPlaceholderPort(hit.id, point, _this.dragState.sourcePortId);
7173
+ var placeholder = _this.createPlaceholderPort(hit.id, point, _this.dragState.sourcePortId, _this.dragState.sourceElementId);
6991
7174
  if (placeholder) {
6992
7175
  var hostElement = _this.getElementById(hit.id);
6993
7176
  if (hostElement) {
@@ -7229,15 +7412,29 @@ var KonvaInteraction = /** @class */ (function () {
7229
7412
  this.stage.on(upEvents, pointerUp);
7230
7413
  this.handlers.push([upEvents, pointerUp]);
7231
7414
  var doubleClick = function () {
7415
+ var args = [];
7416
+ for (var _i = 0; _i < arguments.length; _i++) {
7417
+ args[_i] = arguments[_i];
7418
+ }
7419
+ var event = args[0];
7420
+ var nativeEvent = event === null || event === void 0 ? void 0 : event.evt;
7232
7421
  var point = _this.getPointerPosition();
7233
7422
  if (!point)
7234
7423
  return;
7235
7424
  var hit = _this.resolveHit(point);
7236
- if (!hit || hit.type !== 'text')
7425
+ if (!hit)
7237
7426
  return;
7238
- if (!_this.isTextEditable(hit.id))
7427
+ if (hit.type === 'text') {
7428
+ if (!_this.isTextEditable(hit.id))
7429
+ return;
7430
+ _this.startTextEdit(hit.id);
7239
7431
  return;
7240
- _this.startTextEdit(hit.id);
7432
+ }
7433
+ if (hit.type !== 'element')
7434
+ return;
7435
+ var isMulti = Boolean(nativeEvent && (nativeEvent.ctrlKey || nativeEvent.metaKey || nativeEvent.shiftKey));
7436
+ var pointerInfo = _this.buildPointerInfo(point, nativeEvent);
7437
+ _this.engine.emitElementDoubleClick(hit.id, pointerInfo, isMulti);
7241
7438
  };
7242
7439
  this.stage.on('dblclick dbltap', doubleClick);
7243
7440
  this.handlers.push(['dblclick dbltap', doubleClick]);
@@ -8662,7 +8859,8 @@ var KonvaInteraction = /** @class */ (function () {
8662
8859
  return { createdLinkId: createdLinkId, targetPortId: targetPortId, targetElementId: targetElementId };
8663
8860
  };
8664
8861
  KonvaInteraction.prototype.tryCreateLinkToElement = function (sourcePortId, sourceElementId, targetElementId, worldPoint) {
8665
- var targetPort = this.createPortForLink(targetElementId, worldPoint, sourcePortId);
8862
+ var _a, _b;
8863
+ var targetPort = this.createPortForLink(targetElementId, worldPoint, sourcePortId, sourceElementId);
8666
8864
  if (!targetPort) {
8667
8865
  return { createdLinkId: null, targetPortId: null, targetElementId: null };
8668
8866
  }
@@ -8678,7 +8876,10 @@ var KonvaInteraction = /** @class */ (function () {
8678
8876
  return { createdLinkId: null, targetPortId: targetPort.id, targetElementId: targetElementId };
8679
8877
  }
8680
8878
  this.engine.addPortToElement(targetElementId, targetPort);
8681
- this.engine.movePortTo(targetPort.id, worldPoint.x, worldPoint.y);
8879
+ var targetElementWorld = (_a = this.engine.getElementWorldPosition(targetElementId)) !== null && _a !== void 0 ? _a : (_b = this.getElementById(targetElementId)) === null || _b === void 0 ? void 0 : _b.position;
8880
+ if (targetElementWorld) {
8881
+ this.engine.movePortTo(targetPort.id, targetElementWorld.x + targetPort.position.x, targetElementWorld.y + targetPort.position.y);
8882
+ }
8682
8883
  var createdLinkId = createId();
8683
8884
  this.engine.addLink({
8684
8885
  id: createdLinkId,
@@ -8688,61 +8889,139 @@ var KonvaInteraction = /** @class */ (function () {
8688
8889
  });
8689
8890
  return { createdLinkId: createdLinkId, targetPortId: targetPort.id, targetElementId: targetElementId };
8690
8891
  };
8691
- KonvaInteraction.prototype.createPortForLink = function (elementId, worldPoint, sourcePortId) {
8692
- var _a, _b, _c, _d;
8693
- var element = this.getElementById(elementId);
8694
- if (!element)
8892
+ KonvaInteraction.prototype.createPortForLink = function (elementId, worldPoint, sourcePortId, sourceElementId) {
8893
+ var resolved = this.resolveLinkTargetPortDraft(elementId, worldPoint, sourcePortId, sourceElementId, 'commit');
8894
+ if (!resolved)
8695
8895
  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
8896
  return {
8706
8897
  id: createId(),
8707
8898
  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,
8899
+ position: __assign({}, resolved.draft.position),
8900
+ shapeId: resolved.draft.shapeId,
8901
+ size: resolved.draft.size ? __assign({}, resolved.draft.size) : undefined,
8902
+ style: resolved.draft.style ? __assign({}, resolved.draft.style) : undefined,
8903
+ textIds: resolved.draft.textIds ? __spreadArray([], resolved.draft.textIds, true) : undefined,
8904
+ moveMode: resolved.draft.moveMode,
8905
+ anchorCenter: resolved.draft.anchorCenter,
8906
+ orientToHostBorder: resolved.draft.orientToHostBorder,
8907
+ placementPoint: resolved.draft.placementPoint ? __assign({}, resolved.draft.placementPoint) : undefined,
8908
+ linkAttachPoint: resolved.draft.linkAttachPoint ? __assign({}, resolved.draft.linkAttachPoint) : undefined,
8909
+ externalLinkAttachPoint: resolved.draft.externalLinkAttachPoint ? __assign({}, resolved.draft.externalLinkAttachPoint) : undefined,
8910
+ internalLinkAttachPoint: resolved.draft.internalLinkAttachPoint ? __assign({}, resolved.draft.internalLinkAttachPoint) : undefined,
8911
+ rotationPivot: resolved.draft.rotationPivot ? __assign({}, resolved.draft.rotationPivot) : undefined,
8912
+ currentAnchorId: resolved.draft.currentAnchorId,
8720
8913
  };
8721
8914
  };
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;
8915
+ KonvaInteraction.prototype.createPlaceholderPort = function (elementId, worldPoint, sourcePortId, sourceElementId) {
8916
+ var _a;
8917
+ var resolved = this.resolveLinkTargetPortDraft(elementId, worldPoint, sourcePortId, sourceElementId, 'preview');
8918
+ if (!resolved)
8919
+ return null;
8920
+ var hostWorld = (_a = this.engine.getElementWorldPosition(elementId)) !== null && _a !== void 0 ? _a : resolved.targetElement.position;
8729
8921
  return {
8730
8922
  id: "port-placeholder:".concat(sourcePortId),
8731
8923
  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,
8924
+ position: {
8925
+ x: hostWorld.x + resolved.draft.position.x,
8926
+ y: hostWorld.y + resolved.draft.position.y,
8927
+ },
8928
+ shapeId: resolved.draft.shapeId,
8929
+ size: resolved.draft.size ? __assign({}, resolved.draft.size) : undefined,
8930
+ style: resolved.draft.style ? __assign({}, resolved.draft.style) : undefined,
8931
+ textIds: resolved.draft.textIds ? __spreadArray([], resolved.draft.textIds, true) : undefined,
8932
+ moveMode: resolved.draft.moveMode,
8933
+ anchorCenter: resolved.draft.anchorCenter,
8934
+ orientToHostBorder: resolved.draft.orientToHostBorder,
8935
+ placementPoint: resolved.draft.placementPoint ? __assign({}, resolved.draft.placementPoint) : undefined,
8936
+ linkAttachPoint: resolved.draft.linkAttachPoint ? __assign({}, resolved.draft.linkAttachPoint) : undefined,
8937
+ externalLinkAttachPoint: resolved.draft.externalLinkAttachPoint ? __assign({}, resolved.draft.externalLinkAttachPoint) : undefined,
8938
+ internalLinkAttachPoint: resolved.draft.internalLinkAttachPoint ? __assign({}, resolved.draft.internalLinkAttachPoint) : undefined,
8939
+ rotationPivot: resolved.draft.rotationPivot ? __assign({}, resolved.draft.rotationPivot) : undefined,
8940
+ currentAnchorId: resolved.draft.currentAnchorId,
8941
+ };
8942
+ };
8943
+ KonvaInteraction.prototype.resolveLinkTargetPortDraft = function (elementId, worldPoint, sourcePortId, sourceElementId, phase) {
8944
+ var _a;
8945
+ var targetElement = this.getElementById(elementId);
8946
+ var sourcePort = this.resolveLinkSourcePort(sourcePortId);
8947
+ if (!targetElement || !sourcePort)
8948
+ return null;
8949
+ var defaultDraft = this.buildDefaultLinkTargetPortDraft(targetElement, worldPoint, sourcePort);
8950
+ var override = (_a = this.onCreateLinkTargetPort) === null || _a === void 0 ? void 0 : _a.call(this, {
8951
+ phase: phase,
8952
+ pointer: __assign({}, worldPoint),
8953
+ sourcePortId: sourcePortId,
8954
+ sourceElementId: sourceElementId,
8955
+ targetElementId: elementId,
8956
+ sourcePort: this.clonePortData(sourcePort),
8957
+ targetElement: this.cloneElementData(targetElement),
8958
+ defaultPort: this.cloneLinkTargetPortDraft(defaultDraft),
8959
+ });
8960
+ var mergedDraft = this.mergeLinkTargetPortDraft(defaultDraft, override);
8961
+ var normalizedDraft = this.engine.normalizePortDraftForElement(elementId, mergedDraft);
8962
+ if (!normalizedDraft)
8963
+ return null;
8964
+ return {
8965
+ draft: normalizedDraft,
8966
+ targetElement: this.cloneElementData(targetElement),
8967
+ };
8968
+ };
8969
+ KonvaInteraction.prototype.buildDefaultLinkTargetPortDraft = function (element, worldPoint, sourcePort) {
8970
+ var _a, _b, _c, _d;
8971
+ var elementPosition = (_a = this.engine.getElementWorldPosition(element.id)) !== null && _a !== void 0 ? _a : element.position;
8972
+ var destinationMoveMode = ((_b = element.portMovement) === null || _b === void 0 ? void 0 : _b.moveMode) && element.portMovement.moveMode !== 'anchors'
8973
+ ? element.portMovement.moveMode
8974
+ : undefined;
8975
+ return {
8976
+ position: {
8977
+ x: worldPoint.x - elementPosition.x,
8978
+ y: worldPoint.y - elementPosition.y,
8979
+ },
8980
+ shapeId: sourcePort.shapeId,
8981
+ size: sourcePort.size ? __assign({}, sourcePort.size) : undefined,
8982
+ style: sourcePort.style ? __assign({}, sourcePort.style) : undefined,
8983
+ moveMode: destinationMoveMode !== null && destinationMoveMode !== void 0 ? destinationMoveMode : sourcePort.moveMode,
8984
+ anchorCenter: (_c = sourcePort.anchorCenter) !== null && _c !== void 0 ? _c : true,
8985
+ orientToHostBorder: (_d = sourcePort.orientToHostBorder) !== null && _d !== void 0 ? _d : true,
8986
+ placementPoint: sourcePort.placementPoint ? __assign({}, sourcePort.placementPoint) : undefined,
8987
+ linkAttachPoint: sourcePort.linkAttachPoint ? __assign({}, sourcePort.linkAttachPoint) : undefined,
8988
+ externalLinkAttachPoint: sourcePort.externalLinkAttachPoint ? __assign({}, sourcePort.externalLinkAttachPoint) : undefined,
8989
+ internalLinkAttachPoint: sourcePort.internalLinkAttachPoint ? __assign({}, sourcePort.internalLinkAttachPoint) : undefined,
8990
+ rotationPivot: sourcePort.rotationPivot ? __assign({}, sourcePort.rotationPivot) : undefined,
8744
8991
  };
8745
8992
  };
8993
+ KonvaInteraction.prototype.mergeLinkTargetPortDraft = function (defaultDraft, override) {
8994
+ return this.cloneLinkTargetPortDraft(__assign(__assign({}, defaultDraft), (override !== null && override !== void 0 ? override : {})));
8995
+ };
8996
+ KonvaInteraction.prototype.resolveLinkSourcePort = function (sourcePortId) {
8997
+ var _a, _b;
8998
+ if (((_a = this.programmaticLinkSession) === null || _a === void 0 ? void 0 : _a.sourcePortId) === sourcePortId) {
8999
+ return this.clonePortData(this.programmaticLinkSession.sourcePort);
9000
+ }
9001
+ if (((_b = this.dragState) === null || _b === void 0 ? void 0 : _b.mode) === 'link-drag' && this.dragState.sourcePortId === sourcePortId) {
9002
+ return this.clonePortData(this.dragState.sourcePort);
9003
+ }
9004
+ var sourcePort = this.getPortById(sourcePortId);
9005
+ return sourcePort ? this.clonePortData(sourcePort) : null;
9006
+ };
9007
+ KonvaInteraction.prototype.clonePortData = function (port) {
9008
+ 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 });
9009
+ };
9010
+ KonvaInteraction.prototype.cloneLinkTargetPortDraft = function (draft) {
9011
+ 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 });
9012
+ };
9013
+ KonvaInteraction.prototype.cloneElementData = function (element) {
9014
+ 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
9015
+ ? __assign(__assign({}, element.portMovement), { anchorConstraint: element.portMovement.anchorConstraint
9016
+ ? __assign({}, element.portMovement.anchorConstraint) : undefined, positionLimits: element.portMovement.positionLimits
9017
+ ? {
9018
+ x: element.portMovement.positionLimits.x
9019
+ ? __assign({}, element.portMovement.positionLimits.x) : undefined,
9020
+ y: element.portMovement.positionLimits.y
9021
+ ? __assign({}, element.portMovement.positionLimits.y) : undefined,
9022
+ }
9023
+ : undefined }) : undefined });
9024
+ };
8746
9025
  KonvaInteraction.prototype.getElementById = function (id) {
8747
9026
  return this.engine.getState().elements.find(function (element) { return element.id === id; });
8748
9027
  };
@@ -9673,6 +9952,29 @@ var resolveViewportFitTransform = function (state, viewportSize, options) {
9673
9952
  };
9674
9953
  return { pan: pan, zoom: zoom };
9675
9954
  };
9955
+ var resolveFocusElementTransform = function (state, elementId, viewportSize, currentZoom, options) {
9956
+ var elementsById = new Map(state.elements.map(function (element) { return [element.id, element]; }));
9957
+ var element = elementsById.get(elementId);
9958
+ if (!element)
9959
+ return null;
9960
+ var position = resolveElementWorldPositionInState(elementId, elementsById);
9961
+ if (!position)
9962
+ return null;
9963
+ var safeWidth = Math.max(1, viewportSize.width);
9964
+ var safeHeight = Math.max(1, viewportSize.height);
9965
+ var requestedZoom = options === null || options === void 0 ? void 0 : options.zoom;
9966
+ var zoom = typeof requestedZoom === 'number' && Number.isFinite(requestedZoom)
9967
+ ? clamp(requestedZoom, DEFAULT_VIEWPORT_FIT_MIN_ZOOM, DEFAULT_VIEWPORT_FIT_MAX_ZOOM)
9968
+ : currentZoom;
9969
+ var safeZoom = zoom === 0 ? 1 : zoom;
9970
+ var centerX = position.x + element.size.width / 2;
9971
+ var centerY = position.y + element.size.height / 2;
9972
+ var pan = {
9973
+ x: safeWidth / 2 - centerX * safeZoom,
9974
+ y: safeHeight / 2 - centerY * safeZoom,
9975
+ };
9976
+ return { pan: pan, zoom: zoom };
9977
+ };
9676
9978
  var resolveFitToContentPadding = function (fitToContent) {
9677
9979
  if (typeof fitToContent === 'object' && typeof fitToContent.padding === 'number') {
9678
9980
  return Math.max(0, fitToContent.padding);
@@ -9859,6 +10161,7 @@ var createDiagramEditor = function (config) {
9859
10161
  shapeHoverControls: config.elementShapeHoverControls,
9860
10162
  onShapeHoverControlInteracted: config.onElementShapeHoverControlInteraction,
9861
10163
  onShapeHoverControlActivated: config.onElementShapeHoverControlActivated,
10164
+ onCreateLinkTargetPort: config.onCreateLinkTargetPort,
9862
10165
  });
9863
10166
  interaction.bind();
9864
10167
  if (config.initialState) {
@@ -9906,6 +10209,12 @@ var createDiagramEditor = function (config) {
9906
10209
  return;
9907
10210
  engine.setViewport(transform.pan, transform.zoom);
9908
10211
  },
10212
+ focusElement: function (elementId, options) {
10213
+ var transform = resolveFocusElementTransform(engine.getState(), elementId, { width: stageWidth, height: stageHeight }, engine.getViewport().zoom, options);
10214
+ if (!transform)
10215
+ return;
10216
+ engine.setViewport(transform.pan, transform.zoom);
10217
+ },
9909
10218
  exportImage: function (options) {
9910
10219
  engine.render();
9911
10220
  if (typeof stage.toDataURL !== 'function') {