orcasvn-react-diagrams 0.2.12 → 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 (35) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +15 -11
  3. package/ai/api-contract.json +47 -0
  4. package/ai/invariants.json +6 -2
  5. package/ai/manifest.json +1 -1
  6. package/dist/cjs/examples.js +427 -48
  7. package/dist/cjs/index.js +226 -36
  8. package/dist/cjs/types/api/createDiagramEditor.d.ts +2 -1
  9. package/dist/cjs/types/api/types.d.ts +50 -0
  10. package/dist/cjs/types/displaybox/demos/deletionEventsDemo.d.ts +2 -0
  11. package/dist/cjs/types/displaybox/demos/focusElementDemo.d.ts +4 -0
  12. package/dist/cjs/types/engine/DiagramEngine.d.ts +9 -0
  13. package/dist/esm/examples.js +427 -48
  14. package/dist/esm/examples.js.map +1 -1
  15. package/dist/esm/index.js +226 -36
  16. package/dist/esm/index.js.map +1 -1
  17. package/dist/esm/types/api/createDiagramEditor.d.ts +2 -1
  18. package/dist/esm/types/api/types.d.ts +50 -0
  19. package/dist/esm/types/displaybox/demos/deletionEventsDemo.d.ts +2 -0
  20. package/dist/esm/types/displaybox/demos/focusElementDemo.d.ts +4 -0
  21. package/dist/esm/types/engine/DiagramEngine.d.ts +9 -0
  22. package/dist/examples.d.ts +51 -0
  23. package/dist/index.d.ts +52 -1
  24. package/docs/API_CONTRACT.md +48 -1
  25. package/docs/ARCHITECTURE.md +9 -7
  26. package/docs/CAPABILITIES.md +3 -0
  27. package/docs/COMMANDS_EVENTS.md +15 -6
  28. package/docs/DOCUMENTATION_WORKFLOW.md +3 -1
  29. package/docs/INTEGRATION_PLAYBOOK.md +4 -0
  30. package/docs/PORTING_CHECKLIST.md +4 -1
  31. package/package.json +1 -1
  32. package/src/displaybox/demos/DeletionEventsDemoTab.tsx +167 -9
  33. package/src/displaybox/demos/deletionEventsDemo.ts +2 -2
  34. package/src/displaybox/demos/focusElementDemo.ts +91 -0
  35. package/src/displaybox/demos/index.tsx +2 -0
