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/esm/index.js CHANGED
@@ -1879,21 +1879,20 @@ var TextLayoutService = /** @class */ (function () {
1879
1879
  return ids;
1880
1880
  };
1881
1881
  TextLayoutService.prototype.shouldTrackOwnerBoundLayout = function (text) {
1882
- var _a;
1883
1882
  if (!text.layout)
1884
1883
  return false;
1885
- var boundsMode = (_a = text.layout.boundsMode) !== null && _a !== void 0 ? _a : (text.ownerId ? 'owner-width' : undefined);
1884
+ var boundsMode = this.resolveDefaultBoundsMode(text);
1886
1885
  return boundsMode === 'owner-width' || boundsMode === 'owner-box';
1887
1886
  };
1888
1887
  TextLayoutService.prototype.resolveTextLayoutBounds = function (text, padding) {
1889
- var _a, _b, _c;
1888
+ var _a, _b;
1890
1889
  var layout = text.layout;
1891
1890
  if (!layout)
1892
1891
  return {};
1893
- var boundsMode = (_a = layout.boundsMode) !== null && _a !== void 0 ? _a : (text.ownerId ? 'owner-width' : undefined);
1892
+ var boundsMode = this.resolveDefaultBoundsMode(text);
1894
1893
  if (boundsMode === 'fixed') {
1895
- var width = (_b = layout.fixedSize) === null || _b === void 0 ? void 0 : _b.width;
1896
- var height = (_c = layout.fixedSize) === null || _c === void 0 ? void 0 : _c.height;
1894
+ var width = (_a = layout.fixedSize) === null || _a === void 0 ? void 0 : _a.width;
1895
+ var height = (_b = layout.fixedSize) === null || _b === void 0 ? void 0 : _b.height;
1897
1896
  return {
1898
1897
  width: typeof width === 'number' ? Math.max(0, width - padding * 2) : undefined,
1899
1898
  height: typeof height === 'number' ? Math.max(0, height - padding * 2) : undefined,
@@ -1913,6 +1912,14 @@ var TextLayoutService = /** @class */ (function () {
1913
1912
  }
1914
1913
  return {};
1915
1914
  };
1915
+ TextLayoutService.prototype.resolveDefaultBoundsMode = function (text) {
1916
+ var _a;
1917
+ if ((_a = text.layout) === null || _a === void 0 ? void 0 : _a.boundsMode)
1918
+ return text.layout.boundsMode;
1919
+ if (!text.ownerId)
1920
+ return undefined;
1921
+ return this.model.getElement(text.ownerId) ? 'owner-width' : undefined;
1922
+ };
1916
1923
  TextLayoutService.prototype.wrapText = function (content, maxWidth, mode, text) {
1917
1924
  var _this = this;
1918
1925
  if (maxWidth === undefined || !Number.isFinite(maxWidth)) {
@@ -4128,8 +4135,15 @@ var DiagramEngine = /** @class */ (function () {
4128
4135
  var _this = this;
4129
4136
  var _a;
4130
4137
  var existing = this.model.getElement(id);
4131
- var parentId = (_a = existing === null || existing === void 0 ? void 0 : existing.parentId) !== null && _a !== void 0 ? _a : null;
4138
+ if (!existing)
4139
+ return;
4140
+ var parentId = (_a = existing.parentId) !== null && _a !== void 0 ? _a : null;
4132
4141
  var before = this.model.toState();
4142
+ var root = { entity: 'element', id: id };
4143
+ var plannedRemoval = this.planRemoval(before, root);
4144
+ if (!plannedRemoval || this.emitDeletionLifecycleEvents(plannedRemoval.removed, root, 'direct')) {
4145
+ return;
4146
+ }
4133
4147
  this.commandQueue.run(createRemoveElementCommand(id), this.model);
4134
4148
  var removal = this.computeRemovalDiff(before);
4135
4149
  var allPatches = this.mutationPipeline.run({
@@ -4137,9 +4151,6 @@ var DiagramEngine = /** @class */ (function () {
4137
4151
  layoutSteps: [function () { return _this.applyLayoutCascade(parentId); }],
4138
4152
  });
4139
4153
  this.emitChange(allPatches);
4140
- if (existing) {
4141
- this.events.emit('elementDeleted', { elementId: id });
4142
- }
4143
4154
  this.emitEntityDeletionEvents(removal.removed);
4144
4155
  };
4145
4156
  DiagramEngine.prototype.addPortToElement = function (elementId, port) {
@@ -4154,6 +4165,24 @@ var DiagramEngine = /** @class */ (function () {
4154
4165
  var patches = this.commandQueue.run(createAddPortCommand(nextPort), this.model);
4155
4166
  this.emitChange(patches);
4156
4167
  };
4168
+ DiagramEngine.prototype.normalizePortDraftForElement = function (elementId, draft) {
4169
+ var _a;
4170
+ var element = this.model.getElement(elementId);
4171
+ if (!element)
4172
+ return null;
4173
+ 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 });
4174
+ var constrained = this.resolveConstrainedPortRelativePosition({
4175
+ position: nextDraft.position,
4176
+ size: nextDraft.size,
4177
+ style: nextDraft.style,
4178
+ moveMode: nextDraft.moveMode,
4179
+ anchorCenter: nextDraft.anchorCenter,
4180
+ currentAnchorId: nextDraft.currentAnchorId,
4181
+ }, element, nextDraft.position);
4182
+ nextDraft.position = constrained.position;
4183
+ nextDraft.currentAnchorId = (_a = constrained.currentAnchorId) !== null && _a !== void 0 ? _a : undefined;
4184
+ return nextDraft;
4185
+ };
4157
4186
  DiagramEngine.prototype.movePortTo = function (id, x, y) {
4158
4187
  var snapped = this.snapper.snap({ x: x, y: y });
4159
4188
  var port = this.model.getPort(id);
@@ -4202,7 +4231,14 @@ var DiagramEngine = /** @class */ (function () {
4202
4231
  }
4203
4232
  };
4204
4233
  DiagramEngine.prototype.removePort = function (id) {
4234
+ if (!this.model.getPort(id))
4235
+ return;
4205
4236
  var before = this.model.toState();
4237
+ var root = { entity: 'port', id: id };
4238
+ var plannedRemoval = this.planRemoval(before, root);
4239
+ if (!plannedRemoval || this.emitDeletionLifecycleEvents(plannedRemoval.removed, root, 'direct')) {
4240
+ return;
4241
+ }
4206
4242
  this.commandQueue.run(createRemovePortCommand(id), this.model);
4207
4243
  var removal = this.computeRemovalDiff(before);
4208
4244
  this.emitChange(removal.patches);
@@ -4296,7 +4332,14 @@ var DiagramEngine = /** @class */ (function () {
4296
4332
  }
4297
4333
  };
4298
4334
  DiagramEngine.prototype.removeLink = function (id) {
4335
+ if (!this.model.getLink(id))
4336
+ return;
4299
4337
  var before = this.model.toState();
4338
+ var root = { entity: 'link', id: id };
4339
+ var plannedRemoval = this.planRemoval(before, root);
4340
+ if (!plannedRemoval || this.emitDeletionLifecycleEvents(plannedRemoval.removed, root, 'direct')) {
4341
+ return;
4342
+ }
4300
4343
  this.commandQueue.run(createRemoveLinkCommand(id), this.model);
4301
4344
  var removal = this.computeRemovalDiff(before);
4302
4345
  this.emitChange(removal.patches);
@@ -4381,7 +4424,14 @@ var DiagramEngine = /** @class */ (function () {
4381
4424
  this.emitChange(patches);
4382
4425
  };
4383
4426
  DiagramEngine.prototype.removeText = function (id) {
4427
+ if (!this.model.getText(id))
4428
+ return;
4384
4429
  var before = this.model.toState();
4430
+ var root = { entity: 'text', id: id };
4431
+ var plannedRemoval = this.planRemoval(before, root);
4432
+ if (!plannedRemoval || this.emitDeletionLifecycleEvents(plannedRemoval.removed, root, 'direct')) {
4433
+ return;
4434
+ }
4385
4435
  this.commandQueue.run(createRemoveTextCommand(id), this.model);
4386
4436
  var removal = this.computeRemovalDiff(before);
4387
4437
  this.emitChange(removal.patches);
@@ -4576,40 +4626,22 @@ var DiagramEngine = /** @class */ (function () {
4576
4626
  if (selected.length === 0)
4577
4627
  return;
4578
4628
  var before = this.model.toState();
4579
- var elementIds = [];
4580
- selected.forEach(function (id) {
4581
- if (_this.model.getElement(id))
4582
- elementIds.push(id);
4583
- else if (_this.model.getPort(id))
4584
- ;
4585
- else if (_this.model.getLink(id))
4586
- ;
4587
- else if (_this.model.getText(id))
4588
- ;
4589
- });
4590
4629
  selected.forEach(function (id) {
4591
- if (_this.model.getElement(id)) {
4592
- _this.commandQueue.run(createRemoveElementCommand(id), _this.model);
4630
+ var root = _this.resolveDeletionRoot(id);
4631
+ if (!root)
4593
4632
  return;
4594
- }
4595
- if (_this.model.getPort(id)) {
4596
- _this.commandQueue.run(createRemovePortCommand(id), _this.model);
4633
+ var currentState = _this.model.toState();
4634
+ var plannedRemoval = _this.planRemoval(currentState, root);
4635
+ if (!plannedRemoval || _this.emitDeletionLifecycleEvents(plannedRemoval.removed, root, 'selection')) {
4597
4636
  return;
4598
4637
  }
4599
- if (_this.model.getLink(id)) {
4600
- _this.commandQueue.run(createRemoveLinkCommand(id), _this.model);
4601
- return;
4602
- }
4603
- if (_this.model.getText(id)) {
4604
- _this.commandQueue.run(createRemoveTextCommand(id), _this.model);
4605
- }
4638
+ _this.applyRemovalCommand(root);
4606
4639
  });
4607
4640
  var removal = this.computeRemovalDiff(before);
4641
+ if (removal.patches.length === 0)
4642
+ return;
4608
4643
  this.emitChange(removal.patches);
4609
4644
  this.emitEntityDeletionEvents(removal.removed);
4610
- elementIds.forEach(function (elementId) { return _this.events.emit('elementDeleted', { elementId: elementId }); });
4611
- this.selection.clear();
4612
- this.emitSelection();
4613
4645
  };
4614
4646
  DiagramEngine.prototype.setViewport = function (pan, zoom) {
4615
4647
  var hasPanChange = this.viewport.pan.x !== pan.x || this.viewport.pan.y !== pan.y;
@@ -4662,6 +4694,9 @@ var DiagramEngine = /** @class */ (function () {
4662
4694
  DiagramEngine.prototype.emitElementClick = function (elementId, pointer, isMulti) {
4663
4695
  this.events.emit('elementClick', { elementId: elementId, pointer: pointer, isMulti: isMulti });
4664
4696
  };
4697
+ DiagramEngine.prototype.emitElementDoubleClick = function (elementId, pointer, isMulti) {
4698
+ this.events.emit('elementDoubleClick', { elementId: elementId, pointer: pointer, isMulti: isMulti });
4699
+ };
4665
4700
  DiagramEngine.prototype.emitElementLinkStarted = function (event) {
4666
4701
  this.events.emit('elementLinkStarted', event);
4667
4702
  };
@@ -5305,8 +5340,8 @@ var DiagramEngine = /** @class */ (function () {
5305
5340
  });
5306
5341
  return { patches: normalizedPatches, movedPortIds: Array.from(movedPortIds) };
5307
5342
  };
5308
- DiagramEngine.prototype.computeRemovalDiff = function (before) {
5309
- var after = this.model.toState();
5343
+ DiagramEngine.prototype.computeRemovalDiff = function (before, after) {
5344
+ if (after === void 0) { after = this.model.toState(); }
5310
5345
  var removedPatches = [];
5311
5346
  var beforeElements = new Set(before.elements.map(function (element) { return element.id; }));
5312
5347
  var beforePorts = new Set(before.ports.map(function (port) { return port.id; }));
@@ -5316,9 +5351,13 @@ var DiagramEngine = /** @class */ (function () {
5316
5351
  var afterPorts = new Set(after.ports.map(function (port) { return port.id; }));
5317
5352
  var afterLinks = new Set(after.links.map(function (link) { return link.id; }));
5318
5353
  var afterTexts = new Set(after.texts.map(function (text) { return text.id; }));
5354
+ var removedElements = [];
5319
5355
  beforeElements.forEach(function (id) {
5320
5356
  if (!afterElements.has(id))
5321
5357
  removedPatches.push(patchRemove('element', id));
5358
+ var removedElement = before.elements.find(function (element) { return element.id === id; });
5359
+ if (!afterElements.has(id) && removedElement)
5360
+ removedElements.push(removedElement);
5322
5361
  });
5323
5362
  var removedPorts = [];
5324
5363
  beforePorts.forEach(function (id) {
@@ -5349,11 +5388,144 @@ var DiagramEngine = /** @class */ (function () {
5349
5388
  });
5350
5389
  return {
5351
5390
  patches: removedPatches,
5352
- removed: { ports: removedPorts, links: removedLinks, texts: removedTexts },
5391
+ removed: { elements: removedElements, ports: removedPorts, links: removedLinks, texts: removedTexts },
5353
5392
  };
5354
5393
  };
5394
+ DiagramEngine.prototype.resolveDeletionRoot = function (id) {
5395
+ if (this.model.getElement(id))
5396
+ return { entity: 'element', id: id };
5397
+ if (this.model.getPort(id))
5398
+ return { entity: 'port', id: id };
5399
+ if (this.model.getLink(id))
5400
+ return { entity: 'link', id: id };
5401
+ if (this.model.getText(id))
5402
+ return { entity: 'text', id: id };
5403
+ return null;
5404
+ };
5405
+ DiagramEngine.prototype.applyRemovalCommand = function (root) {
5406
+ if (root.entity === 'element') {
5407
+ this.commandQueue.run(createRemoveElementCommand(root.id), this.model);
5408
+ return;
5409
+ }
5410
+ if (root.entity === 'port') {
5411
+ this.commandQueue.run(createRemovePortCommand(root.id), this.model);
5412
+ return;
5413
+ }
5414
+ if (root.entity === 'link') {
5415
+ this.commandQueue.run(createRemoveLinkCommand(root.id), this.model);
5416
+ return;
5417
+ }
5418
+ this.commandQueue.run(createRemoveTextCommand(root.id), this.model);
5419
+ };
5420
+ DiagramEngine.prototype.planRemoval = function (before, root) {
5421
+ var tempModel = new DiagramModel();
5422
+ tempModel.load(before);
5423
+ if (root.entity === 'element') {
5424
+ tempModel.removeElement(root.id);
5425
+ }
5426
+ else if (root.entity === 'port') {
5427
+ tempModel.removePort(root.id);
5428
+ }
5429
+ else if (root.entity === 'link') {
5430
+ tempModel.removeLink(root.id);
5431
+ }
5432
+ else {
5433
+ tempModel.removeText(root.id);
5434
+ }
5435
+ return this.computeRemovalDiff(before, tempModel.toState());
5436
+ };
5437
+ DiagramEngine.prototype.emitDeletionLifecycleEvents = function (removed, root, rootTrigger) {
5438
+ for (var _i = 0, _a = removed.elements; _i < _a.length; _i++) {
5439
+ var element = _a[_i];
5440
+ var trigger = root.entity === 'element' && element.id === root.id ? rootTrigger : 'cascade';
5441
+ if (this.emitElementDeleting({
5442
+ elementId: element.id,
5443
+ trigger: trigger,
5444
+ root: root,
5445
+ })) {
5446
+ return true;
5447
+ }
5448
+ }
5449
+ for (var _b = 0, _c = removed.ports; _b < _c.length; _b++) {
5450
+ var port = _c[_b];
5451
+ var trigger = root.entity === 'port' && port.id === root.id ? rootTrigger : 'cascade';
5452
+ if (this.emitPortDeleting({
5453
+ portId: port.id,
5454
+ elementId: port.elementId,
5455
+ trigger: trigger,
5456
+ root: root,
5457
+ })) {
5458
+ return true;
5459
+ }
5460
+ }
5461
+ for (var _d = 0, _e = removed.links; _d < _e.length; _d++) {
5462
+ var link = _e[_d];
5463
+ var trigger = root.entity === 'link' && link.id === root.id ? rootTrigger : 'cascade';
5464
+ if (this.emitLinkDeleting({
5465
+ linkId: link.id,
5466
+ sourcePortId: link.sourcePortId,
5467
+ targetPortId: link.targetPortId,
5468
+ trigger: trigger,
5469
+ root: root,
5470
+ })) {
5471
+ return true;
5472
+ }
5473
+ }
5474
+ for (var _f = 0, _g = removed.texts; _f < _g.length; _f++) {
5475
+ var text = _g[_f];
5476
+ var trigger = root.entity === 'text' && text.id === root.id ? rootTrigger : 'cascade';
5477
+ if (this.emitTextDeleting({
5478
+ textId: text.id,
5479
+ ownerId: text.ownerId,
5480
+ trigger: trigger,
5481
+ root: root,
5482
+ })) {
5483
+ return true;
5484
+ }
5485
+ }
5486
+ return false;
5487
+ };
5488
+ DiagramEngine.prototype.emitElementDeleting = function (event) {
5489
+ var cancelled = false;
5490
+ var payload = __assign(__assign({}, event), { cancelled: false, cancel: function () {
5491
+ cancelled = true;
5492
+ payload.cancelled = true;
5493
+ } });
5494
+ this.events.emit('elementDeleting', payload);
5495
+ return cancelled || payload.cancelled;
5496
+ };
5497
+ DiagramEngine.prototype.emitPortDeleting = function (event) {
5498
+ var cancelled = false;
5499
+ var payload = __assign(__assign({}, event), { cancelled: false, cancel: function () {
5500
+ cancelled = true;
5501
+ payload.cancelled = true;
5502
+ } });
5503
+ this.events.emit('portDeleting', payload);
5504
+ return cancelled || payload.cancelled;
5505
+ };
5506
+ DiagramEngine.prototype.emitLinkDeleting = function (event) {
5507
+ var cancelled = false;
5508
+ var payload = __assign(__assign({}, event), { cancelled: false, cancel: function () {
5509
+ cancelled = true;
5510
+ payload.cancelled = true;
5511
+ } });
5512
+ this.events.emit('linkDeleting', payload);
5513
+ return cancelled || payload.cancelled;
5514
+ };
5515
+ DiagramEngine.prototype.emitTextDeleting = function (event) {
5516
+ var cancelled = false;
5517
+ var payload = __assign(__assign({}, event), { cancelled: false, cancel: function () {
5518
+ cancelled = true;
5519
+ payload.cancelled = true;
5520
+ } });
5521
+ this.events.emit('textDeleting', payload);
5522
+ return cancelled || payload.cancelled;
5523
+ };
5355
5524
  DiagramEngine.prototype.emitEntityDeletionEvents = function (removed) {
5356
5525
  var _this = this;
5526
+ removed.elements.forEach(function (element) {
5527
+ _this.events.emit('elementDeleted', { elementId: element.id });
5528
+ });
5357
5529
  removed.ports.forEach(function (port) {
5358
5530
  _this.events.emit('portDeleted', { portId: port.id, elementId: port.elementId });
5359
5531
  });
@@ -6549,6 +6721,7 @@ var KonvaInteraction = /** @class */ (function () {
6549
6721
  this.shapeHoverControls = this.normalizeShapeHoverControls(config.shapeHoverControls);
6550
6722
  this.onShapeHoverControlInteracted = config.onShapeHoverControlInteracted;
6551
6723
  this.onShapeHoverControlActivated = config.onShapeHoverControlActivated;
6724
+ this.onCreateLinkTargetPort = config.onCreateLinkTargetPort;
6552
6725
  }
6553
6726
  KonvaInteraction.prototype.setShapeHoverControls = function (controls) {
6554
6727
  this.shapeHoverControls = this.normalizeShapeHoverControls(controls);
@@ -6565,6 +6738,9 @@ var KonvaInteraction = /** @class */ (function () {
6565
6738
  var sourceElementId = this.engine.getPortElementId(sourcePortId);
6566
6739
  if (!sourceElementId)
6567
6740
  return;
6741
+ var sourcePort = this.getPortById(sourcePortId);
6742
+ if (!sourcePort)
6743
+ return;
6568
6744
  var sourcePoint = (_a = this.engine.getPortLinkWorldPosition(sourcePortId)) !== null && _a !== void 0 ? _a : this.engine.getPortWorldPosition(sourcePortId);
6569
6745
  if (!sourcePoint)
6570
6746
  return;
@@ -6581,6 +6757,7 @@ var KonvaInteraction = /** @class */ (function () {
6581
6757
  this.programmaticLinkSession = {
6582
6758
  sourcePortId: sourcePortId,
6583
6759
  sourceElementId: sourceElementId,
6760
+ sourcePort: this.clonePortData(sourcePort),
6584
6761
  start: start,
6585
6762
  current: start,
6586
6763
  };
@@ -6590,6 +6767,7 @@ var KonvaInteraction = /** @class */ (function () {
6590
6767
  mode: 'link-drag',
6591
6768
  sourcePortId: sourcePortId,
6592
6769
  sourceElementId: sourceElementId,
6770
+ sourcePort: this.clonePortData(sourcePort),
6593
6771
  start: start,
6594
6772
  current: start,
6595
6773
  isMulti: false,
@@ -6605,7 +6783,7 @@ var KonvaInteraction = /** @class */ (function () {
6605
6783
  }
6606
6784
  };
6607
6785
  KonvaInteraction.prototype.updateLinkPreview = function (pointer) {
6608
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
6786
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
6609
6787
  if (this.programmaticLinkSession) {
6610
6788
  this.programmaticLinkSession.current = __assign({}, pointer);
6611
6789
  }
@@ -6617,28 +6795,29 @@ var KonvaInteraction = /** @class */ (function () {
6617
6795
  return;
6618
6796
  }
6619
6797
  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);
6798
+ 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);
6620
6799
  if (!sourcePortId)
6621
6800
  return;
6622
6801
  var source = this.resolveLinkPreviewSource(sourcePortId, pointer);
6623
6802
  if (source) {
6624
- (_e = this.renderer) === null || _e === void 0 ? void 0 : _e.renderTempLink([source, pointer]);
6803
+ (_h = this.renderer) === null || _h === void 0 ? void 0 : _h.renderTempLink([source, pointer]);
6625
6804
  }
6626
6805
  var hit = this.resolveHit(pointer);
6627
- if ((hit === null || hit === void 0 ? void 0 : hit.type) === 'element') {
6628
- var placeholder = this.createPlaceholderPort(hit.id, pointer, sourcePortId);
6806
+ if ((hit === null || hit === void 0 ? void 0 : hit.type) === 'element' && sourceElementId) {
6807
+ var placeholder = this.createPlaceholderPort(hit.id, pointer, sourcePortId, sourceElementId);
6629
6808
  if (placeholder) {
6630
6809
  var hostElement = this.getElementById(hit.id);
6631
6810
  if (hostElement) {
6632
- var hostWorld = (_f = this.engine.getElementWorldPosition(hit.id)) !== null && _f !== void 0 ? _f : hostElement.position;
6633
- (_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 });
6811
+ var hostWorld = (_j = this.engine.getElementWorldPosition(hit.id)) !== null && _j !== void 0 ? _j : hostElement.position;
6812
+ (_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 });
6634
6813
  }
6635
6814
  else {
6636
- (_k = (_j = this.renderer) === null || _j === void 0 ? void 0 : _j.renderPortPlaceholder) === null || _k === void 0 ? void 0 : _k.call(_j, placeholder);
6815
+ (_o = (_m = this.renderer) === null || _m === void 0 ? void 0 : _m.renderPortPlaceholder) === null || _o === void 0 ? void 0 : _o.call(_m, placeholder);
6637
6816
  }
6638
6817
  }
6639
6818
  return;
6640
6819
  }
6641
- (_m = (_l = this.renderer) === null || _l === void 0 ? void 0 : _l.clearPortPlaceholder) === null || _m === void 0 ? void 0 : _m.call(_l);
6820
+ (_q = (_p = this.renderer) === null || _p === void 0 ? void 0 : _p.clearPortPlaceholder) === null || _q === void 0 ? void 0 : _q.call(_p);
6642
6821
  };
6643
6822
  KonvaInteraction.prototype.completeLinkToPort = function (targetPortId) {
6644
6823
  var _a, _b;
@@ -6800,10 +6979,14 @@ var KonvaInteraction = /** @class */ (function () {
6800
6979
  }
6801
6980
  }
6802
6981
  else {
6982
+ var sourcePort = _this.getPortById(hit.id);
6983
+ if (!sourcePort)
6984
+ return;
6803
6985
  _this.dragState = {
6804
6986
  mode: 'link-drag',
6805
6987
  sourcePortId: hit.id,
6806
6988
  sourceElementId: elementId,
6989
+ sourcePort: _this.clonePortData(sourcePort),
6807
6990
  start: point,
6808
6991
  current: point,
6809
6992
  isMulti: isMulti,
@@ -6985,7 +7168,7 @@ var KonvaInteraction = /** @class */ (function () {
6985
7168
  }
6986
7169
  }
6987
7170
  else if ((hit === null || hit === void 0 ? void 0 : hit.type) === 'element') {
6988
- var placeholder = _this.createPlaceholderPort(hit.id, point, _this.dragState.sourcePortId);
7171
+ var placeholder = _this.createPlaceholderPort(hit.id, point, _this.dragState.sourcePortId, _this.dragState.sourceElementId);
6989
7172
  if (placeholder) {
6990
7173
  var hostElement = _this.getElementById(hit.id);
6991
7174
  if (hostElement) {
@@ -7227,15 +7410,29 @@ var KonvaInteraction = /** @class */ (function () {
7227
7410
  this.stage.on(upEvents, pointerUp);
7228
7411
  this.handlers.push([upEvents, pointerUp]);
7229
7412
  var doubleClick = function () {
7413
+ var args = [];
7414
+ for (var _i = 0; _i < arguments.length; _i++) {
7415
+ args[_i] = arguments[_i];
7416
+ }
7417
+ var event = args[0];
7418
+ var nativeEvent = event === null || event === void 0 ? void 0 : event.evt;
7230
7419
  var point = _this.getPointerPosition();
7231
7420
  if (!point)
7232
7421
  return;
7233
7422
  var hit = _this.resolveHit(point);
7234
- if (!hit || hit.type !== 'text')
7423
+ if (!hit)
7235
7424
  return;
7236
- if (!_this.isTextEditable(hit.id))
7425
+ if (hit.type === 'text') {
7426
+ if (!_this.isTextEditable(hit.id))
7427
+ return;
7428
+ _this.startTextEdit(hit.id);
7237
7429
  return;
7238
- _this.startTextEdit(hit.id);
7430
+ }
7431
+ if (hit.type !== 'element')
7432
+ return;
7433
+ var isMulti = Boolean(nativeEvent && (nativeEvent.ctrlKey || nativeEvent.metaKey || nativeEvent.shiftKey));
7434
+ var pointerInfo = _this.buildPointerInfo(point, nativeEvent);
7435
+ _this.engine.emitElementDoubleClick(hit.id, pointerInfo, isMulti);
7239
7436
  };
7240
7437
  this.stage.on('dblclick dbltap', doubleClick);
7241
7438
  this.handlers.push(['dblclick dbltap', doubleClick]);
@@ -8660,7 +8857,8 @@ var KonvaInteraction = /** @class */ (function () {
8660
8857
  return { createdLinkId: createdLinkId, targetPortId: targetPortId, targetElementId: targetElementId };
8661
8858
  };
8662
8859
  KonvaInteraction.prototype.tryCreateLinkToElement = function (sourcePortId, sourceElementId, targetElementId, worldPoint) {
8663
- var targetPort = this.createPortForLink(targetElementId, worldPoint, sourcePortId);
8860
+ var _a, _b;
8861
+ var targetPort = this.createPortForLink(targetElementId, worldPoint, sourcePortId, sourceElementId);
8664
8862
  if (!targetPort) {
8665
8863
  return { createdLinkId: null, targetPortId: null, targetElementId: null };
8666
8864
  }
@@ -8676,7 +8874,10 @@ var KonvaInteraction = /** @class */ (function () {
8676
8874
  return { createdLinkId: null, targetPortId: targetPort.id, targetElementId: targetElementId };
8677
8875
  }
8678
8876
  this.engine.addPortToElement(targetElementId, targetPort);
8679
- this.engine.movePortTo(targetPort.id, worldPoint.x, worldPoint.y);
8877
+ var targetElementWorld = (_a = this.engine.getElementWorldPosition(targetElementId)) !== null && _a !== void 0 ? _a : (_b = this.getElementById(targetElementId)) === null || _b === void 0 ? void 0 : _b.position;
8878
+ if (targetElementWorld) {
8879
+ this.engine.movePortTo(targetPort.id, targetElementWorld.x + targetPort.position.x, targetElementWorld.y + targetPort.position.y);
8880
+ }
8680
8881
  var createdLinkId = createId();
8681
8882
  this.engine.addLink({
8682
8883
  id: createdLinkId,
@@ -8686,61 +8887,139 @@ var KonvaInteraction = /** @class */ (function () {
8686
8887
  });
8687
8888
  return { createdLinkId: createdLinkId, targetPortId: targetPort.id, targetElementId: targetElementId };
8688
8889
  };
8689
- KonvaInteraction.prototype.createPortForLink = function (elementId, worldPoint, sourcePortId) {
8690
- var _a, _b, _c, _d;
8691
- var element = this.getElementById(elementId);
8692
- if (!element)
8890
+ KonvaInteraction.prototype.createPortForLink = function (elementId, worldPoint, sourcePortId, sourceElementId) {
8891
+ var resolved = this.resolveLinkTargetPortDraft(elementId, worldPoint, sourcePortId, sourceElementId, 'commit');
8892
+ if (!resolved)
8693
8893
  return null;
8694
- var elementPosition = (_a = this.engine.getElementWorldPosition(elementId)) !== null && _a !== void 0 ? _a : element.position;
8695
- var relative = {
8696
- x: worldPoint.x - elementPosition.x,
8697
- y: worldPoint.y - elementPosition.y,
8698
- };
8699
- var sourcePort = this.getPortById(sourcePortId);
8700
- var destinationMoveMode = ((_b = element.portMovement) === null || _b === void 0 ? void 0 : _b.moveMode) && element.portMovement.moveMode !== 'anchors'
8701
- ? element.portMovement.moveMode
8702
- : undefined;
8703
8894
  return {
8704
8895
  id: createId(),
8705
8896
  elementId: elementId,
8706
- position: relative,
8707
- shapeId: sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.shapeId,
8708
- size: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.size) ? __assign({}, sourcePort.size) : undefined,
8709
- style: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.style) ? __assign({}, sourcePort.style) : undefined,
8710
- moveMode: destinationMoveMode !== null && destinationMoveMode !== void 0 ? destinationMoveMode : sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.moveMode,
8711
- anchorCenter: (_c = sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.anchorCenter) !== null && _c !== void 0 ? _c : true,
8712
- orientToHostBorder: (_d = sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.orientToHostBorder) !== null && _d !== void 0 ? _d : true,
8713
- placementPoint: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.placementPoint) ? __assign({}, sourcePort.placementPoint) : undefined,
8714
- linkAttachPoint: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.linkAttachPoint) ? __assign({}, sourcePort.linkAttachPoint) : undefined,
8715
- externalLinkAttachPoint: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.externalLinkAttachPoint) ? __assign({}, sourcePort.externalLinkAttachPoint) : undefined,
8716
- internalLinkAttachPoint: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.internalLinkAttachPoint) ? __assign({}, sourcePort.internalLinkAttachPoint) : undefined,
8717
- rotationPivot: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.rotationPivot) ? __assign({}, sourcePort.rotationPivot) : undefined,
8897
+ position: __assign({}, resolved.draft.position),
8898
+ shapeId: resolved.draft.shapeId,
8899
+ size: resolved.draft.size ? __assign({}, resolved.draft.size) : undefined,
8900
+ style: resolved.draft.style ? __assign({}, resolved.draft.style) : undefined,
8901
+ textIds: resolved.draft.textIds ? __spreadArray([], resolved.draft.textIds, true) : undefined,
8902
+ moveMode: resolved.draft.moveMode,
8903
+ anchorCenter: resolved.draft.anchorCenter,
8904
+ orientToHostBorder: resolved.draft.orientToHostBorder,
8905
+ placementPoint: resolved.draft.placementPoint ? __assign({}, resolved.draft.placementPoint) : undefined,
8906
+ linkAttachPoint: resolved.draft.linkAttachPoint ? __assign({}, resolved.draft.linkAttachPoint) : undefined,
8907
+ externalLinkAttachPoint: resolved.draft.externalLinkAttachPoint ? __assign({}, resolved.draft.externalLinkAttachPoint) : undefined,
8908
+ internalLinkAttachPoint: resolved.draft.internalLinkAttachPoint ? __assign({}, resolved.draft.internalLinkAttachPoint) : undefined,
8909
+ rotationPivot: resolved.draft.rotationPivot ? __assign({}, resolved.draft.rotationPivot) : undefined,
8910
+ currentAnchorId: resolved.draft.currentAnchorId,
8718
8911
  };
8719
8912
  };
8720
- KonvaInteraction.prototype.createPlaceholderPort = function (elementId, worldPoint, sourcePortId) {
8721
- var _a, _b, _c;
8722
- var element = this.getElementById(elementId);
8723
- var sourcePort = this.getPortById(sourcePortId);
8724
- var destinationMoveMode = ((_a = element === null || element === void 0 ? void 0 : element.portMovement) === null || _a === void 0 ? void 0 : _a.moveMode) && element.portMovement.moveMode !== 'anchors'
8725
- ? element.portMovement.moveMode
8726
- : undefined;
8913
+ KonvaInteraction.prototype.createPlaceholderPort = function (elementId, worldPoint, sourcePortId, sourceElementId) {
8914
+ var _a;
8915
+ var resolved = this.resolveLinkTargetPortDraft(elementId, worldPoint, sourcePortId, sourceElementId, 'preview');
8916
+ if (!resolved)
8917
+ return null;
8918
+ var hostWorld = (_a = this.engine.getElementWorldPosition(elementId)) !== null && _a !== void 0 ? _a : resolved.targetElement.position;
8727
8919
  return {
8728
8920
  id: "port-placeholder:".concat(sourcePortId),
8729
8921
  elementId: elementId,
8730
- position: { x: worldPoint.x, y: worldPoint.y },
8731
- shapeId: sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.shapeId,
8732
- size: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.size) ? __assign({}, sourcePort.size) : undefined,
8733
- style: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.style) ? __assign({}, sourcePort.style) : undefined,
8734
- moveMode: destinationMoveMode !== null && destinationMoveMode !== void 0 ? destinationMoveMode : sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.moveMode,
8735
- anchorCenter: (_b = sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.anchorCenter) !== null && _b !== void 0 ? _b : true,
8736
- orientToHostBorder: (_c = sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.orientToHostBorder) !== null && _c !== void 0 ? _c : true,
8737
- placementPoint: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.placementPoint) ? __assign({}, sourcePort.placementPoint) : undefined,
8738
- linkAttachPoint: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.linkAttachPoint) ? __assign({}, sourcePort.linkAttachPoint) : undefined,
8739
- externalLinkAttachPoint: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.externalLinkAttachPoint) ? __assign({}, sourcePort.externalLinkAttachPoint) : undefined,
8740
- internalLinkAttachPoint: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.internalLinkAttachPoint) ? __assign({}, sourcePort.internalLinkAttachPoint) : undefined,
8741
- rotationPivot: (sourcePort === null || sourcePort === void 0 ? void 0 : sourcePort.rotationPivot) ? __assign({}, sourcePort.rotationPivot) : undefined,
8922
+ position: {
8923
+ x: hostWorld.x + resolved.draft.position.x,
8924
+ y: hostWorld.y + resolved.draft.position.y,
8925
+ },
8926
+ shapeId: resolved.draft.shapeId,
8927
+ size: resolved.draft.size ? __assign({}, resolved.draft.size) : undefined,
8928
+ style: resolved.draft.style ? __assign({}, resolved.draft.style) : undefined,
8929
+ textIds: resolved.draft.textIds ? __spreadArray([], resolved.draft.textIds, true) : undefined,
8930
+ moveMode: resolved.draft.moveMode,
8931
+ anchorCenter: resolved.draft.anchorCenter,
8932
+ orientToHostBorder: resolved.draft.orientToHostBorder,
8933
+ placementPoint: resolved.draft.placementPoint ? __assign({}, resolved.draft.placementPoint) : undefined,
8934
+ linkAttachPoint: resolved.draft.linkAttachPoint ? __assign({}, resolved.draft.linkAttachPoint) : undefined,
8935
+ externalLinkAttachPoint: resolved.draft.externalLinkAttachPoint ? __assign({}, resolved.draft.externalLinkAttachPoint) : undefined,
8936
+ internalLinkAttachPoint: resolved.draft.internalLinkAttachPoint ? __assign({}, resolved.draft.internalLinkAttachPoint) : undefined,
8937
+ rotationPivot: resolved.draft.rotationPivot ? __assign({}, resolved.draft.rotationPivot) : undefined,
8938
+ currentAnchorId: resolved.draft.currentAnchorId,
8939
+ };
8940
+ };
8941
+ KonvaInteraction.prototype.resolveLinkTargetPortDraft = function (elementId, worldPoint, sourcePortId, sourceElementId, phase) {
8942
+ var _a;
8943
+ var targetElement = this.getElementById(elementId);
8944
+ var sourcePort = this.resolveLinkSourcePort(sourcePortId);
8945
+ if (!targetElement || !sourcePort)
8946
+ return null;
8947
+ var defaultDraft = this.buildDefaultLinkTargetPortDraft(targetElement, worldPoint, sourcePort);
8948
+ var override = (_a = this.onCreateLinkTargetPort) === null || _a === void 0 ? void 0 : _a.call(this, {
8949
+ phase: phase,
8950
+ pointer: __assign({}, worldPoint),
8951
+ sourcePortId: sourcePortId,
8952
+ sourceElementId: sourceElementId,
8953
+ targetElementId: elementId,
8954
+ sourcePort: this.clonePortData(sourcePort),
8955
+ targetElement: this.cloneElementData(targetElement),
8956
+ defaultPort: this.cloneLinkTargetPortDraft(defaultDraft),
8957
+ });
8958
+ var mergedDraft = this.mergeLinkTargetPortDraft(defaultDraft, override);
8959
+ var normalizedDraft = this.engine.normalizePortDraftForElement(elementId, mergedDraft);
8960
+ if (!normalizedDraft)
8961
+ return null;
8962
+ return {
8963
+ draft: normalizedDraft,
8964
+ targetElement: this.cloneElementData(targetElement),
8965
+ };
8966
+ };
8967
+ KonvaInteraction.prototype.buildDefaultLinkTargetPortDraft = function (element, worldPoint, sourcePort) {
8968
+ var _a, _b, _c, _d;
8969
+ var elementPosition = (_a = this.engine.getElementWorldPosition(element.id)) !== null && _a !== void 0 ? _a : element.position;
8970
+ var destinationMoveMode = ((_b = element.portMovement) === null || _b === void 0 ? void 0 : _b.moveMode) && element.portMovement.moveMode !== 'anchors'
8971
+ ? element.portMovement.moveMode
8972
+ : undefined;
8973
+ return {
8974
+ position: {
8975
+ x: worldPoint.x - elementPosition.x,
8976
+ y: worldPoint.y - elementPosition.y,
8977
+ },
8978
+ shapeId: sourcePort.shapeId,
8979
+ size: sourcePort.size ? __assign({}, sourcePort.size) : undefined,
8980
+ style: sourcePort.style ? __assign({}, sourcePort.style) : undefined,
8981
+ moveMode: destinationMoveMode !== null && destinationMoveMode !== void 0 ? destinationMoveMode : sourcePort.moveMode,
8982
+ anchorCenter: (_c = sourcePort.anchorCenter) !== null && _c !== void 0 ? _c : true,
8983
+ orientToHostBorder: (_d = sourcePort.orientToHostBorder) !== null && _d !== void 0 ? _d : true,
8984
+ placementPoint: sourcePort.placementPoint ? __assign({}, sourcePort.placementPoint) : undefined,
8985
+ linkAttachPoint: sourcePort.linkAttachPoint ? __assign({}, sourcePort.linkAttachPoint) : undefined,
8986
+ externalLinkAttachPoint: sourcePort.externalLinkAttachPoint ? __assign({}, sourcePort.externalLinkAttachPoint) : undefined,
8987
+ internalLinkAttachPoint: sourcePort.internalLinkAttachPoint ? __assign({}, sourcePort.internalLinkAttachPoint) : undefined,
8988
+ rotationPivot: sourcePort.rotationPivot ? __assign({}, sourcePort.rotationPivot) : undefined,
8742
8989
  };
8743
8990
  };
8991
+ KonvaInteraction.prototype.mergeLinkTargetPortDraft = function (defaultDraft, override) {
8992
+ return this.cloneLinkTargetPortDraft(__assign(__assign({}, defaultDraft), (override !== null && override !== void 0 ? override : {})));
8993
+ };
8994
+ KonvaInteraction.prototype.resolveLinkSourcePort = function (sourcePortId) {
8995
+ var _a, _b;
8996
+ if (((_a = this.programmaticLinkSession) === null || _a === void 0 ? void 0 : _a.sourcePortId) === sourcePortId) {
8997
+ return this.clonePortData(this.programmaticLinkSession.sourcePort);
8998
+ }
8999
+ if (((_b = this.dragState) === null || _b === void 0 ? void 0 : _b.mode) === 'link-drag' && this.dragState.sourcePortId === sourcePortId) {
9000
+ return this.clonePortData(this.dragState.sourcePort);
9001
+ }
9002
+ var sourcePort = this.getPortById(sourcePortId);
9003
+ return sourcePort ? this.clonePortData(sourcePort) : null;
9004
+ };
9005
+ KonvaInteraction.prototype.clonePortData = function (port) {
9006
+ 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 });
9007
+ };
9008
+ KonvaInteraction.prototype.cloneLinkTargetPortDraft = function (draft) {
9009
+ 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 });
9010
+ };
9011
+ KonvaInteraction.prototype.cloneElementData = function (element) {
9012
+ 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
9013
+ ? __assign(__assign({}, element.portMovement), { anchorConstraint: element.portMovement.anchorConstraint
9014
+ ? __assign({}, element.portMovement.anchorConstraint) : undefined, positionLimits: element.portMovement.positionLimits
9015
+ ? {
9016
+ x: element.portMovement.positionLimits.x
9017
+ ? __assign({}, element.portMovement.positionLimits.x) : undefined,
9018
+ y: element.portMovement.positionLimits.y
9019
+ ? __assign({}, element.portMovement.positionLimits.y) : undefined,
9020
+ }
9021
+ : undefined }) : undefined });
9022
+ };
8744
9023
  KonvaInteraction.prototype.getElementById = function (id) {
8745
9024
  return this.engine.getState().elements.find(function (element) { return element.id === id; });
8746
9025
  };
@@ -9671,6 +9950,29 @@ var resolveViewportFitTransform = function (state, viewportSize, options) {
9671
9950
  };
9672
9951
  return { pan: pan, zoom: zoom };
9673
9952
  };
9953
+ var resolveFocusElementTransform = function (state, elementId, viewportSize, currentZoom, options) {
9954
+ var elementsById = new Map(state.elements.map(function (element) { return [element.id, element]; }));
9955
+ var element = elementsById.get(elementId);
9956
+ if (!element)
9957
+ return null;
9958
+ var position = resolveElementWorldPositionInState(elementId, elementsById);
9959
+ if (!position)
9960
+ return null;
9961
+ var safeWidth = Math.max(1, viewportSize.width);
9962
+ var safeHeight = Math.max(1, viewportSize.height);
9963
+ var requestedZoom = options === null || options === void 0 ? void 0 : options.zoom;
9964
+ var zoom = typeof requestedZoom === 'number' && Number.isFinite(requestedZoom)
9965
+ ? clamp(requestedZoom, DEFAULT_VIEWPORT_FIT_MIN_ZOOM, DEFAULT_VIEWPORT_FIT_MAX_ZOOM)
9966
+ : currentZoom;
9967
+ var safeZoom = zoom === 0 ? 1 : zoom;
9968
+ var centerX = position.x + element.size.width / 2;
9969
+ var centerY = position.y + element.size.height / 2;
9970
+ var pan = {
9971
+ x: safeWidth / 2 - centerX * safeZoom,
9972
+ y: safeHeight / 2 - centerY * safeZoom,
9973
+ };
9974
+ return { pan: pan, zoom: zoom };
9975
+ };
9674
9976
  var resolveFitToContentPadding = function (fitToContent) {
9675
9977
  if (typeof fitToContent === 'object' && typeof fitToContent.padding === 'number') {
9676
9978
  return Math.max(0, fitToContent.padding);
@@ -9857,6 +10159,7 @@ var createDiagramEditor = function (config) {
9857
10159
  shapeHoverControls: config.elementShapeHoverControls,
9858
10160
  onShapeHoverControlInteracted: config.onElementShapeHoverControlInteraction,
9859
10161
  onShapeHoverControlActivated: config.onElementShapeHoverControlActivated,
10162
+ onCreateLinkTargetPort: config.onCreateLinkTargetPort,
9860
10163
  });
9861
10164
  interaction.bind();
9862
10165
  if (config.initialState) {
@@ -9904,6 +10207,12 @@ var createDiagramEditor = function (config) {
9904
10207
  return;
9905
10208
  engine.setViewport(transform.pan, transform.zoom);
9906
10209
  },
10210
+ focusElement: function (elementId, options) {
10211
+ var transform = resolveFocusElementTransform(engine.getState(), elementId, { width: stageWidth, height: stageHeight }, engine.getViewport().zoom, options);
10212
+ if (!transform)
10213
+ return;
10214
+ engine.setViewport(transform.pan, transform.zoom);
10215
+ },
9907
10216
  exportImage: function (options) {
9908
10217
  engine.render();
9909
10218
  if (typeof stage.toDataURL !== 'function') {