package/dist/cjs/index.js CHANGED
@@ -4137,8 +4137,15 @@ var DiagramEngine = /** @class */ (function () {
4137
4137
  var _this = this;
4138
4138
  var _a;
4139
4139
  var existing = this.model.getElement(id);
4140
- 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;
4141
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
+ }
4142
4149
  this.commandQueue.run(createRemoveElementCommand(id), this.model);
4143
4150
  var removal = this.computeRemovalDiff(before);
4144
4151
  var allPatches = this.mutationPipeline.run({
@@ -4146,9 +4153,6 @@ var DiagramEngine = /** @class */ (function () {
4146
4153
  layoutSteps: [function () { return _this.applyLayoutCascade(parentId); }],
4147
4154
  });
4148
4155
  this.emitChange(allPatches);
4149
- if (existing) {
4150
- this.events.emit('elementDeleted', { elementId: id });
4151
- }
4152
4156
  this.emitEntityDeletionEvents(removal.removed);
4153
4157
  };
4154
4158
  DiagramEngine.prototype.addPortToElement = function (elementId, port) {
@@ -4229,7 +4233,14 @@ var DiagramEngine = /** @class */ (function () {
4229
4233
  }
4230
4234
  };
4231
4235
  DiagramEngine.prototype.removePort = function (id) {
4236
+ if (!this.model.getPort(id))
4237
+ return;
4232
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
+ }
4233
4244
  this.commandQueue.run(createRemovePortCommand(id), this.model);
4234
4245
  var removal = this.computeRemovalDiff(before);
4235
4246
  this.emitChange(removal.patches);
@@ -4323,7 +4334,14 @@ var DiagramEngine = /** @class */ (function () {
4323
4334
  }
4324
4335
  };
4325
4336
  DiagramEngine.prototype.removeLink = function (id) {
4337
+ if (!this.model.getLink(id))
4338
+ return;
4326
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
+ }
4327
4345
  this.commandQueue.run(createRemoveLinkCommand(id), this.model);
4328
4346
  var removal = this.computeRemovalDiff(before);
4329
4347
  this.emitChange(removal.patches);
@@ -4408,7 +4426,14 @@ var DiagramEngine = /** @class */ (function () {
4408
4426
  this.emitChange(patches);
4409
4427
  };
4410
4428
  DiagramEngine.prototype.removeText = function (id) {
4429
+ if (!this.model.getText(id))
4430
+ return;
4411
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
+ }
4412
4437
  this.commandQueue.run(createRemoveTextCommand(id), this.model);
4413
4438
  var removal = this.computeRemovalDiff(before);
4414
4439
  this.emitChange(removal.patches);
@@ -4603,40 +4628,22 @@ var DiagramEngine = /** @class */ (function () {
4603
4628
  if (selected.length === 0)
4604
4629
  return;
4605
4630
  var before = this.model.toState();
4606
- var elementIds = [];
4607
- selected.forEach(function (id) {
4608
- if (_this.model.getElement(id))
4609
- elementIds.push(id);
4610
- else if (_this.model.getPort(id))
4611
- ;
4612
- else if (_this.model.getLink(id))
4613
- ;
4614
- else if (_this.model.getText(id))
4615
- ;
4616
- });
4617
4631
  selected.forEach(function (id) {
4618
- if (_this.model.getElement(id)) {
4619
- _this.commandQueue.run(createRemoveElementCommand(id), _this.model);
4632
+ var root = _this.resolveDeletionRoot(id);
4633
+ if (!root)
4620
4634
  return;
4621
- }
4622
- if (_this.model.getPort(id)) {
4623
- _this.commandQueue.run(createRemovePortCommand(id), _this.model);
4624
- return;
4625
- }
4626
- if (_this.model.getLink(id)) {
4627
- _this.commandQueue.run(createRemoveLinkCommand(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')) {
4628
4638
  return;
4629
4639
  }
4630
- if (_this.model.getText(id)) {
4631
- _this.commandQueue.run(createRemoveTextCommand(id), _this.model);
4632
- }
4640
+ _this.applyRemovalCommand(root);
4633
4641
  });
4634
4642
  var removal = this.computeRemovalDiff(before);
4643
+ if (removal.patches.length === 0)
4644
+ return;
4635
4645
  this.emitChange(removal.patches);
4636
4646
  this.emitEntityDeletionEvents(removal.removed);
4637
- elementIds.forEach(function (elementId) { return _this.events.emit('elementDeleted', { elementId: elementId }); });
4638
- this.selection.clear();
4639
- this.emitSelection();
4640
4647
  };
4641
4648
  DiagramEngine.prototype.setViewport = function (pan, zoom) {
4642
4649
  var hasPanChange = this.viewport.pan.x !== pan.x || this.viewport.pan.y !== pan.y;
@@ -4689,6 +4696,9 @@ var DiagramEngine = /** @class */ (function () {
4689
4696
  DiagramEngine.prototype.emitElementClick = function (elementId, pointer, isMulti) {
4690
4697
  this.events.emit('elementClick', { elementId: elementId, pointer: pointer, isMulti: isMulti });
4691
4698
  };
4699
+ DiagramEngine.prototype.emitElementDoubleClick = function (elementId, pointer, isMulti) {
4700
+ this.events.emit('elementDoubleClick', { elementId: elementId, pointer: pointer, isMulti: isMulti });
4701
+ };
4692
4702
  DiagramEngine.prototype.emitElementLinkStarted = function (event) {
4693
4703
  this.events.emit('elementLinkStarted', event);
4694
4704
  };
@@ -5332,8 +5342,8 @@ var DiagramEngine = /** @class */ (function () {
5332
5342
  });
5333
5343
  return { patches: normalizedPatches, movedPortIds: Array.from(movedPortIds) };
5334
5344
  };
5335
- DiagramEngine.prototype.computeRemovalDiff = function (before) {
5336
- var after = this.model.toState();
5345
+ DiagramEngine.prototype.computeRemovalDiff = function (before, after) {
5346
+ if (after === void 0) { after = this.model.toState(); }
5337
5347
  var removedPatches = [];
5338
5348
  var beforeElements = new Set(before.elements.map(function (element) { return element.id; }));
5339
5349
  var beforePorts = new Set(before.ports.map(function (port) { return port.id; }));
@@ -5343,9 +5353,13 @@ var DiagramEngine = /** @class */ (function () {
5343
5353
  var afterPorts = new Set(after.ports.map(function (port) { return port.id; }));
5344
5354
  var afterLinks = new Set(after.links.map(function (link) { return link.id; }));
5345
5355
  var afterTexts = new Set(after.texts.map(function (text) { return text.id; }));
5356
+ var removedElements = [];
5346
5357
  beforeElements.forEach(function (id) {
5347
5358
  if (!afterElements.has(id))
5348
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);
5349
5363
  });
5350
5364
  var removedPorts = [];
5351
5365
  beforePorts.forEach(function (id) {
@@ -5376,11 +5390,144 @@ var DiagramEngine = /** @class */ (function () {
5376
5390
  });
5377
5391
  return {
5378
5392
  patches: removedPatches,
5379
- removed: { ports: removedPorts, links: removedLinks, texts: removedTexts },
5393
+ removed: { elements: removedElements, ports: removedPorts, links: removedLinks, texts: removedTexts },
5380
5394
  };
5381
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
+ };
5382
5526
  DiagramEngine.prototype.emitEntityDeletionEvents = function (removed) {
5383
5527
  var _this = this;
5528
+ removed.elements.forEach(function (element) {
5529
+ _this.events.emit('elementDeleted', { elementId: element.id });
5530
+ });
5384
5531
  removed.ports.forEach(function (port) {
5385
5532
  _this.events.emit('portDeleted', { portId: port.id, elementId: port.elementId });
5386
5533
  });
@@ -7265,15 +7412,29 @@ var KonvaInteraction = /** @class */ (function () {
7265
7412
  this.stage.on(upEvents, pointerUp);
7266
7413
  this.handlers.push([upEvents, pointerUp]);
7267
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;
7268
7421
  var point = _this.getPointerPosition();
7269
7422
  if (!point)
7270
7423
  return;
7271
7424
  var hit = _this.resolveHit(point);
7272
- if (!hit || hit.type !== 'text')
7425
+ if (!hit)
7273
7426
  return;
7274
- if (!_this.isTextEditable(hit.id))
7427
+ if (hit.type === 'text') {
7428
+ if (!_this.isTextEditable(hit.id))
7429
+ return;
7430
+ _this.startTextEdit(hit.id);
7431
+ return;
7432
+ }
7433
+ if (hit.type !== 'element')
7275
7434
  return;
7276
- _this.startTextEdit(hit.id);
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);
7277
7438
  };
7278
7439
  this.stage.on('dblclick dbltap', doubleClick);
7279
7440
  this.handlers.push(['dblclick dbltap', doubleClick]);
@@ -9791,6 +9952,29 @@ var resolveViewportFitTransform = function (state, viewportSize, options) {
9791
9952
  };
9792
9953
  return { pan: pan, zoom: zoom };
9793
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
+ };
9794
9978
  var resolveFitToContentPadding = function (fitToContent) {
9795
9979
  if (typeof fitToContent === 'object' && typeof fitToContent.padding === 'number') {
9796
9980
  return Math.max(0, fitToContent.padding);
@@ -10025,6 +10209,12 @@ var createDiagramEditor = function (config) {
10025
10209
  return;
10026
10210
  engine.setViewport(transform.pan, transform.zoom);
10027
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
+ },
10028
10218
  exportImage: function (options) {
10029
10219
  engine.render();
10030
10220
  if (typeof stage.toDataURL !== 'function') {
@@ -1,4 +1,4 @@
1
- import { DiagramEngineHandle, Point, DiagramState, ElementShapeHoverControlActivationEvent, ElementShapeHoverControlInteractionEvent, ElementShapeHoverControls, EngineChangeEvent, EngineSelectionEvent, LinkTargetPortCreationHandler, LinkColorPoolPolicy, LinkRouteRefreshPolicy, ViewportFitOptions } from './types';
1
+ import { DiagramEngineHandle, Point, DiagramState, ElementShapeHoverControlActivationEvent, ElementShapeHoverControlInteractionEvent, ElementShapeHoverControls, EngineChangeEvent, EngineSelectionEvent, LinkTargetPortCreationHandler, LinkColorPoolPolicy, LinkRouteRefreshPolicy, FocusElementOptions, ViewportFitOptions } from './types';
2
2
  import { type BuiltInShapeKind } from '../shapes';
3
3
  export type SimpleShape = {
4
4
  id: string;
@@ -41,6 +41,7 @@ export type DiagramEditorHandle = DiagramEngineHandle & {
41
41
  completeLinkToElement: (targetElementId: string, pointer: Point) => void;
42
42
  cancelLink: () => void;
43
43
  zoomToFitElements: (options?: ViewportFitOptions) => void;
44
+ focusElement: (elementId: string, options?: FocusElementOptions) => void;
44
45
  exportImage: (options?: DiagramImageExportOptions) => string;
45
46
  resize: (width: number, height: number) => void;
46
47
  setElementShapeHoverControls: (controls?: ElementShapeHoverControls) => void;
@@ -24,6 +24,9 @@ export type ViewportFitOptions = {
24
24
  minZoom?: number;
25
25
  maxZoom?: number;
26
26
  };
27
+ export type FocusElementOptions = {
28
+ zoom?: number;
29
+ };
27
30
  export type MoveConstraint = 'free' | 'inside' | 'border';
28
31
  export type TextInteractionPolicy = {
29
32
  movable?: boolean;
@@ -394,6 +397,11 @@ export type ElementPointerEvent = {
394
397
  pointer: EnginePointerInfo;
395
398
  isMulti: boolean;
396
399
  };
400
+ export type ElementDoubleClickEvent = {
401
+ elementId: string;
402
+ pointer: EnginePointerInfo;
403
+ isMulti: boolean;
404
+ };
397
405
  export type ElementMovedEvent = {
398
406
  elementId: string;
399
407
  oldWorld: Point;
@@ -418,18 +426,55 @@ export type GridLayoutChangedEvent = {
418
426
  beforeGridTemplate?: ElementLayoutGridRowTemplate[];
419
427
  afterGridTemplate: ElementLayoutGridRowTemplate[];
420
428
  };
429
+ export type DeletionTrigger = 'direct' | 'selection' | 'cascade';
430
+ export type DeletionRootRef = {
431
+ entity: 'element' | 'port' | 'link' | 'text';
432
+ id: string;
433
+ };
434
+ export type ElementDeletingEvent = {
435
+ elementId: string;
436
+ trigger: DeletionTrigger;
437
+ root: DeletionRootRef;
438
+ cancel: () => void;
439
+ cancelled: boolean;
440
+ };
421
441
  export type ElementDeletedEvent = {
422
442
  elementId: string;
423
443
  };
444
+ export type PortDeletingEvent = {
445
+ portId: string;
446
+ elementId: string;
447
+ trigger: DeletionTrigger;
448
+ root: DeletionRootRef;
449
+ cancel: () => void;
450
+ cancelled: boolean;
451
+ };
424
452
  export type PortDeletedEvent = {
425
453
  portId: string;
426
454
  elementId: string;
427
455
  };
456
+ export type LinkDeletingEvent = {
457
+ linkId: string;
458
+ sourcePortId: string;
459
+ targetPortId: string;
460
+ trigger: DeletionTrigger;
461
+ root: DeletionRootRef;
462
+ cancel: () => void;
463
+ cancelled: boolean;
464
+ };
428
465
  export type LinkDeletedEvent = {
429
466
  linkId: string;
430
467
  sourcePortId: string;
431
468
  targetPortId: string;
432
469
  };
470
+ export type TextDeletingEvent = {
471
+ textId: string;
472
+ ownerId?: string | null;
473
+ trigger: DeletionTrigger;
474
+ root: DeletionRootRef;
475
+ cancel: () => void;
476
+ cancelled: boolean;
477
+ };
433
478
  export type TextDeletedEvent = {
434
479
  textId: string;
435
480
  ownerId?: string | null;
@@ -483,13 +528,18 @@ export type EngineEventMap = {
483
528
  portMoved: PortMovedEvent;
484
529
  portSelected: PortSelectedEvent;
485
530
  elementClick: ElementPointerEvent;
531
+ elementDoubleClick: ElementDoubleClickEvent;
486
532
  elementDragged: ElementDropEvent;
487
533
  elementMoved: ElementMovedEvent;
488
534
  elementResized: ElementResizedEvent;
489
535
  gridLayoutChanged: GridLayoutChangedEvent;
536
+ elementDeleting: ElementDeletingEvent;
490
537
  elementDeleted: ElementDeletedEvent;
538
+ portDeleting: PortDeletingEvent;
491
539
  portDeleted: PortDeletedEvent;
540
+ linkDeleting: LinkDeletingEvent;
492
541
  linkDeleted: LinkDeletedEvent;
542
+ textDeleting: TextDeletingEvent;
493
543
  textDeleted: TextDeletedEvent;
494
544
  textUpdated: TextUpdatedEvent;
495
545
  elementSelected: ElementSelectedEvent;
@@ -1,2 +1,4 @@
1
+ import type { DiagramState } from '../../api';
1
2
  import type { DemoConfig } from '../types';
3
+ export declare const createDeletionEventsState: () => DiagramState;
2
4
  export declare const deletionEventsDemoConfig: DemoConfig;
@@ -0,0 +1,4 @@
1
+ import type { DiagramState } from '../../api';
2
+ import type { DemoConfig } from '../types';
3
+ export declare const createFocusElementState: () => DiagramState;
4
+ export declare const focusElementDemoConfig: DemoConfig;
@@ -120,6 +120,7 @@ export default class DiagramEngine {
120
120
  emitPortMouseDown(event: PortMouseEvent): void;
121
121
  emitPortMouseUp(event: PortMouseEvent): void;
122
122
  emitElementClick(elementId: string, pointer: EnginePointerInfo, isMulti: boolean): void;
123
+ emitElementDoubleClick(elementId: string, pointer: EnginePointerInfo, isMulti: boolean): void;
123
124
  emitElementLinkStarted(event: {
124
125
  sourcePortId: string;
125
126
  sourceElementId: string;
@@ -172,6 +173,14 @@ export default class DiagramEngine {
172
173
  private refreshLinksForRenderCycle;
173
174
  private normalizePortsForHostPolicies;
174
175
  private computeRemovalDiff;
176
+ private resolveDeletionRoot;
177
+ private applyRemovalCommand;
178
+ private planRemoval;
179
+ private emitDeletionLifecycleEvents;
180
+ private emitElementDeleting;
181
+ private emitPortDeleting;
182
+ private emitLinkDeleting;
183
+ private emitTextDeleting;
175
184
  private emitEntityDeletionEvents;
176
185
  }
177
186
  export declare const createDiagramEngine: (config: DiagramEngineConfig) => DiagramEngineHandle;