orcasvn-react-diagrams 0.2.5 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +15 -34
  3. package/ai/api-contract.json +38 -1
  4. package/ai/manifest.json +1 -1
  5. package/dist/cjs/examples.js +1252 -113
  6. package/dist/cjs/index.js +876 -81
  7. package/dist/cjs/types/api/createDiagramEditor.d.ts +2 -1
  8. package/dist/cjs/types/api/types.d.ts +26 -1
  9. package/dist/cjs/types/displaybox/demos/OffsetAnchorAvoidanceDemoTab.d.ts +3 -0
  10. package/dist/cjs/types/displaybox/demos/ZoomToFitElementsDemoTab.d.ts +3 -0
  11. package/dist/cjs/types/displaybox/demos/offsetAnchorAvoidanceDemo.d.ts +4 -0
  12. package/dist/cjs/types/displaybox/demos/textDemo.d.ts +3 -0
  13. package/dist/cjs/types/displaybox/demos/zoomToFitElementsDemo.d.ts +4 -0
  14. package/dist/cjs/types/engine/AutoLayoutService.d.ts +44 -1
  15. package/dist/cjs/types/engine/DiagramEngine.d.ts +12 -0
  16. package/dist/cjs/types/engine/LinkRoutingService.d.ts +1 -0
  17. package/dist/cjs/types/models/TextModel.d.ts +1 -0
  18. package/dist/cjs/types/renderer/konva/KonvaInteraction.d.ts +2 -0
  19. package/dist/esm/examples.js +1252 -113
  20. package/dist/esm/examples.js.map +1 -1
  21. package/dist/esm/index.js +876 -81
  22. package/dist/esm/index.js.map +1 -1
  23. package/dist/esm/types/api/createDiagramEditor.d.ts +2 -1
  24. package/dist/esm/types/api/types.d.ts +26 -1
  25. package/dist/esm/types/displaybox/demos/OffsetAnchorAvoidanceDemoTab.d.ts +3 -0
  26. package/dist/esm/types/displaybox/demos/ZoomToFitElementsDemoTab.d.ts +3 -0
  27. package/dist/esm/types/displaybox/demos/offsetAnchorAvoidanceDemo.d.ts +4 -0
  28. package/dist/esm/types/displaybox/demos/textDemo.d.ts +3 -0
  29. package/dist/esm/types/displaybox/demos/zoomToFitElementsDemo.d.ts +4 -0
  30. package/dist/esm/types/engine/AutoLayoutService.d.ts +44 -1
  31. package/dist/esm/types/engine/DiagramEngine.d.ts +12 -0
  32. package/dist/esm/types/engine/LinkRoutingService.d.ts +1 -0
  33. package/dist/esm/types/models/TextModel.d.ts +1 -0
  34. package/dist/esm/types/renderer/konva/KonvaInteraction.d.ts +2 -0
  35. package/dist/examples.d.ts +27 -1
  36. package/dist/index.d.ts +29 -2
  37. package/docs/API_CONTRACT.md +38 -3
  38. package/docs/CAPABILITIES.md +3 -0
  39. package/docs/COMMANDS_EVENTS.md +8 -0
  40. package/docs/DOCUMENTATION_WORKFLOW.md +2 -1
  41. package/docs/INTEGRATION_PLAYBOOK.md +3 -0
  42. package/docs/STATE_INVARIANTS.md +4 -0
  43. package/package.json +1 -1
  44. package/src/displaybox/demos/AutoLayoutDemoTab.tsx +337 -316
  45. package/src/displaybox/demos/EngineEventsDemoTab.tsx +12 -11
  46. package/src/displaybox/demos/OffsetAnchorAvoidanceDemoTab.tsx +30 -0
  47. package/src/displaybox/demos/TextLayoutDemoTab.tsx +18 -1
  48. package/src/displaybox/demos/ZoomToFitElementsDemoTab.tsx +29 -0
  49. package/src/displaybox/demos/autoLayoutDemo.ts +74 -73
  50. package/src/displaybox/demos/index.tsx +80 -64
  51. package/src/displaybox/demos/offsetAnchorAvoidanceDemo.ts +211 -0
  52. package/src/displaybox/demos/textDemo.ts +6 -2
  53. package/src/displaybox/demos/zoomToFitElementsDemo.ts +83 -0
@@ -178,7 +178,7 @@ var pathLength = function (points) {
178
178
  }
179
179
  return total;
180
180
  };
181
- var clamp$1 = function (value, min, max) { return Math.max(min, Math.min(max, value)); };
181
+ var clamp$2 = function (value, min, max) { return Math.max(min, Math.min(max, value)); };
182
182
  var ObstacleRouter = /** @class */ (function () {
183
183
  function ObstacleRouter(options) {
184
184
  var _a, _b, _c;
@@ -458,7 +458,7 @@ var ObstacleRouter = /** @class */ (function () {
458
458
  return null;
459
459
  if (corridor.axis === 'horizontal') {
460
460
  var direction_1 = source.x <= target.x ? 1 : -1;
461
- var corridorY = clamp$1((source.y + target.y) / 2, corridor.bounds.y + this.padding, corridor.bounds.y + corridor.bounds.height - this.padding);
461
+ var corridorY = clamp$2((source.y + target.y) / 2, corridor.bounds.y + this.padding, corridor.bounds.y + corridor.bounds.height - this.padding);
462
462
  var sourceExitX = direction_1 > 0
463
463
  ? corridor.sourceBranchRect.x + corridor.sourceBranchRect.width + this.padding
464
464
  : corridor.sourceBranchRect.x - this.padding;
@@ -475,7 +475,7 @@ var ObstacleRouter = /** @class */ (function () {
475
475
  ]);
476
476
  }
477
477
  var direction = source.y <= target.y ? 1 : -1;
478
- var corridorX = clamp$1((source.x + target.x) / 2, corridor.bounds.x + this.padding, corridor.bounds.x + corridor.bounds.width - this.padding);
478
+ var corridorX = clamp$2((source.x + target.x) / 2, corridor.bounds.x + this.padding, corridor.bounds.x + corridor.bounds.width - this.padding);
479
479
  var sourceExitY = direction > 0
480
480
  ? corridor.sourceBranchRect.y + corridor.sourceBranchRect.height + this.padding
481
481
  : corridor.sourceBranchRect.y - this.padding;
@@ -990,6 +990,8 @@ var textDemoOwnerId = 'text-layout-owner';
990
990
  var textDemoOwnedTextId = 'text-owned-overflow';
991
991
  var textDemoFloatingTextId = 'text-floating-overflow';
992
992
  var textDemoLongSample = 'Long diagram label: middle ellipsis should keep the beginning and end visible while preserving the full canonical content in model state.';
993
+ var textDemoOwnedInteraction = { movable: false, editable: false };
994
+ var textDemoFloatingInteraction = { movable: true, editable: true };
993
995
  var createTextOwnershipState = function () { return ({
994
996
  elements: [
995
997
  {
@@ -1007,6 +1009,7 @@ var createTextOwnershipState = function () { return ({
1007
1009
  content: textDemoLongSample,
1008
1010
  position: { x: 12, y: 12 },
1009
1011
  ownerId: textDemoOwnerId,
1012
+ interaction: textDemoOwnedInteraction,
1010
1013
  layout: {
1011
1014
  boundsMode: 'owner-width',
1012
1015
  wrap: 'none',
@@ -1018,6 +1021,7 @@ var createTextOwnershipState = function () { return ({
1018
1021
  id: textDemoFloatingTextId,
1019
1022
  content: textDemoLongSample,
1020
1023
  position: { x: 470, y: 120 },
1024
+ interaction: textDemoFloatingInteraction,
1021
1025
  layout: {
1022
1026
  boundsMode: 'fixed',
1023
1027
  fixedSize: { width: 240, height: 90 },
@@ -1032,7 +1036,7 @@ var createTextOwnershipState = function () { return ({
1032
1036
  var textDemoConfig = ({
1033
1037
  id: 'text',
1034
1038
  title: 'Text Layout + Overflow',
1035
- description: 'Owner-constrained and fixed-bounds text with wrap and ellipsis behavior. Full content is preserved in model state; truncation is visual-only.',
1039
+ description: 'Owner-constrained and fixed-bounds text with wrap, ellipsis, and per-text interaction behavior. Full content is preserved in model state; truncation is visual-only.',
1036
1040
  createState: createTextOwnershipState,
1037
1041
  elementShapes: baseElementShapes,
1038
1042
  portShapes: basePortShapes,
@@ -1278,7 +1282,8 @@ var createAutoLayoutState = function () { return ({
1278
1282
  gap: 10,
1279
1283
  align: 'center',
1280
1284
  autoResize: 'grow-shrink',
1281
- gridTemplate: [[3], [1, 2]],
1285
+ gridTemplate: [12, 4, 8],
1286
+ gridChildWidthResizeEnabled: false,
1282
1287
  childMinWidth: 24,
1283
1288
  childMinHeight: 18,
1284
1289
  },
@@ -1348,7 +1353,7 @@ var createAutoLayoutState = function () { return ({
1348
1353
  { id: 'label-col-c', content: 'col-c', position: { x: 6, y: -14 }, ownerId: 'col-c' },
1349
1354
  {
1350
1355
  id: 'label-layout-grid',
1351
- content: 'Grid template [[3],[1,2]]',
1356
+ content: 'Grid template [12,4,8]',
1352
1357
  position: { x: 8, y: 6 },
1353
1358
  ownerId: 'layout-grid',
1354
1359
  layout: { boundsMode: 'owner-width', wrap: 'word', overflow: 'clip', padding: 0 },
@@ -3391,7 +3396,7 @@ var addLinksAction = {
3391
3396
  });
3392
3397
  },
3393
3398
  };
3394
- var rerouteAllAction = {
3399
+ var rerouteAllAction$1 = {
3395
3400
  id: 'reroute-links',
3396
3401
  label: 'Reroute All Links',
3397
3402
  run: function (editor) {
@@ -3407,7 +3412,7 @@ var obstacleRoutingDemoConfig = {
3407
3412
  portShapes: basePortShapes,
3408
3413
  defaultElementShapeId: 'default',
3409
3414
  defaultPortShapeId: 'port-circle',
3410
- actions: [addLinksAction, rerouteAllAction],
3415
+ actions: [addLinksAction, rerouteAllAction$1],
3411
3416
  };
3412
3417
 
3413
3418
  var createLinkBendHandlesState = function () { return ({
@@ -4385,6 +4390,7 @@ var TextModel = /** @class */ (function () {
4385
4390
  this.size = data.size ? __assign({}, data.size) : undefined;
4386
4391
  this.style = data.style;
4387
4392
  this.ownerId = (_a = data.ownerId) !== null && _a !== void 0 ? _a : null;
4393
+ this.interaction = data.interaction ? __assign({}, data.interaction) : undefined;
4388
4394
  this.layout = data.layout ? __assign({}, data.layout) : undefined;
4389
4395
  this.displayContent = (_b = data.displayContent) !== null && _b !== void 0 ? _b : data.content;
4390
4396
  this.displayOffset = data.displayOffset ? __assign({}, data.displayOffset) : undefined;
@@ -4421,6 +4427,7 @@ var TextModel = /** @class */ (function () {
4421
4427
  size: this.size ? __assign({}, this.size) : undefined,
4422
4428
  style: this.style,
4423
4429
  ownerId: this.ownerId,
4430
+ interaction: this.interaction ? __assign({}, this.interaction) : undefined,
4424
4431
  layout: this.layout ? __assign({}, this.layout) : undefined,
4425
4432
  displayContent: (_a = this.displayContent) !== null && _a !== void 0 ? _a : this.content,
4426
4433
  displayOffset: this.displayOffset ? __assign({}, this.displayOffset) : undefined,
@@ -4435,7 +4442,7 @@ var distance = function (a, b) {
4435
4442
  var dy = a.y - b.y;
4436
4443
  return Math.sqrt(dx * dx + dy * dy);
4437
4444
  };
4438
- var clamp = function (value, min, max) {
4445
+ var clamp$1 = function (value, min, max) {
4439
4446
  if (value < min)
4440
4447
  return min;
4441
4448
  if (value > max)
@@ -5683,6 +5690,7 @@ var TextLayoutService = /** @class */ (function () {
5683
5690
  return TextLayoutService;
5684
5691
  }());
5685
5692
 
5693
+ var GRID_ROW_UNITS = 12;
5686
5694
  var AutoLayoutService = /** @class */ (function () {
5687
5695
  function AutoLayoutService(config) {
5688
5696
  this.model = config.model;
@@ -5697,11 +5705,24 @@ var AutoLayoutService = /** @class */ (function () {
5697
5705
  if (!layout || layout.mode === 'manual')
5698
5706
  return { patches: [], movedPortIds: [] };
5699
5707
  var preserveParentSize = Boolean(options === null || options === void 0 ? void 0 : options.preserveParentSize);
5708
+ var preserveParentWidth = preserveParentSize || Boolean(options === null || options === void 0 ? void 0 : options.preserveParentWidth);
5709
+ var preserveParentHeight = preserveParentSize || Boolean(options === null || options === void 0 ? void 0 : options.preserveParentHeight);
5700
5710
  var padding = this.resolveLayoutPadding(layout);
5701
5711
  var labelReservedTopLane = this.resolveLabelReservedTopLane(parentId, layout);
5702
5712
  var autoResize = this.resolveAutoResizeMode(layout);
5703
5713
  var children = this.model.getChildren(parentId);
5704
5714
  if (children.length === 0) {
5715
+ if (preserveParentWidth || preserveParentHeight) {
5716
+ var targetWidth_1 = preserveParentWidth ? parent.size.width : Math.max(0, Math.round(padding.x * 2));
5717
+ var targetHeight_1 = preserveParentHeight
5718
+ ? parent.size.height
5719
+ : Math.max(0, Math.round(padding.y * 2 + labelReservedTopLane));
5720
+ if (parent.size.width === targetWidth_1 && parent.size.height === targetHeight_1) {
5721
+ return { patches: [], movedPortIds: [] };
5722
+ }
5723
+ var resizePatches_1 = this.commandQueue.run(createResizeElementCommand(parentId, { width: targetWidth_1, height: targetHeight_1 }), this.model);
5724
+ return { patches: resizePatches_1, movedPortIds: __spreadArray([], parent.portIds, true) };
5725
+ }
5705
5726
  if (preserveParentSize) {
5706
5727
  return { patches: [], movedPortIds: [] };
5707
5728
  }
@@ -5716,9 +5737,17 @@ var AutoLayoutService = /** @class */ (function () {
5716
5737
  return { patches: resizePatches, movedPortIds: __spreadArray([], parent.portIds, true) };
5717
5738
  }
5718
5739
  if (layout.mode === 'grid') {
5719
- return this.applyGridLayoutForParent(parentId, parent, children, preserveParentSize);
5740
+ return this.applyGridLayoutForParent(parentId, parent, children, {
5741
+ preserveParentSize: preserveParentSize,
5742
+ preserveParentWidth: preserveParentWidth,
5743
+ preserveParentHeight: preserveParentHeight,
5744
+ });
5720
5745
  }
5721
- return this.applyAxisLayoutForParent(parentId, parent, children, layout.mode, preserveParentSize);
5746
+ return this.applyAxisLayoutForParent(parentId, parent, children, layout.mode, {
5747
+ preserveParentSize: preserveParentSize,
5748
+ preserveParentWidth: preserveParentWidth,
5749
+ preserveParentHeight: preserveParentHeight,
5750
+ });
5722
5751
  };
5723
5752
  AutoLayoutService.prototype.applyLayoutCascade = function (startParentId) {
5724
5753
  var _a;
@@ -5761,11 +5790,102 @@ var AutoLayoutService = /** @class */ (function () {
5761
5790
  });
5762
5791
  return { patches: patches, movedPortIds: Array.from(new Set(movedPortIds)) };
5763
5792
  };
5764
- AutoLayoutService.prototype.applyAxisLayoutForParent = function (parentId, parent, children, axis, preserveParentSize) {
5793
+ AutoLayoutService.prototype.describeGridRows = function (parentId) {
5794
+ var _a;
5795
+ var parent = this.model.getElement(parentId);
5796
+ if (!parent || ((_a = parent.layout) === null || _a === void 0 ? void 0 : _a.mode) !== 'grid')
5797
+ return [];
5798
+ return this.resolveAssignedGridRows(parent).map(function (row) { return ({ childIds: __spreadArray([], row.childIds, true) }); });
5799
+ };
5800
+ AutoLayoutService.prototype.describeGridSlotState = function (parentId) {
5801
+ var _this = this;
5802
+ var _a;
5803
+ var parent = this.model.getElement(parentId);
5804
+ if (!parent || ((_a = parent.layout) === null || _a === void 0 ? void 0 : _a.mode) !== 'grid')
5805
+ return null;
5806
+ var assignedRows = this.resolveAssignedGridRows(parent);
5807
+ return {
5808
+ orderedChildIds: assignedRows.flatMap(function (row) { return row.childIds; }),
5809
+ slotWeights: assignedRows.flatMap(function (row) { return row.weights.slice(0, row.childIds.length).map(function (weight) { return _this.clampGridUnits(weight); }); }),
5810
+ };
5811
+ };
5812
+ AutoLayoutService.prototype.resolveGridReorderedLayout = function (parentId, previousState) {
5813
+ var _this = this;
5814
+ var _a;
5815
+ var parent = this.model.getElement(parentId);
5816
+ if (!parent || ((_a = parent.layout) === null || _a === void 0 ? void 0 : _a.mode) !== 'grid' || !parent.layout)
5817
+ return null;
5818
+ var sortedChildren = this.sortGridChildrenForLayout(this.model.getChildren(parentId));
5819
+ var orderedChildIds = sortedChildren.map(function (child) { return child.id; });
5820
+ if (orderedChildIds.length === previousState.orderedChildIds.length &&
5821
+ orderedChildIds.every(function (childId, index) { return childId === previousState.orderedChildIds[index]; })) {
5822
+ return null;
5823
+ }
5824
+ var weightByChildId = new Map();
5825
+ previousState.orderedChildIds.forEach(function (childId, index) {
5826
+ var _a;
5827
+ weightByChildId.set(childId, _this.clampGridUnits((_a = previousState.slotWeights[index]) !== null && _a !== void 0 ? _a : GRID_ROW_UNITS));
5828
+ });
5829
+ var reorderedTemplate = orderedChildIds.map(function (childId) { var _a; return (_a = weightByChildId.get(childId)) !== null && _a !== void 0 ? _a : GRID_ROW_UNITS; });
5830
+ return __assign(__assign({}, parent.layout), { gridTemplate: reorderedTemplate });
5831
+ };
5832
+ AutoLayoutService.prototype.resolveGridChildResizeTopologyChange = function (parentId, childId, requestedWidth) {
5833
+ var _a;
5834
+ var parent = this.model.getElement(parentId);
5835
+ if (!parent || ((_a = parent.layout) === null || _a === void 0 ? void 0 : _a.mode) !== 'grid' || !parent.layout)
5836
+ return null;
5837
+ var slotState = this.resolveGridChildSlotState(parentId, childId);
5838
+ if (!slotState)
5839
+ return null;
5840
+ var assignedRows = slotState.assignedRows, orderedChildIds = slotState.orderedChildIds, slotWeights = slotState.slotWeights, childFlatIndex = slotState.childFlatIndex, rowIndex = slotState.rowIndex;
5841
+ var currentUnits = slotWeights[childFlatIndex];
5842
+ var requestedUnits = this.resolveRequestedGridUnits(parent, assignedRows[rowIndex], requestedWidth);
5843
+ if (requestedUnits === currentUnits)
5844
+ return null;
5845
+ var nextSlotWeights = __spreadArray([], slotWeights, true);
5846
+ nextSlotWeights[childFlatIndex] = requestedUnits;
5847
+ var nextRows = this.packGridRowsFromSlots(orderedChildIds, nextSlotWeights);
5848
+ var beforeRows = assignedRows.map(function (row) { return ({ childIds: __spreadArray([], row.childIds, true) }); });
5849
+ var afterRows = nextRows.map(function (row) { return ({ childIds: __spreadArray([], row.childIds, true) }); });
5850
+ var rowsChanged = !this.gridRowSnapshotsEqual(beforeRows, afterRows);
5851
+ var reason = requestedUnits < currentUnits && rowsChanged ? 'child-resize-split' : 'child-resize-redistribute';
5852
+ return {
5853
+ parentId: parentId,
5854
+ triggerChildId: childId,
5855
+ reason: reason,
5856
+ beforeRows: beforeRows,
5857
+ afterRows: afterRows,
5858
+ nextLayout: __assign(__assign({}, parent.layout), { gridTemplate: nextSlotWeights }),
5859
+ };
5860
+ };
5861
+ AutoLayoutService.prototype.snapGridChildRequestedWidth = function (parentId, childId, requestedWidth) {
5862
+ var _a, _b;
5863
+ var parent = this.model.getElement(parentId);
5864
+ if (!parent || ((_a = parent.layout) === null || _a === void 0 ? void 0 : _a.mode) !== 'grid' || !parent.layout)
5865
+ return requestedWidth;
5866
+ var slotState = this.resolveGridChildSlotState(parentId, childId);
5867
+ if (!slotState)
5868
+ return requestedWidth;
5869
+ var requestedUnits = this.resolveRequestedGridUnits(parent, slotState.assignedRows[slotState.rowIndex], requestedWidth);
5870
+ var rowUnitWidth = this.resolveGridRowUnitWidth(Math.max(0, parent.size.width - this.resolveLayoutPadding(parent.layout).x * 2), slotState.assignedRows[slotState.rowIndex].childIds.length, (_b = parent.layout.gap) !== null && _b !== void 0 ? _b : 12);
5871
+ return Math.max(1, Math.round(requestedUnits * rowUnitWidth));
5872
+ };
5873
+ AutoLayoutService.prototype.canGridChildGrowRightward = function (parentId, childId) {
5874
+ var _a;
5875
+ var parent = this.model.getElement(parentId);
5876
+ if (!parent || ((_a = parent.layout) === null || _a === void 0 ? void 0 : _a.mode) !== 'grid' || !parent.layout)
5877
+ return false;
5878
+ var orderedIds = this.resolveAssignedGridRows(parent).flatMap(function (row) { return row.childIds; });
5879
+ var childIndex = orderedIds.indexOf(childId);
5880
+ return childIndex >= 0 && childIndex < orderedIds.length - 1;
5881
+ };
5882
+ AutoLayoutService.prototype.applyAxisLayoutForParent = function (parentId, parent, children, axis, options) {
5765
5883
  var _a, _b;
5766
5884
  var _this = this;
5767
5885
  var _c, _d, _e, _f;
5768
- if (preserveParentSize === void 0) { preserveParentSize = false; }
5886
+ var preserveParentSize = Boolean(options === null || options === void 0 ? void 0 : options.preserveParentSize);
5887
+ var preserveParentWidth = preserveParentSize || Boolean(options === null || options === void 0 ? void 0 : options.preserveParentWidth);
5888
+ var preserveParentHeight = preserveParentSize || Boolean(options === null || options === void 0 ? void 0 : options.preserveParentHeight);
5769
5889
  var layout = parent.layout;
5770
5890
  var padding = this.resolveLayoutPadding(layout);
5771
5891
  var gap = (_c = layout === null || layout === void 0 ? void 0 : layout.gap) !== null && _c !== void 0 ? _c : 12;
@@ -5848,8 +5968,16 @@ var AutoLayoutService = /** @class */ (function () {
5848
5968
  }
5849
5969
  else {
5850
5970
  (_a = resolveParentSize(fittedSizes), newParentWidth = _a.width, newParentHeight = _a.height);
5971
+ if (preserveParentWidth)
5972
+ newParentWidth = preservedParentWidth;
5973
+ if (preserveParentHeight)
5974
+ newParentHeight = preservedParentHeight;
5851
5975
  fittedSizes = calculateFittedSizes(newParentWidth, newParentHeight);
5852
5976
  (_b = resolveParentSize(fittedSizes), newParentWidth = _b.width, newParentHeight = _b.height);
5977
+ if (preserveParentWidth)
5978
+ newParentWidth = preservedParentWidth;
5979
+ if (preserveParentHeight)
5980
+ newParentHeight = preservedParentHeight;
5853
5981
  }
5854
5982
  var availableWidth = Math.max(0, newParentWidth - padding.x * 2);
5855
5983
  var availableHeight = Math.max(0, newParentHeight - padding.y * 2 - labelReservedTopLane);
@@ -5884,10 +6012,12 @@ var AutoLayoutService = /** @class */ (function () {
5884
6012
  height: newParentHeight,
5885
6013
  });
5886
6014
  };
5887
- AutoLayoutService.prototype.applyGridLayoutForParent = function (parentId, parent, children, preserveParentSize) {
6015
+ AutoLayoutService.prototype.applyGridLayoutForParent = function (parentId, parent, children, options) {
5888
6016
  var _this = this;
5889
6017
  var _a, _b;
5890
- if (preserveParentSize === void 0) { preserveParentSize = false; }
6018
+ var preserveParentSize = Boolean(options === null || options === void 0 ? void 0 : options.preserveParentSize);
6019
+ var preserveParentWidth = preserveParentSize || Boolean(options === null || options === void 0 ? void 0 : options.preserveParentWidth);
6020
+ var preserveParentHeight = preserveParentSize || Boolean(options === null || options === void 0 ? void 0 : options.preserveParentHeight);
5891
6021
  var layout = parent.layout;
5892
6022
  var padding = this.resolveLayoutPadding(layout);
5893
6023
  var gap = (_a = layout === null || layout === void 0 ? void 0 : layout.gap) !== null && _a !== void 0 ? _a : 12;
@@ -5895,9 +6025,7 @@ var AutoLayoutService = /** @class */ (function () {
5895
6025
  var labelReservedTopLane = this.resolveLabelReservedTopLane(parentId, layout);
5896
6026
  var constraints = this.resolveChildSizeConstraints(layout);
5897
6027
  var autoResize = this.resolveAutoResizeMode(layout);
5898
- // Keep grid child ordering stable across resize/layout cycles.
5899
- // Grid slot assignment should not depend on transient child positions produced during drag.
5900
- var sorted = __spreadArray([], children, true);
6028
+ var sorted = this.sortGridChildrenForLayout(children);
5901
6029
  var templateRows = this.normalizeGridTemplate(layout === null || layout === void 0 ? void 0 : layout.gridTemplate);
5902
6030
  var assignedRows = this.assignChildrenToGridRows(sorted.map(function (child) { return child.id; }), templateRows);
5903
6031
  var rowMetrics = assignedRows.map(function (row) {
@@ -5912,20 +6040,33 @@ var AutoLayoutService = /** @class */ (function () {
5912
6040
  };
5913
6041
  });
5914
6042
  var rowHeight = clampedSizes.reduce(function (max, size) { return Math.max(max, size.height); }, 0);
5915
- var rowWidth = clampedSizes.reduce(function (sum, size) { return sum + size.width; }, 0) + Math.max(0, clampedSizes.length - 1) * gap;
6043
+ var totalGap = Math.max(0, clampedSizes.length - 1) * gap;
6044
+ var usedUnits = effectiveWeights.reduce(function (sum, weight) { return sum + _this.clampGridUnits(weight); }, 0);
6045
+ var requiredUnitWidth = effectiveWeights.reduce(function (max, weight, index) {
6046
+ var _a, _b;
6047
+ var slotUnits = Math.max(1, weight !== null && weight !== void 0 ? weight : 1);
6048
+ var width = (_b = (_a = clampedSizes[index]) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : 0;
6049
+ return Math.max(max, width / slotUnits);
6050
+ }, 0);
6051
+ var rowWidth = usedUnits >= GRID_ROW_UNITS
6052
+ ? autoResize === 'grow-shrink'
6053
+ ? Math.round(requiredUnitWidth * GRID_ROW_UNITS) + totalGap
6054
+ : clampedSizes.reduce(function (sum, size) { return sum + size.width; }, 0) + totalGap
6055
+ : Math.round(requiredUnitWidth * Math.max(1, usedUnits)) + totalGap;
5916
6056
  return {
5917
6057
  row: row,
5918
6058
  rowHeight: rowHeight,
5919
6059
  rowWidth: rowWidth,
6060
+ usedUnits: usedUnits,
5920
6061
  effectiveWeights: effectiveWeights,
5921
6062
  };
5922
6063
  });
5923
6064
  var requiredInnerWidth = rowMetrics.reduce(function (max, metric) { return Math.max(max, metric.rowWidth); }, 0);
5924
6065
  var requiredInnerHeight = rowMetrics.reduce(function (sum, metric) { return sum + metric.rowHeight; }, 0) + Math.max(0, rowMetrics.length - 1) * gap;
5925
- var newParentWidth = preserveParentSize
6066
+ var newParentWidth = preserveParentWidth
5926
6067
  ? Math.max(0, Math.round(parent.size.width))
5927
6068
  : this.resolveAutoResizedDimension(parent.size.width, padding.x * 2 + requiredInnerWidth, autoResize);
5928
- var newParentHeight = preserveParentSize
6069
+ var newParentHeight = preserveParentHeight
5929
6070
  ? Math.max(0, Math.round(parent.size.height))
5930
6071
  : this.resolveAutoResizedDimension(parent.size.height, padding.y * 2 + labelReservedTopLane + requiredInnerHeight, autoResize);
5931
6072
  var availableWidth = Math.max(0, newParentWidth - padding.x * 2);
@@ -5944,8 +6085,11 @@ var AutoLayoutService = /** @class */ (function () {
5944
6085
  if (childCount <= 0)
5945
6086
  return;
5946
6087
  var totalGap = Math.max(0, childCount - 1) * gap;
5947
- var rowInnerWidth = Math.max(0, availableWidth - totalGap);
5948
- var cellWidths = _this.distributeWeightedSizes(rowInnerWidth, metric.effectiveWeights);
6088
+ var rowOuterWidth = metric.usedUnits >= GRID_ROW_UNITS
6089
+ ? availableWidth
6090
+ : Math.min(availableWidth, metric.rowWidth);
6091
+ var rowInnerWidth = Math.max(0, rowOuterWidth - totalGap);
6092
+ var cellWidths = _this.resolveGridCellWidths(rowInnerWidth, metric.effectiveWeights);
5949
6093
  var rowHeight = metric.rowHeight;
5950
6094
  var cursorX = padding.x;
5951
6095
  metric.row.childIds.forEach(function (childId, index) {
@@ -5969,6 +6113,13 @@ var AutoLayoutService = /** @class */ (function () {
5969
6113
  height: newParentHeight,
5970
6114
  });
5971
6115
  };
6116
+ AutoLayoutService.prototype.resolveGridCellWidths = function (rowInnerWidth, weights) {
6117
+ var _this = this;
6118
+ if (weights.length === 0)
6119
+ return [];
6120
+ var safeWeights = weights.map(function (weight) { return _this.clampGridUnits(weight); });
6121
+ return this.distributeWeightedSizes(Math.max(0, rowInnerWidth), safeWeights);
6122
+ };
5972
6123
  AutoLayoutService.prototype.applyResolvedLayout = function (parentId, parent, desiredPositions, desiredSizes, parentSize) {
5973
6124
  var _this = this;
5974
6125
  var _a;
@@ -6031,43 +6182,96 @@ var AutoLayoutService = /** @class */ (function () {
6031
6182
  : Number.POSITIVE_INFINITY;
6032
6183
  return { minWidth: minWidth, maxWidth: maxWidth, minHeight: minHeight, maxHeight: maxHeight };
6033
6184
  };
6185
+ AutoLayoutService.prototype.resolveAssignedGridRows = function (parent) {
6186
+ var _a;
6187
+ var children = this.model.getChildren(parent.id);
6188
+ var sorted = this.sortGridChildrenForLayout(children);
6189
+ var templateRows = this.normalizeGridTemplate((_a = parent.layout) === null || _a === void 0 ? void 0 : _a.gridTemplate);
6190
+ return this.assignChildrenToGridRows(sorted.map(function (child) { return child.id; }), templateRows);
6191
+ };
6192
+ AutoLayoutService.prototype.repartitionAssignedGridRows = function (assignedRows, rowIndex, nextCurrentRowCount) {
6193
+ var _a, _b;
6194
+ var allChildIds = assignedRows.flatMap(function (row) { return row.childIds; });
6195
+ var prefixRows = assignedRows.slice(0, rowIndex).map(function (row) { return ({
6196
+ weights: __spreadArray([], row.weights.slice(0, row.childIds.length), true),
6197
+ childIds: __spreadArray([], row.childIds, true),
6198
+ }); });
6199
+ var prefixCount = prefixRows.reduce(function (sum, row) { return sum + row.childIds.length; }, 0);
6200
+ var nextRows = __spreadArray([], prefixRows, true);
6201
+ var currentChildIds = allChildIds.slice(prefixCount, prefixCount + nextCurrentRowCount);
6202
+ if (currentChildIds.length > 0) {
6203
+ nextRows.push({
6204
+ weights: this.fitGridRowWeights((_a = assignedRows[rowIndex]) === null || _a === void 0 ? void 0 : _a.weights, currentChildIds.length),
6205
+ childIds: currentChildIds,
6206
+ });
6207
+ }
6208
+ var cursor = prefixCount + currentChildIds.length;
6209
+ var trailingRowIndex = rowIndex + 1;
6210
+ while (cursor < allChildIds.length) {
6211
+ var sourceRow = assignedRows[Math.min(trailingRowIndex, assignedRows.length - 1)];
6212
+ var sourceCapacity = Math.max(1, (_b = sourceRow === null || sourceRow === void 0 ? void 0 : sourceRow.childIds.length) !== null && _b !== void 0 ? _b : 1);
6213
+ var rowChildIds = allChildIds.slice(cursor, cursor + sourceCapacity);
6214
+ nextRows.push({
6215
+ weights: this.fitGridRowWeights(sourceRow === null || sourceRow === void 0 ? void 0 : sourceRow.weights, rowChildIds.length),
6216
+ childIds: rowChildIds,
6217
+ });
6218
+ cursor += rowChildIds.length;
6219
+ trailingRowIndex += 1;
6220
+ }
6221
+ return nextRows;
6222
+ };
6223
+ AutoLayoutService.prototype.fitGridRowWeights = function (sourceWeights, childCount) {
6224
+ if (childCount <= 0)
6225
+ return [];
6226
+ var base = Array.isArray(sourceWeights) && sourceWeights.length > 0 ? sourceWeights : [1];
6227
+ var normalizedBase = this.normalizeRowWeightsToTwelveUnits(base);
6228
+ if (normalizedBase.length === childCount) {
6229
+ return normalizedBase;
6230
+ }
6231
+ if (normalizedBase.length > childCount) {
6232
+ return this.normalizeRowWeightsToTwelveUnits(normalizedBase.slice(0, childCount));
6233
+ }
6234
+ return this.buildEqualGridUnits(childCount);
6235
+ };
6236
+ AutoLayoutService.prototype.gridRowSnapshotsEqual = function (a, b) {
6237
+ var _a, _b, _c, _d;
6238
+ if (a.length !== b.length)
6239
+ return false;
6240
+ for (var index = 0; index < a.length; index += 1) {
6241
+ var left = (_b = (_a = a[index]) === null || _a === void 0 ? void 0 : _a.childIds) !== null && _b !== void 0 ? _b : [];
6242
+ var right = (_d = (_c = b[index]) === null || _c === void 0 ? void 0 : _c.childIds) !== null && _d !== void 0 ? _d : [];
6243
+ if (left.length !== right.length)
6244
+ return false;
6245
+ for (var childIndex = 0; childIndex < left.length; childIndex += 1) {
6246
+ if (left[childIndex] !== right[childIndex])
6247
+ return false;
6248
+ }
6249
+ }
6250
+ return true;
6251
+ };
6034
6252
  AutoLayoutService.prototype.normalizeGridTemplate = function (template) {
6253
+ var slots = this.normalizeGridSlotUnits(template);
6035
6254
  var rows = [];
6036
- (template !== null && template !== void 0 ? template : []).forEach(function (entry) {
6037
- if (typeof entry === 'number') {
6038
- var count = Math.max(0, Math.floor(entry));
6039
- if (count > 0) {
6040
- rows.push({ weights: Array.from({ length: count }, function () { return 1; }) });
6041
- }
6042
- return;
6043
- }
6044
- if (!Array.isArray(entry))
6045
- return;
6046
- if (entry.length === 1 && Number.isFinite(entry[0]) && entry[0] > 1) {
6047
- var count = Math.max(0, Math.floor(entry[0]));
6048
- if (count > 0) {
6049
- rows.push({ weights: Array.from({ length: count }, function () { return 1; }) });
6050
- }
6051
- return;
6052
- }
6053
- var weights = entry
6054
- .map(function (value) {
6055
- if (!Number.isFinite(value) || value <= 0)
6056
- return 1;
6057
- return value;
6058
- })
6059
- .filter(function (value) { return value > 0; });
6060
- if (weights.length > 0) {
6061
- rows.push({ weights: weights });
6255
+ var currentRow = [];
6256
+ var currentUnits = 0;
6257
+ slots.forEach(function (slotUnits) {
6258
+ if (currentRow.length > 0 && currentUnits + slotUnits > GRID_ROW_UNITS) {
6259
+ rows.push({ weights: __spreadArray([], currentRow, true) });
6260
+ currentRow = [];
6261
+ currentUnits = 0;
6062
6262
  }
6263
+ currentRow.push(slotUnits);
6264
+ currentUnits += slotUnits;
6063
6265
  });
6266
+ if (currentRow.length > 0) {
6267
+ rows.push({ weights: __spreadArray([], currentRow, true) });
6268
+ }
6064
6269
  if (rows.length === 0) {
6065
- rows.push({ weights: [1] });
6270
+ rows.push({ weights: [GRID_ROW_UNITS] });
6066
6271
  }
6067
6272
  return rows;
6068
6273
  };
6069
6274
  AutoLayoutService.prototype.assignChildrenToGridRows = function (childIds, templateRows) {
6070
- var _a;
6071
6275
  var assigned = [];
6072
6276
  var cursor = 0;
6073
6277
  templateRows.forEach(function (rowTemplate) {
@@ -6083,19 +6287,348 @@ var AutoLayoutService = /** @class */ (function () {
6083
6287
  cursor += rowChildren.length;
6084
6288
  });
6085
6289
  while (cursor < childIds.length) {
6086
- var remaining = childIds.length - cursor;
6087
- var lastRow = templateRows[templateRows.length - 1];
6088
- var fallbackColumns = (_a = lastRow === null || lastRow === void 0 ? void 0 : lastRow.weights.length) !== null && _a !== void 0 ? _a : 1;
6089
- var fallbackCount = Math.max(1, Math.min(remaining, fallbackColumns));
6090
- var rowChildren = childIds.slice(cursor, cursor + fallbackCount);
6290
+ var rowChildren = childIds.slice(cursor, cursor + 1);
6091
6291
  assigned.push({
6092
- weights: Array.from({ length: rowChildren.length }, function () { return 1; }),
6292
+ weights: [GRID_ROW_UNITS],
6093
6293
  childIds: rowChildren,
6094
6294
  });
6095
6295
  cursor += rowChildren.length;
6096
6296
  }
6097
6297
  return assigned;
6098
6298
  };
6299
+ AutoLayoutService.prototype.resolveGridChildSlotState = function (parentId, childId) {
6300
+ var _this = this;
6301
+ var _a;
6302
+ var parent = this.model.getElement(parentId);
6303
+ if (!parent || ((_a = parent.layout) === null || _a === void 0 ? void 0 : _a.mode) !== 'grid')
6304
+ return null;
6305
+ var assignedRows = this.resolveAssignedGridRows(parent);
6306
+ if (assignedRows.length === 0)
6307
+ return null;
6308
+ var orderedChildIds = assignedRows.flatMap(function (row) { return row.childIds; });
6309
+ var slotWeights = assignedRows.flatMap(function (row) { return row.weights.slice(0, row.childIds.length).map(function (weight) { return _this.clampGridUnits(weight); }); });
6310
+ var childFlatIndex = orderedChildIds.indexOf(childId);
6311
+ if (childFlatIndex < 0)
6312
+ return null;
6313
+ var rowIndex = assignedRows.findIndex(function (row) { return row.childIds.includes(childId); });
6314
+ if (rowIndex < 0)
6315
+ return null;
6316
+ return { assignedRows: assignedRows, orderedChildIds: orderedChildIds, slotWeights: slotWeights, childFlatIndex: childFlatIndex, rowIndex: rowIndex };
6317
+ };
6318
+ AutoLayoutService.prototype.packGridRowsFromSlots = function (childIds, slotWeights) {
6319
+ var _this = this;
6320
+ var rows = [];
6321
+ var currentChildIds = [];
6322
+ var currentWeights = [];
6323
+ var currentUnits = 0;
6324
+ childIds.forEach(function (childId, index) {
6325
+ var _a;
6326
+ var slotUnits = _this.clampGridUnits((_a = slotWeights[index]) !== null && _a !== void 0 ? _a : GRID_ROW_UNITS);
6327
+ if (currentChildIds.length > 0 && currentUnits + slotUnits > GRID_ROW_UNITS) {
6328
+ rows.push({ childIds: __spreadArray([], currentChildIds, true), weights: __spreadArray([], currentWeights, true) });
6329
+ currentChildIds = [];
6330
+ currentWeights = [];
6331
+ currentUnits = 0;
6332
+ }
6333
+ currentChildIds.push(childId);
6334
+ currentWeights.push(slotUnits);
6335
+ currentUnits += slotUnits;
6336
+ });
6337
+ if (currentChildIds.length > 0) {
6338
+ rows.push({ childIds: __spreadArray([], currentChildIds, true), weights: __spreadArray([], currentWeights, true) });
6339
+ }
6340
+ return rows;
6341
+ };
6342
+ AutoLayoutService.prototype.resolveRequestedGridUnits = function (parent, currentRow, requestedWidth) {
6343
+ var _a;
6344
+ if (!parent.layout || parent.layout.mode !== 'grid' || !currentRow)
6345
+ return GRID_ROW_UNITS;
6346
+ var rowUnitWidth = this.resolveGridRowUnitWidth(Math.max(0, parent.size.width - this.resolveLayoutPadding(parent.layout).x * 2), currentRow.childIds.length, (_a = parent.layout.gap) !== null && _a !== void 0 ? _a : 12);
6347
+ if (rowUnitWidth <= 0)
6348
+ return GRID_ROW_UNITS;
6349
+ return this.clampGridUnits(Math.round(requestedWidth / rowUnitWidth));
6350
+ };
6351
+ AutoLayoutService.prototype.sortGridChildrenForLayout = function (children) {
6352
+ return __spreadArray([], children, true).sort(function (a, b) {
6353
+ if (a.position.y === b.position.y) {
6354
+ if (a.position.x === b.position.x)
6355
+ return a.id.localeCompare(b.id);
6356
+ return a.position.x - b.position.x;
6357
+ }
6358
+ return a.position.y - b.position.y;
6359
+ });
6360
+ };
6361
+ AutoLayoutService.prototype.resolveRightwardGridOverflowChange = function (params) {
6362
+ var _a, _b;
6363
+ var assignedRows = params.assignedRows, rowIndex = params.rowIndex, childIndex = params.childIndex, requestedWidth = params.requestedWidth, availableWidth = params.availableWidth, gap = params.gap, parentLayout = params.parentLayout, parentId = params.parentId, childId = params.childId;
6364
+ var currentRow = assignedRows[rowIndex];
6365
+ if (!currentRow || childIndex < 0 || childIndex >= currentRow.childIds.length - 1)
6366
+ return null;
6367
+ var rowUnitWidth = this.resolveGridRowUnitWidth(availableWidth, currentRow.childIds.length, gap);
6368
+ if (rowUnitWidth <= 0)
6369
+ return null;
6370
+ var currentUnits = (_b = (_a = currentRow.weights[childIndex]) !== null && _a !== void 0 ? _a : this.normalizeRowWeightsToTwelveUnits(currentRow.weights)[childIndex]) !== null && _b !== void 0 ? _b : 1;
6371
+ var requestedUnits = this.clampLayoutSize(Math.round(requestedWidth / rowUnitWidth), currentUnits + 1, GRID_ROW_UNITS - 1);
6372
+ var leftWeights = currentRow.weights.slice(0, childIndex);
6373
+ var leftSum = leftWeights.reduce(function (sum, value) { return sum + value; }, 0);
6374
+ var rightWeights = currentRow.weights.slice(childIndex + 1);
6375
+ var rightIds = currentRow.childIds.slice(childIndex + 1);
6376
+ var followingRows = assignedRows.slice(rowIndex + 1);
6377
+ for (var retainCount = rightIds.length - 1; retainCount >= 0; retainCount -= 1) {
6378
+ var maxTargetUnits = GRID_ROW_UNITS - leftSum - retainCount;
6379
+ if (requestedUnits > maxTargetUnits)
6380
+ continue;
6381
+ var retainedIds = rightIds.slice(0, retainCount);
6382
+ var retainedWeights = rightWeights.slice(0, retainCount);
6383
+ var overflowIds = __spreadArray(__spreadArray([], rightIds.slice(retainCount), true), followingRows.flatMap(function (row) { return row.childIds; }), true);
6384
+ var remainingUnits = GRID_ROW_UNITS - leftSum - requestedUnits;
6385
+ var nextCurrentWeights = __spreadArray(__spreadArray(__spreadArray([], leftWeights, true), [
6386
+ requestedUnits
6387
+ ], false), this.distributeUnitsWithMinimums(remainingUnits, retainedWeights), true);
6388
+ var nextRows = assignedRows.slice(0, rowIndex).map(function (row) { return ({
6389
+ weights: __spreadArray([], row.weights, true),
6390
+ childIds: __spreadArray([], row.childIds, true),
6391
+ }); });
6392
+ nextRows.push({
6393
+ weights: nextCurrentWeights,
6394
+ childIds: __spreadArray(__spreadArray([], currentRow.childIds.slice(0, childIndex + 1), true), retainedIds, true),
6395
+ });
6396
+ var trailingRows = this.reflowTrailingGridRows(overflowIds, followingRows, currentRow.weights.length);
6397
+ var allRows = __spreadArray(__spreadArray([], nextRows, true), trailingRows, true);
6398
+ var beforeRows = assignedRows.map(function (row) { return ({ childIds: __spreadArray([], row.childIds, true) }); });
6399
+ var afterRows = allRows.map(function (row) { return ({ childIds: __spreadArray([], row.childIds, true) }); });
6400
+ if (this.gridRowSnapshotsEqual(beforeRows, afterRows) && this.gridWeightsEqual(assignedRows, allRows)) {
6401
+ return null;
6402
+ }
6403
+ return {
6404
+ parentId: parentId,
6405
+ triggerChildId: childId,
6406
+ reason: 'child-resize-redistribute',
6407
+ beforeRows: beforeRows,
6408
+ afterRows: afterRows,
6409
+ nextLayout: __assign(__assign({}, parentLayout), { gridTemplate: this.flattenAssignedRowsToGridTemplate(allRows) }),
6410
+ };
6411
+ }
6412
+ return null;
6413
+ };
6414
+ AutoLayoutService.prototype.resolveSameRowGridUnitResizeChange = function (params) {
6415
+ var _this = this;
6416
+ var _a, _b, _c, _d;
6417
+ var assignedRows = params.assignedRows, rowIndex = params.rowIndex, childIndex = params.childIndex, requestedWidth = params.requestedWidth, availableWidth = params.availableWidth, gap = params.gap, parentLayout = params.parentLayout, parentId = params.parentId, childId = params.childId;
6418
+ var currentRow = assignedRows[rowIndex];
6419
+ if (!currentRow || currentRow.childIds.length <= 1)
6420
+ return null;
6421
+ var donorIndices = Array.from({ length: Math.max(0, currentRow.childIds.length - childIndex - 1) }, function (_, index) { return childIndex + 1 + index; });
6422
+ if (donorIndices.length === 0)
6423
+ return null;
6424
+ var rowUnitWidth = this.resolveGridRowUnitWidth(availableWidth, currentRow.childIds.length, gap);
6425
+ if (rowUnitWidth <= 0)
6426
+ return null;
6427
+ var currentUnits = (_b = (_a = currentRow.weights[childIndex]) !== null && _a !== void 0 ? _a : this.normalizeRowWeightsToTwelveUnits(currentRow.weights)[childIndex]) !== null && _b !== void 0 ? _b : 1;
6428
+ var requestedUnits = this.clampLayoutSize(Math.round(requestedWidth / rowUnitWidth), 1, GRID_ROW_UNITS - 1);
6429
+ if (requestedUnits === currentUnits)
6430
+ return null;
6431
+ var nextWeights = __spreadArray([], currentRow.weights, true);
6432
+ var delta = requestedUnits - currentUnits;
6433
+ if (delta > 0) {
6434
+ for (var _i = 0, donorIndices_1 = donorIndices; _i < donorIndices_1.length; _i++) {
6435
+ var donorIndex = donorIndices_1[_i];
6436
+ if (delta <= 0)
6437
+ break;
6438
+ var donorCapacity = Math.max(0, ((_c = nextWeights[donorIndex]) !== null && _c !== void 0 ? _c : 1) - 1);
6439
+ var transfer = Math.min(delta, donorCapacity);
6440
+ nextWeights[donorIndex] -= transfer;
6441
+ nextWeights[childIndex] += transfer;
6442
+ delta -= transfer;
6443
+ }
6444
+ }
6445
+ else {
6446
+ var release = Math.abs(delta);
6447
+ for (var _e = 0, donorIndices_2 = donorIndices; _e < donorIndices_2.length; _e++) {
6448
+ var donorIndex = donorIndices_2[_e];
6449
+ if (release <= 0)
6450
+ break;
6451
+ var transfer = release;
6452
+ nextWeights[donorIndex] += transfer;
6453
+ nextWeights[childIndex] -= transfer;
6454
+ release -= transfer;
6455
+ }
6456
+ }
6457
+ if (delta > 0)
6458
+ return null;
6459
+ if (((_d = nextWeights[childIndex]) !== null && _d !== void 0 ? _d : currentUnits) === currentUnits)
6460
+ return null;
6461
+ var nextRows = assignedRows.map(function (row, index) {
6462
+ return index === rowIndex
6463
+ ? {
6464
+ weights: _this.normalizeRowWeightsToTwelveUnits(nextWeights),
6465
+ childIds: __spreadArray([], row.childIds, true),
6466
+ }
6467
+ : { weights: __spreadArray([], row.weights, true), childIds: __spreadArray([], row.childIds, true) };
6468
+ });
6469
+ return {
6470
+ parentId: parentId,
6471
+ triggerChildId: childId,
6472
+ reason: 'child-resize-redistribute',
6473
+ beforeRows: assignedRows.map(function (row) { return ({ childIds: __spreadArray([], row.childIds, true) }); }),
6474
+ afterRows: nextRows.map(function (row) { return ({ childIds: __spreadArray([], row.childIds, true) }); }),
6475
+ nextLayout: __assign(__assign({}, parentLayout), { gridTemplate: this.flattenAssignedRowsToGridTemplate(nextRows) }),
6476
+ };
6477
+ };
6478
+ AutoLayoutService.prototype.splitGridRowIntoTwelveUnits = function (assignedRows, rowIndex, childId, requestedWidth, availableWidth, gap) {
6479
+ var _a;
6480
+ var currentRow = assignedRows[rowIndex];
6481
+ var nextRow = assignedRows[rowIndex + 1];
6482
+ if (!currentRow || !nextRow || currentRow.childIds.length !== 1 || nextRow.childIds.length === 0) {
6483
+ return [];
6484
+ }
6485
+ var rowUnitWidth = this.resolveGridRowUnitWidth(availableWidth, 2, gap);
6486
+ var requestedUnits = this.clampLayoutSize(Math.round(requestedWidth / rowUnitWidth), 1, GRID_ROW_UNITS - 1);
6487
+ var nextRows = assignedRows.slice(0, rowIndex).map(function (row) { return ({
6488
+ weights: __spreadArray([], row.weights, true),
6489
+ childIds: __spreadArray([], row.childIds, true),
6490
+ }); });
6491
+ nextRows.push({
6492
+ weights: [requestedUnits, GRID_ROW_UNITS - requestedUnits],
6493
+ childIds: [childId, nextRow.childIds[0]],
6494
+ });
6495
+ var trailingRows = [];
6496
+ var remainingChildIds = __spreadArray(__spreadArray([], nextRow.childIds.slice(1), true), assignedRows.slice(rowIndex + 2).flatMap(function (row) { return row.childIds; }), true);
6497
+ var cursor = 0;
6498
+ var seedRows = assignedRows.slice(rowIndex + 1);
6499
+ var seedIndex = 0;
6500
+ while (cursor < remainingChildIds.length) {
6501
+ var seed = seedRows[Math.min(seedIndex, seedRows.length - 1)];
6502
+ var capacity = Math.max(1, (_a = seed === null || seed === void 0 ? void 0 : seed.childIds.length) !== null && _a !== void 0 ? _a : 1);
6503
+ var rowChildIds = remainingChildIds.slice(cursor, cursor + capacity);
6504
+ trailingRows.push({
6505
+ weights: this.fitGridRowWeights(seed === null || seed === void 0 ? void 0 : seed.weights, rowChildIds.length),
6506
+ childIds: rowChildIds,
6507
+ });
6508
+ cursor += rowChildIds.length;
6509
+ seedIndex += 1;
6510
+ }
6511
+ return __spreadArray(__spreadArray([], nextRows, true), trailingRows, true);
6512
+ };
6513
+ AutoLayoutService.prototype.reflowTrailingGridRows = function (childIds, seedRows, fallbackColumnCount) {
6514
+ var _a;
6515
+ if (childIds.length === 0)
6516
+ return [];
6517
+ var trailingRows = [];
6518
+ var cursor = 0;
6519
+ var seedIndex = 0;
6520
+ var normalizedSeedRows = seedRows.length > 0 ? seedRows : [{ weights: this.buildEqualGridUnits(Math.max(1, fallbackColumnCount)), childIds: [] }];
6521
+ while (cursor < childIds.length) {
6522
+ var seed = normalizedSeedRows[Math.min(seedIndex, normalizedSeedRows.length - 1)];
6523
+ var capacity = Math.max(1, (_a = seed === null || seed === void 0 ? void 0 : seed.weights.length) !== null && _a !== void 0 ? _a : fallbackColumnCount);
6524
+ var rowChildIds = childIds.slice(cursor, cursor + capacity);
6525
+ trailingRows.push({
6526
+ weights: this.fitGridRowWeights(seed === null || seed === void 0 ? void 0 : seed.weights, rowChildIds.length),
6527
+ childIds: rowChildIds,
6528
+ });
6529
+ cursor += rowChildIds.length;
6530
+ seedIndex += 1;
6531
+ }
6532
+ return trailingRows;
6533
+ };
6534
+ AutoLayoutService.prototype.flattenAssignedRowsToGridTemplate = function (rows) {
6535
+ var _this = this;
6536
+ return rows.flatMap(function (row) { return _this.normalizeRowWeightsToTwelveUnits(row.weights.slice(0, row.childIds.length)); });
6537
+ };
6538
+ AutoLayoutService.prototype.buildEqualGridUnits = function (count) {
6539
+ if (count <= 0)
6540
+ return [];
6541
+ var base = Math.floor(GRID_ROW_UNITS / count);
6542
+ var remainder = GRID_ROW_UNITS - base * count;
6543
+ return Array.from({ length: count }, function (_, index) { return base + (index < remainder ? 1 : 0); });
6544
+ };
6545
+ AutoLayoutService.prototype.normalizeRowWeightsToTwelveUnits = function (weights) {
6546
+ var safeWeights = weights.map(function (weight) { return (Number.isFinite(weight) && weight > 0 ? weight : 1); });
6547
+ if (safeWeights.length === 0)
6548
+ return [GRID_ROW_UNITS];
6549
+ if (safeWeights.length === 1)
6550
+ return [GRID_ROW_UNITS];
6551
+ var distributed = this.distributeWeightedSizes(GRID_ROW_UNITS, safeWeights);
6552
+ var normalized = distributed.map(function (value) { return Math.max(1, value); });
6553
+ var total = normalized.reduce(function (sum, value) { return sum + value; }, 0);
6554
+ if (total === GRID_ROW_UNITS)
6555
+ return normalized;
6556
+ if (total < GRID_ROW_UNITS) {
6557
+ var cursor_1 = 0;
6558
+ while (total < GRID_ROW_UNITS) {
6559
+ normalized[cursor_1 % normalized.length] += 1;
6560
+ total += 1;
6561
+ cursor_1 += 1;
6562
+ }
6563
+ return normalized;
6564
+ }
6565
+ var cursor = normalized.length - 1;
6566
+ while (total > GRID_ROW_UNITS && cursor >= 0) {
6567
+ if (normalized[cursor] > 1) {
6568
+ normalized[cursor] -= 1;
6569
+ total -= 1;
6570
+ }
6571
+ else {
6572
+ cursor -= 1;
6573
+ }
6574
+ if (cursor < 0 && total > GRID_ROW_UNITS) {
6575
+ cursor = normalized.length - 1;
6576
+ }
6577
+ }
6578
+ return normalized;
6579
+ };
6580
+ AutoLayoutService.prototype.normalizeGridSlotUnits = function (template) {
6581
+ var _this = this;
6582
+ var slots = [];
6583
+ (template !== null && template !== void 0 ? template : []).forEach(function (entry) {
6584
+ if (typeof entry === 'number') {
6585
+ if (Number.isFinite(entry) && entry > 0) {
6586
+ slots.push(_this.clampGridUnits(entry));
6587
+ }
6588
+ return;
6589
+ }
6590
+ if (!Array.isArray(entry))
6591
+ return;
6592
+ entry.forEach(function (value) {
6593
+ if (Number.isFinite(value) && value > 0) {
6594
+ slots.push(_this.clampGridUnits(value));
6595
+ }
6596
+ });
6597
+ });
6598
+ return slots;
6599
+ };
6600
+ AutoLayoutService.prototype.clampGridUnits = function (value) {
6601
+ return Math.max(1, Math.min(GRID_ROW_UNITS, Math.round(value)));
6602
+ };
6603
+ AutoLayoutService.prototype.distributeUnitsWithMinimums = function (totalUnits, seedWeights) {
6604
+ if (seedWeights.length === 0)
6605
+ return [];
6606
+ var minimumTotal = seedWeights.length;
6607
+ var clampedTotal = Math.max(minimumTotal, totalUnits);
6608
+ var distributed = this.distributeWeightedSizes(clampedTotal - minimumTotal, seedWeights).map(function (value) { return value + 1; });
6609
+ return distributed;
6610
+ };
6611
+ AutoLayoutService.prototype.gridWeightsEqual = function (leftRows, rightRows) {
6612
+ var _a, _b, _c, _d;
6613
+ if (leftRows.length !== rightRows.length)
6614
+ return false;
6615
+ for (var rowIndex = 0; rowIndex < leftRows.length; rowIndex += 1) {
6616
+ var left = (_b = (_a = leftRows[rowIndex]) === null || _a === void 0 ? void 0 : _a.weights) !== null && _b !== void 0 ? _b : [];
6617
+ var right = (_d = (_c = rightRows[rowIndex]) === null || _c === void 0 ? void 0 : _c.weights) !== null && _d !== void 0 ? _d : [];
6618
+ if (left.length !== right.length)
6619
+ return false;
6620
+ for (var index = 0; index < left.length; index += 1) {
6621
+ if (left[index] !== right[index])
6622
+ return false;
6623
+ }
6624
+ }
6625
+ return true;
6626
+ };
6627
+ AutoLayoutService.prototype.resolveGridRowUnitWidth = function (availableWidth, childCount, gap) {
6628
+ var totalGap = Math.max(0, childCount - 1) * gap;
6629
+ var rowInnerWidth = Math.max(0, availableWidth - totalGap);
6630
+ return rowInnerWidth / GRID_ROW_UNITS;
6631
+ };
6099
6632
  AutoLayoutService.prototype.resolveLabelReservedTopLane = function (parentId, layout) {
6100
6633
  var _a, _b, _c, _d;
6101
6634
  var policy = layout === null || layout === void 0 ? void 0 : layout.labelReservedSpace;
@@ -6630,11 +7163,18 @@ var LinkRoutingService = /** @class */ (function () {
6630
7163
  var onEdge = (shape === null || shape === void 0 ? void 0 : shape.projectToBorder)
6631
7164
  ? this.isPointOnProjectedBorder(point, rect, shape.projectToBorder, EDGE_TOLERANCE)
6632
7165
  : this.isPointOnRectEdge(point, rect, EDGE_TOLERANCE);
6633
- var onEdgeSide = onEdge ? (_b = (_a = shape === null || shape === void 0 ? void 0 : shape.resolveBorderSide) === null || _a === void 0 ? void 0 : _a.call(shape, point, rect)) !== null && _b !== void 0 ? _b : this.resolveEdgeSide(point, rect) : undefined;
7166
+ var projectedBorderPoint = (shape === null || shape === void 0 ? void 0 : shape.projectToBorder)
7167
+ ? shape.projectToBorder(point, rect)
7168
+ : projectPointToBoundary(point, rect, 'rect');
7169
+ var projectedBoundaryEquivalent = !onEdge && !this.isPointInsideRect(point, rect, EDGE_TOLERANCE);
7170
+ var sidePoint = projectedBoundaryEquivalent ? projectedBorderPoint : point;
7171
+ var onEdgeSide = onEdge || projectedBoundaryEquivalent
7172
+ ? (_b = (_a = shape === null || shape === void 0 ? void 0 : shape.resolveBorderSide) === null || _a === void 0 ? void 0 : _a.call(shape, sidePoint, rect)) !== null && _b !== void 0 ? _b : this.resolveEdgeSide(sidePoint, rect)
7173
+ : undefined;
6634
7174
  if (onEdgeSide && oppositePoint) {
6635
7175
  onEdgeSide = this.resolveCornerTieBreakSide(point, rect, oppositePoint, onEdgeSide);
6636
7176
  }
6637
- return { onEdge: onEdge, onEdgeSide: onEdgeSide };
7177
+ return { onEdge: onEdge || projectedBoundaryEquivalent, onEdgeSide: onEdgeSide };
6638
7178
  };
6639
7179
  LinkRoutingService.prototype.resolveCornerTieBreakSide = function (point, rect, oppositePoint, currentSide) {
6640
7180
  var onLeft = Math.abs(point.x - rect.x) <= EDGE_TOLERANCE;
@@ -6796,6 +7336,12 @@ var LinkRoutingService = /** @class */ (function () {
6796
7336
  var onBottom = Math.abs(point.y - (rect.y + rect.height)) <= tolerance;
6797
7337
  return onLeft || onRight || onTop || onBottom;
6798
7338
  };
7339
+ LinkRoutingService.prototype.isPointInsideRect = function (point, rect, tolerance) {
7340
+ return (point.x >= rect.x - tolerance &&
7341
+ point.x <= rect.x + rect.width + tolerance &&
7342
+ point.y >= rect.y - tolerance &&
7343
+ point.y <= rect.y + rect.height + tolerance);
7344
+ };
6799
7345
  LinkRoutingService.prototype.resolveEdgeSide = function (point, rect) {
6800
7346
  var distances = [
6801
7347
  { side: 'left', value: Math.abs(point.x - rect.x) },
@@ -6840,8 +7386,8 @@ var MutationPipeline = /** @class */ (function () {
6840
7386
  }());
6841
7387
 
6842
7388
  var clampToRect = function (point, rect) { return ({
6843
- x: clamp(point.x, rect.x, rect.x + rect.width),
6844
- y: clamp(point.y, rect.y, rect.y + rect.height),
7389
+ x: clamp$1(point.x, rect.x, rect.x + rect.width),
7390
+ y: clamp$1(point.y, rect.y, rect.y + rect.height),
6845
7391
  }); };
6846
7392
  var snapToRectBorder = function (point, rect) {
6847
7393
  var clamped = clampToRect(point, rect);
@@ -6978,9 +7524,7 @@ var DiagramEngine = /** @class */ (function () {
6978
7524
  });
6979
7525
  this.emitChange(allPatches);
6980
7526
  };
6981
- DiagramEngine.prototype.moveElementTo = function (id, x, y) {
6982
- var _this = this;
6983
- var oldWorld = this.model.getElementWorldPosition(id);
7527
+ DiagramEngine.prototype.resolveElementMovePosition = function (id, x, y) {
6984
7528
  var snapped = this.snapper.snap({ x: x, y: y });
6985
7529
  var element = this.model.getElement(id);
6986
7530
  var position = snapped;
@@ -7020,14 +7564,46 @@ var DiagramEngine = /** @class */ (function () {
7020
7564
  }
7021
7565
  }
7022
7566
  }
7567
+ return { element: element === null || element === void 0 ? void 0 : element.toData(), position: position };
7568
+ };
7569
+ DiagramEngine.prototype.buildChildMutationLayoutSteps = function (parentId, options) {
7570
+ var _this = this;
7571
+ var _a;
7572
+ if (!parentId) {
7573
+ return [function () { return _this.applyLayoutCascade(null); }];
7574
+ }
7575
+ var parent = this.model.getElement(parentId);
7576
+ if ((options === null || options === void 0 ? void 0 : options.preserveGridParentWidth) && ((_a = parent === null || parent === void 0 ? void 0 : parent.layout) === null || _a === void 0 ? void 0 : _a.mode) === 'grid') {
7577
+ return [
7578
+ function () { return _this.applyLayoutForParent(parentId, { preserveParentWidth: true }); },
7579
+ function () { var _a; return _this.applyLayoutCascade((_a = parent.parentId) !== null && _a !== void 0 ? _a : null); },
7580
+ ];
7581
+ }
7582
+ return [function () { return _this.applyLayoutCascade(parentId); }];
7583
+ };
7584
+ DiagramEngine.prototype.moveElementTo = function (id, x, y) {
7585
+ var _a;
7586
+ var oldWorld = this.model.getElementWorldPosition(id);
7587
+ var _b = this.resolveElementMovePosition(id, x, y), element = _b.element, position = _b.position;
7588
+ var beforeGridSlotState = (element === null || element === void 0 ? void 0 : element.parentId)
7589
+ ? this.autoLayoutService.describeGridSlotState(element.parentId)
7590
+ : null;
7023
7591
  var patches = this.commandQueue.run(createMoveElementCommand(id, position), this.model);
7592
+ if ((element === null || element === void 0 ? void 0 : element.parentId) && beforeGridSlotState) {
7593
+ var reorderedLayout = this.autoLayoutService.resolveGridReorderedLayout(element.parentId, beforeGridSlotState);
7594
+ if (reorderedLayout) {
7595
+ patches.push.apply(patches, this.commandQueue.run(createSetElementLayoutCommand(element.parentId, reorderedLayout), this.model));
7596
+ }
7597
+ }
7024
7598
  var movedPortIds = [];
7025
7599
  if (element) {
7026
7600
  movedPortIds.push.apply(movedPortIds, this.collectElementPortIds(element.id));
7027
7601
  }
7028
7602
  var allPatches = this.mutationPipeline.run({
7029
7603
  basePatches: patches,
7030
- layoutSteps: [function () { var _a; return _this.applyLayoutCascade((_a = element === null || element === void 0 ? void 0 : element.parentId) !== null && _a !== void 0 ? _a : null); }],
7604
+ layoutSteps: this.buildChildMutationLayoutSteps((_a = element === null || element === void 0 ? void 0 : element.parentId) !== null && _a !== void 0 ? _a : null, {
7605
+ preserveGridParentWidth: true,
7606
+ }),
7031
7607
  movedPortIds: movedPortIds,
7032
7608
  });
7033
7609
  this.emitChange(allPatches);
@@ -7044,24 +7620,106 @@ var DiagramEngine = /** @class */ (function () {
7044
7620
  }
7045
7621
  }
7046
7622
  };
7623
+ DiagramEngine.prototype.resizeElementBounds = function (id, bounds) {
7624
+ var _this = this;
7625
+ var _a, _b, _c, _d;
7626
+ var _e = this.resolveElementMovePosition(id, bounds.x, bounds.y), element = _e.element, position = _e.position;
7627
+ if (!element)
7628
+ return;
7629
+ var oldSize = __assign({}, element.size);
7630
+ var preserveParentSize = Boolean(element.layout && element.layout.mode !== 'manual');
7631
+ var gridLayoutChange = this.resolveGridChildWidthResizeTopologyChange(element, bounds.width);
7632
+ var patches = [];
7633
+ if (gridLayoutChange) {
7634
+ patches.push.apply(patches, this.commandQueue.run(createSetElementLayoutCommand(gridLayoutChange.parentId, gridLayoutChange.afterLayout), this.model));
7635
+ }
7636
+ var positionChanged = element.position.x !== position.x || element.position.y !== position.y;
7637
+ if (positionChanged) {
7638
+ patches.push.apply(patches, this.commandQueue.run(createMoveElementCommand(id, position), this.model));
7639
+ }
7640
+ patches.push.apply(patches, this.commandQueue.run(createResizeElementCommand(id, { width: bounds.width, height: bounds.height }), this.model));
7641
+ var movedPortIds = this.collectElementPortIds(element.id);
7642
+ var layoutSteps = [function () { return _this.applyLayoutForParent(id, { preserveParentSize: preserveParentSize }); }];
7643
+ if (gridLayoutChange && element.parentId) {
7644
+ var grandParentId_1 = (_b = (_a = this.model.getElement(element.parentId)) === null || _a === void 0 ? void 0 : _a.parentId) !== null && _b !== void 0 ? _b : null;
7645
+ layoutSteps.push(function () { var _a; return _this.applyLayoutForParent((_a = element.parentId) !== null && _a !== void 0 ? _a : '', { preserveParentWidth: true }); });
7646
+ if (grandParentId_1) {
7647
+ layoutSteps.push(function () { return _this.applyLayoutCascade(grandParentId_1); });
7648
+ }
7649
+ }
7650
+ else {
7651
+ layoutSteps.push.apply(layoutSteps, this.buildChildMutationLayoutSteps((_c = element.parentId) !== null && _c !== void 0 ? _c : null, {
7652
+ preserveGridParentWidth: true,
7653
+ }));
7654
+ }
7655
+ var allPatches = this.mutationPipeline.run({
7656
+ basePatches: patches,
7657
+ layoutSteps: layoutSteps,
7658
+ movedPortIds: movedPortIds,
7659
+ });
7660
+ if (gridLayoutChange) {
7661
+ this.events.emit('gridLayoutChanged', {
7662
+ parentId: gridLayoutChange.parentId,
7663
+ triggerChildId: gridLayoutChange.triggerChildId,
7664
+ reason: gridLayoutChange.reason,
7665
+ beforeRows: gridLayoutChange.beforeRows,
7666
+ afterRows: gridLayoutChange.afterRows,
7667
+ beforeGridTemplate: gridLayoutChange.beforeGridTemplate,
7668
+ afterGridTemplate: gridLayoutChange.afterGridTemplate,
7669
+ });
7670
+ }
7671
+ this.emitChange(allPatches);
7672
+ var newSize = (_d = this.model.getElement(id)) === null || _d === void 0 ? void 0 : _d.size;
7673
+ if (newSize && (oldSize.width !== newSize.width || oldSize.height !== newSize.height)) {
7674
+ this.events.emit('elementResized', { elementId: id, oldSize: oldSize, newSize: __assign({}, newSize) });
7675
+ }
7676
+ };
7047
7677
  DiagramEngine.prototype.resizeElement = function (id, width, height) {
7048
7678
  var _this = this;
7049
- var _a;
7679
+ var _a, _b, _c, _d;
7050
7680
  var element = this.model.getElement(id);
7051
7681
  var oldSize = element === null || element === void 0 ? void 0 : element.size;
7052
7682
  var preserveParentSize = Boolean((element === null || element === void 0 ? void 0 : element.layout) && element.layout.mode !== 'manual');
7053
- var patches = this.commandQueue.run(createResizeElementCommand(id, { width: width, height: height }), this.model);
7683
+ var gridLayoutChange = element
7684
+ ? this.resolveGridChildWidthResizeTopologyChange(element, width)
7685
+ : null;
7686
+ var patches = [];
7687
+ if (gridLayoutChange) {
7688
+ patches.push.apply(patches, this.commandQueue.run(createSetElementLayoutCommand(gridLayoutChange.parentId, gridLayoutChange.afterLayout), this.model));
7689
+ }
7690
+ patches.push.apply(patches, this.commandQueue.run(createResizeElementCommand(id, { width: width, height: height }), this.model));
7054
7691
  var movedPortIds = element ? this.collectElementPortIds(element.id) : [];
7692
+ var layoutSteps = [function () { return _this.applyLayoutForParent(id, { preserveParentSize: preserveParentSize }); }];
7693
+ if (gridLayoutChange && (element === null || element === void 0 ? void 0 : element.parentId)) {
7694
+ var grandParentId_2 = (_b = (_a = this.model.getElement(element.parentId)) === null || _a === void 0 ? void 0 : _a.parentId) !== null && _b !== void 0 ? _b : null;
7695
+ layoutSteps.push(function () { var _a; return _this.applyLayoutForParent((_a = element.parentId) !== null && _a !== void 0 ? _a : '', { preserveParentWidth: true }); });
7696
+ if (grandParentId_2) {
7697
+ layoutSteps.push(function () { return _this.applyLayoutCascade(grandParentId_2); });
7698
+ }
7699
+ }
7700
+ else {
7701
+ layoutSteps.push.apply(layoutSteps, this.buildChildMutationLayoutSteps((_c = element === null || element === void 0 ? void 0 : element.parentId) !== null && _c !== void 0 ? _c : null, {
7702
+ preserveGridParentWidth: true,
7703
+ }));
7704
+ }
7055
7705
  var allPatches = this.mutationPipeline.run({
7056
7706
  basePatches: patches,
7057
- layoutSteps: [
7058
- function () { return _this.applyLayoutForParent(id, { preserveParentSize: preserveParentSize }); },
7059
- function () { var _a; return _this.applyLayoutCascade((_a = element === null || element === void 0 ? void 0 : element.parentId) !== null && _a !== void 0 ? _a : null); },
7060
- ],
7707
+ layoutSteps: layoutSteps,
7061
7708
  movedPortIds: movedPortIds,
7062
7709
  });
7710
+ if (gridLayoutChange) {
7711
+ this.events.emit('gridLayoutChanged', {
7712
+ parentId: gridLayoutChange.parentId,
7713
+ triggerChildId: gridLayoutChange.triggerChildId,
7714
+ reason: gridLayoutChange.reason,
7715
+ beforeRows: gridLayoutChange.beforeRows,
7716
+ afterRows: gridLayoutChange.afterRows,
7717
+ beforeGridTemplate: gridLayoutChange.beforeGridTemplate,
7718
+ afterGridTemplate: gridLayoutChange.afterGridTemplate,
7719
+ });
7720
+ }
7063
7721
  this.emitChange(allPatches);
7064
- var newSize = (_a = this.model.getElement(id)) === null || _a === void 0 ? void 0 : _a.size;
7722
+ var newSize = (_d = this.model.getElement(id)) === null || _d === void 0 ? void 0 : _d.size;
7065
7723
  if (oldSize && newSize && (oldSize.width !== newSize.width || oldSize.height !== newSize.height)) {
7066
7724
  this.events.emit('elementResized', { elementId: id, oldSize: __assign({}, oldSize), newSize: __assign({}, newSize) });
7067
7725
  }
@@ -7366,6 +8024,7 @@ var DiagramEngine = /** @class */ (function () {
7366
8024
  return baseRotation + instanceRotation;
7367
8025
  };
7368
8026
  DiagramEngine.prototype.normalizeElementResize = function (id, proposal, handle, minSize) {
8027
+ var _a, _b;
7369
8028
  if (minSize === void 0) { minSize = 20; }
7370
8029
  var clamped = {
7371
8030
  x: proposal.x,
@@ -7377,13 +8036,19 @@ var DiagramEngine = /** @class */ (function () {
7377
8036
  if (!element)
7378
8037
  return clamped;
7379
8038
  var lockHorizontalResize = this.shouldLockAutoLayoutChildHorizontalResize(element);
8039
+ var currentWorldPosition = this.model.getElementWorldPosition(id);
8040
+ var anchorGridWidthToLeft = this.shouldAnchorAutoLayoutGridChildWidthToLeft(element);
8041
+ var freezeGridLeftEdge = anchorGridWidthToLeft || lockHorizontalResize;
8042
+ var snappedGridWidth = this.resolveSnappedGridChildWidth(element, clamped.width);
7380
8043
  var shape = this.shapeRegistry.get(element.shapeId);
7381
8044
  if (!(shape === null || shape === void 0 ? void 0 : shape.normalizeResize)) {
7382
- if (!lockHorizontalResize)
8045
+ if (!lockHorizontalResize && !anchorGridWidthToLeft)
7383
8046
  return clamped;
7384
- var width_1 = Math.max(minSize, element.size.width);
7385
- var x_1 = clamped.x;
7386
- if (handle === 'sw' || handle === 'nw') {
8047
+ var width_1 = lockHorizontalResize
8048
+ ? Math.max(minSize, element.size.width)
8049
+ : Math.max(minSize, snappedGridWidth);
8050
+ var x_1 = freezeGridLeftEdge ? ((_a = currentWorldPosition === null || currentWorldPosition === void 0 ? void 0 : currentWorldPosition.x) !== null && _a !== void 0 ? _a : clamped.x) : clamped.x;
8051
+ if (!freezeGridLeftEdge && (handle === 'sw' || handle === 'nw')) {
7387
8052
  x_1 += clamped.width - width_1;
7388
8053
  }
7389
8054
  return { x: x_1, y: clamped.y, width: width_1, height: clamped.height };
@@ -7394,11 +8059,15 @@ var DiagramEngine = /** @class */ (function () {
7394
8059
  minSize: minSize,
7395
8060
  proposal: { width: clamped.width, height: clamped.height },
7396
8061
  });
7397
- var width = lockHorizontalResize ? Math.max(minSize, element.size.width) : Math.max(minSize, normalized.width);
8062
+ var width = lockHorizontalResize
8063
+ ? Math.max(minSize, element.size.width)
8064
+ : anchorGridWidthToLeft
8065
+ ? Math.max(minSize, snappedGridWidth)
8066
+ : Math.max(minSize, normalized.width);
7398
8067
  var height = Math.max(minSize, normalized.height);
7399
- var x = clamped.x;
8068
+ var x = freezeGridLeftEdge ? ((_b = currentWorldPosition === null || currentWorldPosition === void 0 ? void 0 : currentWorldPosition.x) !== null && _b !== void 0 ? _b : clamped.x) : clamped.x;
7400
8069
  var y = clamped.y;
7401
- if (handle === 'sw' || handle === 'nw') {
8070
+ if (!freezeGridLeftEdge && (handle === 'sw' || handle === 'nw')) {
7402
8071
  x += clamped.width - width;
7403
8072
  }
7404
8073
  if (handle === 'ne' || handle === 'nw') {
@@ -7416,7 +8085,64 @@ var DiagramEngine = /** @class */ (function () {
7416
8085
  if (element.layout && element.layout.mode !== 'manual')
7417
8086
  return false;
7418
8087
  var parent = this.model.getElement(parentId);
7419
- return ((_b = parent === null || parent === void 0 ? void 0 : parent.layout) === null || _b === void 0 ? void 0 : _b.mode) === 'grid';
8088
+ if (((_b = parent === null || parent === void 0 ? void 0 : parent.layout) === null || _b === void 0 ? void 0 : _b.mode) !== 'grid')
8089
+ return false;
8090
+ return !Boolean(parent.layout.gridChildWidthResizeEnabled);
8091
+ };
8092
+ DiagramEngine.prototype.shouldAnchorAutoLayoutGridChildWidthToLeft = function (element) {
8093
+ var _a, _b;
8094
+ var parentId = (_a = element.parentId) !== null && _a !== void 0 ? _a : null;
8095
+ if (!parentId)
8096
+ return false;
8097
+ if (this.model.getChildren(element.id).length > 0)
8098
+ return false;
8099
+ if (element.layout && element.layout.mode !== 'manual')
8100
+ return false;
8101
+ var parent = this.model.getElement(parentId);
8102
+ return Boolean(((_b = parent === null || parent === void 0 ? void 0 : parent.layout) === null || _b === void 0 ? void 0 : _b.mode) === 'grid' && parent.layout.gridChildWidthResizeEnabled);
8103
+ };
8104
+ DiagramEngine.prototype.shouldRestrictAutoLayoutChildRightGrowth = function (element, handle, requestedWidth) {
8105
+ return false;
8106
+ };
8107
+ DiagramEngine.prototype.resolveSnappedGridChildWidth = function (element, requestedWidth) {
8108
+ var _a;
8109
+ var parentId = (_a = element.parentId) !== null && _a !== void 0 ? _a : null;
8110
+ if (!parentId)
8111
+ return requestedWidth;
8112
+ if (this.model.getChildren(element.id).length > 0)
8113
+ return requestedWidth;
8114
+ if (element.layout && element.layout.mode !== 'manual')
8115
+ return requestedWidth;
8116
+ var parent = this.model.getElement(parentId);
8117
+ if (!(parent === null || parent === void 0 ? void 0 : parent.layout) || parent.layout.mode !== 'grid' || !parent.layout.gridChildWidthResizeEnabled)
8118
+ return requestedWidth;
8119
+ return this.autoLayoutService.snapGridChildRequestedWidth(parentId, element.id, requestedWidth);
8120
+ };
8121
+ DiagramEngine.prototype.resolveGridChildWidthResizeTopologyChange = function (element, requestedWidth) {
8122
+ var _a, _b, _c;
8123
+ var parentId = (_a = element.parentId) !== null && _a !== void 0 ? _a : null;
8124
+ if (!parentId)
8125
+ return null;
8126
+ if (this.model.getChildren(element.id).length > 0)
8127
+ return null;
8128
+ if (element.layout && element.layout.mode !== 'manual')
8129
+ return null;
8130
+ var parent = this.model.getElement(parentId);
8131
+ if (!parent || ((_b = parent.layout) === null || _b === void 0 ? void 0 : _b.mode) !== 'grid' || !parent.layout.gridChildWidthResizeEnabled)
8132
+ return null;
8133
+ var topologyChange = this.autoLayoutService.resolveGridChildResizeTopologyChange(parentId, element.id, requestedWidth);
8134
+ if (!topologyChange)
8135
+ return null;
8136
+ return {
8137
+ parentId: topologyChange.parentId,
8138
+ triggerChildId: topologyChange.triggerChildId,
8139
+ reason: topologyChange.reason,
8140
+ beforeRows: topologyChange.beforeRows,
8141
+ afterRows: topologyChange.afterRows,
8142
+ beforeGridTemplate: parent.layout.gridTemplate ? __spreadArray([], parent.layout.gridTemplate, true) : undefined,
8143
+ afterGridTemplate: __spreadArray([], ((_c = topologyChange.nextLayout.gridTemplate) !== null && _c !== void 0 ? _c : []), true),
8144
+ afterLayout: topologyChange.nextLayout,
8145
+ };
7420
8146
  };
7421
8147
  DiagramEngine.prototype.getPortWorldPosition = function (id) {
7422
8148
  return this.model.getPortWorldPosition(id);
@@ -7699,8 +8425,8 @@ var DiagramEngine = /** @class */ (function () {
7699
8425
  }
7700
8426
  if (style === null || style === void 0 ? void 0 : style.moveBounds) {
7701
8427
  var bounds = style.moveBounds;
7702
- position.x = clamp(position.x, bounds.x, bounds.x + bounds.width);
7703
- position.y = clamp(position.y, bounds.y, bounds.y + bounds.height);
8428
+ position.x = clamp$1(position.x, bounds.x, bounds.x + bounds.width);
8429
+ position.y = clamp$1(position.y, bounds.y, bounds.y + bounds.height);
7704
8430
  }
7705
8431
  if (effectiveMoveMode === 'border') {
7706
8432
  var resolvedBorder = this.resolveBorderPositionWithLimits(position, element, (_e = element.portMovement) === null || _e === void 0 ? void 0 : _e.positionLimits);
@@ -9575,6 +10301,10 @@ var KonvaInteraction = /** @class */ (function () {
9575
10301
  return;
9576
10302
  }
9577
10303
  if (hit.type === 'text') {
10304
+ if (!_this.isTextMovable(hit.id)) {
10305
+ _this.setCursor('default');
10306
+ return;
10307
+ }
9578
10308
  var base = _this.engine.getTextWorldPosition(hit.id);
9579
10309
  if (base) {
9580
10310
  _this.dragState = {
@@ -9964,6 +10694,8 @@ var KonvaInteraction = /** @class */ (function () {
9964
10694
  var hit = _this.resolveHit(point);
9965
10695
  if (!hit || hit.type !== 'text')
9966
10696
  return;
10697
+ if (!_this.isTextEditable(hit.id))
10698
+ return;
9967
10699
  _this.startTextEdit(hit.id);
9968
10700
  };
9969
10701
  this.stage.on('dblclick dbltap', doubleClick);
@@ -11116,8 +11848,12 @@ var KonvaInteraction = /** @class */ (function () {
11116
11848
  y: normalized.y + normalized.height / 2,
11117
11849
  }
11118
11850
  : { x: normalized.x, y: normalized.y };
11119
- this.engine.moveElementTo(state.elementId, moveTarget.x, moveTarget.y);
11120
- this.engine.resizeElement(state.elementId, normalized.width, normalized.height);
11851
+ this.engine.resizeElementBounds(state.elementId, {
11852
+ x: moveTarget.x,
11853
+ y: moveTarget.y,
11854
+ width: normalized.width,
11855
+ height: normalized.height,
11856
+ });
11121
11857
  this.updateSelectionOverlays();
11122
11858
  };
11123
11859
  KonvaInteraction.prototype.parseResizeHandle = function (id) {
@@ -11453,6 +12189,14 @@ var KonvaInteraction = /** @class */ (function () {
11453
12189
  KonvaInteraction.prototype.getTextById = function (id) {
11454
12190
  return this.engine.getState().texts.find(function (text) { return text.id === id; });
11455
12191
  };
12192
+ KonvaInteraction.prototype.isTextMovable = function (id) {
12193
+ var _a, _b;
12194
+ return ((_b = (_a = this.getTextById(id)) === null || _a === void 0 ? void 0 : _a.interaction) === null || _b === void 0 ? void 0 : _b.movable) !== false;
12195
+ };
12196
+ KonvaInteraction.prototype.isTextEditable = function (id) {
12197
+ var _a, _b;
12198
+ return ((_b = (_a = this.getTextById(id)) === null || _a === void 0 ? void 0 : _a.interaction) === null || _b === void 0 ? void 0 : _b.editable) !== false;
12199
+ };
11456
12200
  KonvaInteraction.prototype.getLinkById = function (id) {
11457
12201
  return this.engine.getState().links.find(function (link) { return link.id === id; });
11458
12202
  };
@@ -12135,6 +12879,24 @@ var hasBounds = function (bounds) {
12135
12879
  bounds.maxX >= bounds.minX &&
12136
12880
  bounds.maxY >= bounds.minY;
12137
12881
  };
12882
+ var DEFAULT_VIEWPORT_FIT_PADDING = 24;
12883
+ var DEFAULT_VIEWPORT_FIT_MIN_ZOOM = 0.2;
12884
+ var DEFAULT_VIEWPORT_FIT_MAX_ZOOM = 3;
12885
+ var resolveViewportFitOptions = function (options) {
12886
+ var padding = typeof (options === null || options === void 0 ? void 0 : options.padding) === 'number' && Number.isFinite(options.padding)
12887
+ ? Math.max(0, options.padding)
12888
+ : DEFAULT_VIEWPORT_FIT_PADDING;
12889
+ var requestedMinZoom = typeof (options === null || options === void 0 ? void 0 : options.minZoom) === 'number' && Number.isFinite(options.minZoom)
12890
+ ? Math.max(0.000001, options.minZoom)
12891
+ : DEFAULT_VIEWPORT_FIT_MIN_ZOOM;
12892
+ var requestedMaxZoom = typeof (options === null || options === void 0 ? void 0 : options.maxZoom) === 'number' && Number.isFinite(options.maxZoom)
12893
+ ? Math.max(0.000001, options.maxZoom)
12894
+ : DEFAULT_VIEWPORT_FIT_MAX_ZOOM;
12895
+ var minZoom = Math.min(requestedMinZoom, requestedMaxZoom);
12896
+ var maxZoom = Math.max(requestedMinZoom, requestedMaxZoom);
12897
+ return { padding: padding, minZoom: minZoom, maxZoom: maxZoom };
12898
+ };
12899
+ var clamp = function (value, min, max) { return Math.max(min, Math.min(max, value)); };
12138
12900
  var resolveStateWorldBounds = function (state) {
12139
12901
  var bounds = createBounds();
12140
12902
  state.elements.forEach(function (element) {
@@ -12171,6 +12933,34 @@ var resolveStateWorldBounds = function (state) {
12171
12933
  });
12172
12934
  return hasBounds(bounds) ? bounds : null;
12173
12935
  };
12936
+ var resolveElementWorldBounds = function (state) {
12937
+ var bounds = createBounds();
12938
+ state.elements.forEach(function (element) {
12939
+ includeRect(bounds, element.position.x, element.position.y, element.size.width, element.size.height);
12940
+ });
12941
+ return hasBounds(bounds) ? bounds : null;
12942
+ };
12943
+ var resolveViewportFitTransform = function (state, viewportSize, options) {
12944
+ var bounds = resolveElementWorldBounds(state);
12945
+ if (!bounds)
12946
+ return null;
12947
+ var safeWidth = Math.max(1, viewportSize.width);
12948
+ var safeHeight = Math.max(1, viewportSize.height);
12949
+ var _a = resolveViewportFitOptions(options), padding = _a.padding, minZoom = _a.minZoom, maxZoom = _a.maxZoom;
12950
+ var availableWidth = Math.max(1, safeWidth - padding * 2);
12951
+ var availableHeight = Math.max(1, safeHeight - padding * 2);
12952
+ var contentWidth = Math.max(1, bounds.maxX - bounds.minX);
12953
+ var contentHeight = Math.max(1, bounds.maxY - bounds.minY);
12954
+ var rawZoom = Math.min(availableWidth / contentWidth, availableHeight / contentHeight);
12955
+ var zoom = clamp(rawZoom, minZoom, maxZoom);
12956
+ var centerX = (bounds.minX + bounds.maxX) / 2;
12957
+ var centerY = (bounds.minY + bounds.maxY) / 2;
12958
+ var pan = {
12959
+ x: safeWidth / 2 - centerX * zoom,
12960
+ y: safeHeight / 2 - centerY * zoom,
12961
+ };
12962
+ return { pan: pan, zoom: zoom };
12963
+ };
12174
12964
  var resolveFitToContentPadding = function (fitToContent) {
12175
12965
  if (typeof fitToContent === 'object' && typeof fitToContent.padding === 'number') {
12176
12966
  return Math.max(0, fitToContent.padding);
@@ -12246,10 +13036,12 @@ var registerSimpleShapes = function (registry, shapes, isPort) {
12246
13036
  var createDiagramEditor = function (config) {
12247
13037
  var _a, _b;
12248
13038
  var Konva = getKonva();
13039
+ var stageWidth = (_a = config.width) !== null && _a !== void 0 ? _a : 900;
13040
+ var stageHeight = (_b = config.height) !== null && _b !== void 0 ? _b : 560;
12249
13041
  var stage = new Konva.Stage({
12250
13042
  container: config.container,
12251
- width: (_a = config.width) !== null && _a !== void 0 ? _a : 900,
12252
- height: (_b = config.height) !== null && _b !== void 0 ? _b : 560,
13043
+ width: stageWidth,
13044
+ height: stageHeight,
12253
13045
  });
12254
13046
  var stageContainer = typeof stage.container === 'function' ? stage.container() : stage.container;
12255
13047
  if (stageContainer && stageContainer.tabIndex < 0) {
@@ -12396,6 +13188,12 @@ var createDiagramEditor = function (config) {
12396
13188
  completeLinkToPort: function (targetPortId) { return interaction.completeLinkToPort(targetPortId); },
12397
13189
  completeLinkToElement: function (targetElementId, pointer) { return interaction.completeLinkToElement(targetElementId, pointer); },
12398
13190
  cancelLink: function () { return interaction.cancelLink(); },
13191
+ zoomToFitElements: function (options) {
13192
+ var transform = resolveViewportFitTransform(engine.getState(), { width: stageWidth, height: stageHeight }, options);
13193
+ if (!transform)
13194
+ return;
13195
+ engine.setViewport(transform.pan, transform.zoom);
13196
+ },
12399
13197
  exportImage: function (options) {
12400
13198
  engine.render();
12401
13199
  if (typeof stage.toDataURL !== 'function') {
@@ -12422,6 +13220,8 @@ var createDiagramEditor = function (config) {
12422
13220
  return stage.toDataURL(__assign(__assign({}, baseOptions), { x: cropX, y: cropY, width: cropWidth, height: cropHeight }));
12423
13221
  },
12424
13222
  resize: function (width, height) {
13223
+ stageWidth = width;
13224
+ stageHeight = height;
12425
13225
  stage.width(width);
12426
13226
  stage.height(height);
12427
13227
  engine.render();
@@ -12641,6 +13441,7 @@ var engineEventOptions = [
12641
13441
  'elementDragged',
12642
13442
  'elementMoved',
12643
13443
  'elementResized',
13444
+ 'gridLayoutChanged',
12644
13445
  'elementDeleted',
12645
13446
  'portDeleted',
12646
13447
  'linkDeleted',
@@ -12895,7 +13696,7 @@ var parentOptions = [
12895
13696
  ];
12896
13697
  var shortLabel = 'Parent label lane demo';
12897
13698
  var longLabel = 'Parent label lane demo with longer content to increase flexible reserved space and push children downward.';
12898
- var defaultGridTemplateText = '[[3],[1,2]]';
13699
+ var defaultGridTemplateText = '[12,4,8]';
12899
13700
  var serializeGridTemplate = function (template) {
12900
13701
  return Array.isArray(template) && template.length > 0 ? JSON.stringify(template) : defaultGridTemplateText;
12901
13702
  };
@@ -12914,23 +13715,21 @@ var parseGridTemplate = function (value) {
12914
13715
  return null;
12915
13716
  var normalized = [];
12916
13717
  for (var i = 0; i < parsed.length; i += 1) {
12917
- var row = parsed[i];
12918
- if (typeof row === 'number') {
12919
- if (!Number.isFinite(row) || row <= 0)
13718
+ var entry = parsed[i];
13719
+ if (typeof entry === 'number') {
13720
+ if (!Number.isFinite(entry) || entry <= 0)
12920
13721
  return null;
12921
- normalized.push(Math.floor(row));
13722
+ normalized.push(Math.floor(entry));
12922
13723
  continue;
12923
13724
  }
12924
- if (!Array.isArray(row) || row.length === 0)
13725
+ if (!Array.isArray(entry) || entry.length === 0)
12925
13726
  return null;
12926
- var weights = [];
12927
- for (var j = 0; j < row.length; j += 1) {
12928
- var cell = row[j];
13727
+ for (var j = 0; j < entry.length; j += 1) {
13728
+ var cell = entry[j];
12929
13729
  if (typeof cell !== 'number' || !Number.isFinite(cell) || cell <= 0)
12930
13730
  return null;
12931
- weights.push(cell);
13731
+ normalized.push(Math.floor(cell));
12932
13732
  }
12933
- normalized.push(weights);
12934
13733
  }
12935
13734
  return normalized;
12936
13735
  };
@@ -12965,11 +13764,12 @@ var AutoLayoutDemo = function () {
12965
13764
  var _m = useState(''), childMaxWidth = _m[0], setChildMaxWidth = _m[1];
12966
13765
  var _o = useState(''), childMaxHeight = _o[0], setChildMaxHeight = _o[1];
12967
13766
  var _p = useState(defaultGridTemplateText), gridTemplateText = _p[0], setGridTemplateText = _p[1];
12968
- var _q = useState('none'), labelReservedMode = _q[0], setLabelReservedMode = _q[1];
12969
- var _r = useState(32), labelReservedFixedSize = _r[0], setLabelReservedFixedSize = _r[1];
12970
- var _s = useState(''), labelReservedMinSize = _s[0], setLabelReservedMinSize = _s[1];
12971
- var _t = useState(''), labelReservedMaxSize = _t[0], setLabelReservedMaxSize = _t[1];
12972
- var _u = useState('None yet'), lastTrigger = _u[0], setLastTrigger = _u[1];
13767
+ var _q = useState(false), gridChildWidthResizeEnabled = _q[0], setGridChildWidthResizeEnabled = _q[1];
13768
+ var _r = useState('none'), labelReservedMode = _r[0], setLabelReservedMode = _r[1];
13769
+ var _s = useState(32), labelReservedFixedSize = _s[0], setLabelReservedFixedSize = _s[1];
13770
+ var _t = useState(''), labelReservedMinSize = _t[0], setLabelReservedMinSize = _t[1];
13771
+ var _u = useState(''), labelReservedMaxSize = _u[0], setLabelReservedMaxSize = _u[1];
13772
+ var _v = useState('None yet'), lastTrigger = _v[0], setLastTrigger = _v[1];
12973
13773
  useEffect(function () {
12974
13774
  var editor = editorRef.current;
12975
13775
  if (!editor)
@@ -12977,6 +13777,7 @@ var AutoLayoutDemo = function () {
12977
13777
  var disposers = [
12978
13778
  editor.on('elementMoved', function () { return setLastTrigger('child moved'); }),
12979
13779
  editor.on('elementResized', function () { return setLastTrigger('child resized'); }),
13780
+ editor.on('gridLayoutChanged', function (event) { return setLastTrigger("grid layout changed (".concat(event.reason, ")")); }),
12980
13781
  editor.on('elementDeleted', function () { return setLastTrigger('child removed'); }),
12981
13782
  editor.on('change', function () { return setLastTrigger(function (prev) { return prev; }); }),
12982
13783
  ];
@@ -13051,6 +13852,7 @@ var AutoLayoutDemo = function () {
13051
13852
  setChildMaxWidth((_s = (_q = layout === null || layout === void 0 ? void 0 : layout.childMaxWidth) !== null && _q !== void 0 ? _q : (_r = layout === null || layout === void 0 ? void 0 : layout.childFitMaxSize) === null || _r === void 0 ? void 0 : _r.width) !== null && _s !== void 0 ? _s : '');
13052
13853
  setChildMaxHeight((_v = (_t = layout === null || layout === void 0 ? void 0 : layout.childMaxHeight) !== null && _t !== void 0 ? _t : (_u = layout === null || layout === void 0 ? void 0 : layout.childFitMaxSize) === null || _u === void 0 ? void 0 : _u.height) !== null && _v !== void 0 ? _v : '');
13053
13854
  setGridTemplateText(serializeGridTemplate(layout === null || layout === void 0 ? void 0 : layout.gridTemplate));
13855
+ setGridChildWidthResizeEnabled(Boolean(layout === null || layout === void 0 ? void 0 : layout.gridChildWidthResizeEnabled));
13054
13856
  setLabelReservedMode((_x = (_w = layout === null || layout === void 0 ? void 0 : layout.labelReservedSpace) === null || _w === void 0 ? void 0 : _w.mode) !== null && _x !== void 0 ? _x : 'none');
13055
13857
  setLabelReservedFixedSize((_z = (_y = layout === null || layout === void 0 ? void 0 : layout.labelReservedSpace) === null || _y === void 0 ? void 0 : _y.size) !== null && _z !== void 0 ? _z : 32);
13056
13858
  setLabelReservedMinSize((_1 = (_0 = layout === null || layout === void 0 ? void 0 : layout.labelReservedSpace) === null || _0 === void 0 ? void 0 : _0.minSize) !== null && _1 !== void 0 ? _1 : '');
@@ -13104,7 +13906,7 @@ var AutoLayoutDemo = function () {
13104
13906
  : __assign(__assign(__assign({ mode: labelReservedMode, placement: 'top' }, (labelReservedMode === 'fixed' ? { size: labelReservedFixedSize } : {})), (labelReservedMinSize === '' ? {} : { minSize: labelReservedMinSize })), (labelReservedMaxSize === '' ? {} : { maxSize: labelReservedMaxSize }));
13105
13907
  var layout = mode === 'manual'
13106
13908
  ? { mode: 'manual' }
13107
- : __assign(__assign(__assign(__assign(__assign(__assign({ mode: mode, autoResize: autoResize, padding: padding, gap: gap, align: align !== null && align !== void 0 ? align : 'center', childFitMainAxis: childFitMainAxis, childFitCrossAxis: childFitCrossAxis }, (childMinWidth === '' ? {} : { childMinWidth: childMinWidth })), (childMinHeight === '' ? {} : { childMinHeight: childMinHeight })), (childMaxWidth === '' ? {} : { childMaxWidth: childMaxWidth })), (childMaxHeight === '' ? {} : { childMaxHeight: childMaxHeight })), (mode === 'grid' && parsedGridTemplate ? { gridTemplate: parsedGridTemplate } : {})), { labelReservedSpace: labelReservedSpace });
13909
+ : __assign(__assign(__assign(__assign(__assign(__assign(__assign({ mode: mode, autoResize: autoResize, padding: padding, gap: gap, align: align !== null && align !== void 0 ? align : 'center', childFitMainAxis: childFitMainAxis, childFitCrossAxis: childFitCrossAxis }, (childMinWidth === '' ? {} : { childMinWidth: childMinWidth })), (childMinHeight === '' ? {} : { childMinHeight: childMinHeight })), (childMaxWidth === '' ? {} : { childMaxWidth: childMaxWidth })), (childMaxHeight === '' ? {} : { childMaxHeight: childMaxHeight })), (mode === 'grid' && parsedGridTemplate ? { gridTemplate: parsedGridTemplate } : {})), (mode === 'grid' ? { gridChildWidthResizeEnabled: gridChildWidthResizeEnabled } : {})), { labelReservedSpace: labelReservedSpace });
13108
13910
  editor.setElementLayout(targetElement.id, layout);
13109
13911
  setLastTrigger("layout applied (".concat(mode, ")"));
13110
13912
  };
@@ -13171,13 +13973,11 @@ var AutoLayoutDemo = function () {
13171
13973
  return (React.createElement("section", null,
13172
13974
  React.createElement("div", { style: { marginBottom: 12 } },
13173
13975
  React.createElement("h2", { style: { marginTop: 0, marginBottom: 4 } }, demo.title),
13174
- React.createElement("p", { style: { marginTop: 0 } }, "Try horizontal, vertical, grid, nested, and manual layout containers. Select a layout parent directly on the canvas or pick it from the list; the controls below always act on the current selection. Drag, resize, add, or remove children to see automatic reflow. Use fit controls, explicit child min/max constraints, auto-resize policy, and grid templates to validate v0.2.5 behavior."),
13976
+ React.createElement("p", { style: { marginTop: 0 } }, "Try horizontal, vertical, grid, nested, and manual layout containers. Select a layout parent directly on the canvas or pick it from the list; the controls below always act on the current selection. Drag, resize, add, or remove children to see automatic reflow. Use fit controls, explicit child min/max constraints, auto-resize policy, 12-unit grid templates, and the optional grid child width-resize capability to validate current behavior."),
13175
13977
  React.createElement("p", { style: { marginTop: 0, marginBottom: 0, fontSize: 13, color: '#333' } },
13176
- "Resize-lock check: select ",
13978
+ "Grid child width resize is disabled by default. With the capability off, select ",
13177
13979
  React.createElement("code", null, "grid-b"),
13178
- " and drag a corner mostly downward. Width should stay stable while height changes. Then select ",
13179
- React.createElement("code", null, "layout-grid"),
13180
- " and drag a corner to verify parent width and height both follow pointer movement.")),
13980
+ " and drag a corner mostly downward: width stays stable while height changes. Turn the capability on to let horizontal drag wrap rows automatically from a flat 12-unit slot array, then resize children in 1/12 steps. Any corner can drive width changes, width always grows or shrinks on the right, siblings keep their own widths, and dragging can swap grid item order.")),
13181
13981
  React.createElement(DisplayBoxControls, { actions: demo.actions, snapEnabled: controls.snapEnabled, selectedLinkRouting: controls.selectedLinkRouting, canToggleLinkRouting: controls.canToggleLinkRouting, onReload: controls.handleReload, onZoomIn: controls.handleZoomIn, onZoomOut: controls.handleZoomOut, onResetViewport: controls.handleResetViewport, onToggleSnap: controls.handleToggleSnap, onManualRender: controls.handleManualRender, onToggleLinkRouting: controls.handleToggleLinkRouting, onAction: controls.handleAction, onExportImage: controls.handleExportImage, onClearExportPreview: controls.handleClearExportPreview, exportPreviewDataUrl: controls.exportPreviewDataUrl, exportError: controls.exportError }),
13182
13982
  React.createElement("div", { style: { display: 'grid', gap: 12, marginBottom: 12 } },
13183
13983
  React.createElement("div", { style: { display: 'flex', flexWrap: 'wrap', gap: 12, alignItems: 'center' } },
@@ -13225,7 +14025,11 @@ var AutoLayoutDemo = function () {
13225
14025
  React.createElement("input", { id: "fit-max-width-input", type: "number", value: childMaxWidth, onChange: function (event) { return setChildMaxWidth(event.target.value === '' ? '' : Math.max(0, Number(event.target.value) || 0)); }, style: { width: 64, padding: '6px 8px' }, min: 0, placeholder: "w" }),
13226
14026
  React.createElement("input", { type: "number", value: childMaxHeight, onChange: function (event) { return setChildMaxHeight(event.target.value === '' ? '' : Math.max(0, Number(event.target.value) || 0)); }, style: { width: 64, padding: '6px 8px' }, min: 0, placeholder: "h" })),
13227
14027
  React.createElement("label", { htmlFor: "grid-template-input", style: { fontWeight: 600 } }, "Grid template"),
13228
- React.createElement("input", { id: "grid-template-input", type: "text", value: gridTemplateText, onChange: function (event) { return setGridTemplateText(event.target.value); }, style: { minWidth: 220, padding: '6px 8px' }, placeholder: "[[3],[1,2]] or [[1,1,1,1],[3,1]]", disabled: mode !== 'grid' }),
14028
+ React.createElement("input", { id: "grid-template-input", type: "text", value: gridTemplateText, onChange: function (event) { return setGridTemplateText(event.target.value); }, style: { minWidth: 220, padding: '6px 8px' }, placeholder: "[12,4,8] or [3,3,6,9]", disabled: mode !== 'grid' }),
14029
+ React.createElement("label", { htmlFor: "grid-child-width-resize-enabled", style: { fontWeight: 600 } }, "Grid child width resize"),
14030
+ React.createElement("label", { style: { display: 'inline-flex', alignItems: 'center', gap: 6 } },
14031
+ React.createElement("input", { id: "grid-child-width-resize-enabled", type: "checkbox", checked: gridChildWidthResizeEnabled, onChange: function (event) { return setGridChildWidthResizeEnabled(event.target.checked); }, disabled: mode !== 'grid' }),
14032
+ "Enable 12-unit resize on child width drag"),
13229
14033
  React.createElement("label", { htmlFor: "label-reserved-mode-select", style: { fontWeight: 600 } }, "Label lane"),
13230
14034
  React.createElement("select", { id: "label-reserved-mode-select", value: labelReservedMode, onChange: function (event) { return setLabelReservedMode(event.target.value); }, style: { padding: '6px 10px', minWidth: 120 }, disabled: mode === 'manual' },
13231
14035
  React.createElement("option", { value: "none" }, "None"),
@@ -13278,11 +14082,16 @@ var AutoLayoutDemo = function () {
13278
14082
  React.createElement("div", null,
13279
14083
  React.createElement("div", { style: { fontWeight: 600, marginBottom: 6 } }, "Scenario tips"),
13280
14084
  React.createElement("ul", { style: { marginTop: 0, paddingLeft: 18, fontSize: 13 } },
13281
- React.createElement("li", null, "Resize lock: select grid-b, drag corner diagonally; width should stay fixed while height changes."),
14085
+ React.createElement("li", null, "Resize lock: with grid child width resize off, select grid-b and drag diagonally; width should stay fixed."),
14086
+ React.createElement("li", null, "Enable grid child width resize, then shrink a full-width grid child; it should snap smaller without flashing, and later siblings should keep their own widths."),
14087
+ React.createElement("li", null, "Enable grid child width resize, then grow a child; siblings on the right should keep their own widths and only move down when they no longer fit."),
14088
+ React.createElement("li", null, "Try dragging a left resize handle on the first child in a row; the child should still grow, but only to the right."),
14089
+ React.createElement("li", null, "Try dragging a grid child across a sibling; the row-major order should swap to match the drag position."),
14090
+ React.createElement("li", null, "Whenever enabled child width resize changes row allocation, the last-trigger badge should report grid layout changed."),
13282
14091
  React.createElement("li", null, "Parent resize: select layout-grid, drag corner; parent width and height should both track drag."),
13283
14092
  React.createElement("li", null, "Horizontal: try center vs bottom alignment and larger padding."),
13284
14093
  React.createElement("li", null, "Vertical: see parent grow taller as children stack."),
13285
- React.createElement("li", null, "Grid: apply templates like [[3],[1,2]] and [[1,1,1,1],[3,1]]."),
14094
+ React.createElement("li", null, "Grid: apply templates like [12,4,8] and [3,3,6,9]. Rows wrap automatically when the next item cannot fit."),
13286
14095
  React.createElement("li", null, "Auto resize: compare grow-only vs grow-shrink while adding/removing children."),
13287
14096
  React.createElement("li", null, "Label lane: compare none/fixed/flexible and observe children start below the reserved lane."),
13288
14097
  React.createElement("li", null, "Fit main-axis distribute fills inner layout space across siblings."),
@@ -13714,10 +14523,15 @@ var TextLayoutDemo = function () {
13714
14523
  var selectedText = diagramState === null || diagramState === void 0 ? void 0 : diagramState.texts.find(function (text) { return text.id === selectedTextId; });
13715
14524
  var selectedDisplayContent = (_b = (_a = selectedText === null || selectedText === void 0 ? void 0 : selectedText.displayContent) !== null && _a !== void 0 ? _a : selectedText === null || selectedText === void 0 ? void 0 : selectedText.content) !== null && _b !== void 0 ? _b : '';
13716
14525
  var ownerElement = diagramState === null || diagramState === void 0 ? void 0 : diagramState.elements.find(function (element) { return element.id === textDemoOwnerId; });
14526
+ var selectedInteraction = selectedText === null || selectedText === void 0 ? void 0 : selectedText.interaction;
14527
+ var getInteractionForTarget = function (nextTarget) {
14528
+ return nextTarget === 'owned' ? textDemoOwnedInteraction : textDemoFloatingInteraction;
14529
+ };
13717
14530
  var applyLayoutToTarget = function (nextTarget, nextLayout) {
13718
14531
  var editor = editorRef.current;
13719
14532
  if (!editor)
13720
14533
  return;
14534
+ var interaction = getInteractionForTarget(nextTarget);
13721
14535
  if (nextTarget === 'owned') {
13722
14536
  editor.removeText(textDemoOwnedTextId);
13723
14537
  editor.addText({
@@ -13725,6 +14539,7 @@ var TextLayoutDemo = function () {
13725
14539
  content: textDemoLongSample,
13726
14540
  ownerId: textDemoOwnerId,
13727
14541
  position: { x: 12, y: 12 },
14542
+ interaction: interaction,
13728
14543
  layout: nextLayout,
13729
14544
  });
13730
14545
  editor.setSelection([textDemoOwnedTextId]);
@@ -13735,6 +14550,7 @@ var TextLayoutDemo = function () {
13735
14550
  id: textDemoFloatingTextId,
13736
14551
  content: textDemoLongSample,
13737
14552
  position: { x: 470, y: 120 },
14553
+ interaction: interaction,
13738
14554
  layout: nextLayout,
13739
14555
  });
13740
14556
  editor.setSelection([textDemoFloatingTextId]);
@@ -13802,7 +14618,8 @@ var TextLayoutDemo = function () {
13802
14618
  return (React.createElement("section", null,
13803
14619
  React.createElement("div", { style: { marginBottom: 12 } },
13804
14620
  React.createElement("h2", { style: { marginTop: 0, marginBottom: 4 } }, demo.title),
13805
- React.createElement("p", { style: { marginTop: 0 } }, "Full text content is preserved in state. Overflow and ellipsis settings only change visual output (`displayContent`) for rendering.")),
14621
+ React.createElement("p", { style: { marginTop: 0 } }, "Full text content is preserved in state. Overflow and ellipsis settings only change visual output (`displayContent`) for rendering."),
14622
+ React.createElement("p", { style: { marginTop: 0, marginBottom: 0, fontSize: 13 } }, "Owned text is fixed and read-only. Floating text remains draggable and editable. Try drag and double-click on each label to compare built-in interaction policy behavior.")),
13806
14623
  React.createElement(DisplayBoxControls, { actions: demo.actions, snapEnabled: controls.snapEnabled, selectedLinkRouting: controls.selectedLinkRouting, canToggleLinkRouting: controls.canToggleLinkRouting, onReload: controls.handleReload, onZoomIn: controls.handleZoomIn, onZoomOut: controls.handleZoomOut, onResetViewport: controls.handleResetViewport, onToggleSnap: controls.handleToggleSnap, onManualRender: controls.handleManualRender, onToggleLinkRouting: controls.handleToggleLinkRouting, onAction: controls.handleAction, onExportImage: controls.handleExportImage, onClearExportPreview: controls.handleClearExportPreview, exportPreviewDataUrl: controls.exportPreviewDataUrl, exportError: controls.exportError }),
13807
14624
  React.createElement("div", { style: { display: 'grid', gap: 10, marginBottom: 12 } },
13808
14625
  React.createElement("div", { style: { display: 'flex', flexWrap: 'wrap', gap: 10, alignItems: 'center' } },
@@ -13890,7 +14707,12 @@ var TextLayoutDemo = function () {
13890
14707
  ' ',
13891
14708
  Number.isFinite(selectedWorldX) && Number.isFinite(selectedWorldY)
13892
14709
  ? "".concat(selectedWorldX.toFixed(1), ", ").concat(selectedWorldY.toFixed(1))
13893
- : 'n/a')),
14710
+ : 'n/a'),
14711
+ React.createElement("div", null,
14712
+ "interaction: movable=",
14713
+ (selectedInteraction === null || selectedInteraction === void 0 ? void 0 : selectedInteraction.movable) === false ? 'false' : 'true',
14714
+ " | editable=",
14715
+ (selectedInteraction === null || selectedInteraction === void 0 ? void 0 : selectedInteraction.editable) === false ? 'false' : 'true')),
13894
14716
  React.createElement("div", { style: { display: 'grid', gap: 6 } },
13895
14717
  React.createElement("div", { style: { fontSize: 12 } },
13896
14718
  React.createElement("strong", null, "Canonical content:"),
@@ -13960,6 +14782,311 @@ var ObstacleRoutingDemo = function () {
13960
14782
  "Enable redraw refresh on two-endpoint change")) }));
13961
14783
  };
13962
14784
 
14785
+ var offsetAnchorShapes = __spreadArray(__spreadArray([], baseElementShapes, true), [
14786
+ {
14787
+ id: 'offset-anchor-ellipse',
14788
+ kind: 'ellipse',
14789
+ style: {
14790
+ fill: '#eef8ff',
14791
+ stroke: '#2563eb',
14792
+ strokeWidth: 2,
14793
+ },
14794
+ },
14795
+ ], false);
14796
+ var createOffsetAnchorAvoidanceState = function () { return ({
14797
+ elements: [
14798
+ {
14799
+ id: 'offset-sibling-parent',
14800
+ position: { x: 40, y: 110 },
14801
+ size: { width: 520, height: 250 },
14802
+ shapeId: 'panel',
14803
+ style: { fill: '#faf7ef' },
14804
+ },
14805
+ {
14806
+ id: 'offset-sibling-a',
14807
+ position: { x: 60, y: 78 },
14808
+ size: { width: 130, height: 96 },
14809
+ shapeId: 'offset-anchor-ellipse',
14810
+ parentId: 'offset-sibling-parent',
14811
+ portMovement: { moveMode: 'anchors', anchorConstraint: { preset: 'cardinal' } },
14812
+ },
14813
+ {
14814
+ id: 'offset-sibling-b',
14815
+ position: { x: 320, y: 78 },
14816
+ size: { width: 130, height: 96 },
14817
+ shapeId: 'offset-anchor-ellipse',
14818
+ parentId: 'offset-sibling-parent',
14819
+ portMovement: { moveMode: 'anchors', anchorConstraint: { preset: 'cardinal' } },
14820
+ },
14821
+ {
14822
+ id: 'offset-direction-parent',
14823
+ position: { x: 620, y: 110 },
14824
+ size: { width: 330, height: 250 },
14825
+ shapeId: 'offset-anchor-ellipse',
14826
+ portMovement: { moveMode: 'anchors', anchorConstraint: { preset: 'cardinal' } },
14827
+ },
14828
+ {
14829
+ id: 'offset-direction-child',
14830
+ position: { x: 48, y: 74 },
14831
+ size: { width: 128, height: 92 },
14832
+ shapeId: 'default',
14833
+ parentId: 'offset-direction-parent',
14834
+ portMovement: { moveMode: 'anchors', anchorConstraint: { preset: 'cardinal' } },
14835
+ },
14836
+ {
14837
+ id: 'offset-direction-sibling',
14838
+ position: { x: 190, y: 126 },
14839
+ size: { width: 96, height: 70 },
14840
+ shapeId: 'default',
14841
+ parentId: 'offset-direction-parent',
14842
+ style: { fill: '#fff6e8', stroke: '#b45309', strokeWidth: 2 },
14843
+ },
14844
+ ],
14845
+ ports: [
14846
+ {
14847
+ id: 'offset-sibling-a-port',
14848
+ elementId: 'offset-sibling-a',
14849
+ position: { x: 0, y: 48 },
14850
+ shapeId: 'port-dark',
14851
+ anchorCenter: true,
14852
+ currentAnchorId: 'left',
14853
+ moveMode: 'border',
14854
+ externalLinkAttachPoint: { x: 0, y: 24 },
14855
+ },
14856
+ {
14857
+ id: 'offset-sibling-b-port',
14858
+ elementId: 'offset-sibling-b',
14859
+ position: { x: 130, y: 48 },
14860
+ shapeId: 'port-dark',
14861
+ anchorCenter: true,
14862
+ currentAnchorId: 'right',
14863
+ moveMode: 'border',
14864
+ externalLinkAttachPoint: { x: 0, y: 24 },
14865
+ },
14866
+ {
14867
+ id: 'offset-parent-port',
14868
+ elementId: 'offset-direction-parent',
14869
+ position: { x: 18, y: 125 },
14870
+ shapeId: 'port-circle',
14871
+ anchorCenter: true,
14872
+ currentAnchorId: 'left',
14873
+ moveMode: 'border',
14874
+ externalLinkAttachPoint: { x: 0, y: 18 },
14875
+ internalLinkAttachPoint: { x: 0, y: -18 },
14876
+ },
14877
+ {
14878
+ id: 'offset-child-port',
14879
+ elementId: 'offset-direction-child',
14880
+ position: { x: 128, y: 46 },
14881
+ shapeId: 'port-circle',
14882
+ anchorCenter: true,
14883
+ currentAnchorId: 'right',
14884
+ moveMode: 'border',
14885
+ externalLinkAttachPoint: { x: 0, y: 18 },
14886
+ internalLinkAttachPoint: { x: 0, y: -18 },
14887
+ },
14888
+ ],
14889
+ links: [
14890
+ {
14891
+ id: 'offset-sibling-link',
14892
+ sourcePortId: 'offset-sibling-a-port',
14893
+ targetPortId: 'offset-sibling-b-port',
14894
+ points: [],
14895
+ routing: 'auto',
14896
+ },
14897
+ {
14898
+ id: 'offset-parent-child-link',
14899
+ sourcePortId: 'offset-parent-port',
14900
+ targetPortId: 'offset-child-port',
14901
+ points: [],
14902
+ routing: 'auto',
14903
+ },
14904
+ {
14905
+ id: 'offset-child-parent-link',
14906
+ sourcePortId: 'offset-child-port',
14907
+ targetPortId: 'offset-parent-port',
14908
+ points: [],
14909
+ routing: 'auto',
14910
+ },
14911
+ ],
14912
+ texts: [
14913
+ {
14914
+ id: 'offset-anchor-intro',
14915
+ content: 'Offset attach anchors now keep endpoint hosts forbidden during auto routing. Inspect that routes exit from projected border sides instead of cutting through the source or target host interior.',
14916
+ position: { x: 40, y: 28 },
14917
+ },
14918
+ {
14919
+ id: 'offset-sibling-label',
14920
+ content: 'Scenario A: sibling children use external attach points offset beyond left/right edges.',
14921
+ position: { x: 52, y: 82 },
14922
+ },
14923
+ {
14924
+ id: 'offset-direction-label',
14925
+ content: 'Scenario B: parent/child links reuse the same offset anchors but resolve internal vs external semantics by direction.',
14926
+ position: { x: 620, y: 82 },
14927
+ },
14928
+ {
14929
+ id: 'offset-sibling-a-text',
14930
+ content: 'Child A\nexternal offset 24',
14931
+ ownerId: 'offset-sibling-a',
14932
+ position: { x: 14, y: -20 },
14933
+ },
14934
+ {
14935
+ id: 'offset-sibling-b-text',
14936
+ content: 'Child B\nexternal offset 24',
14937
+ ownerId: 'offset-sibling-b',
14938
+ position: { x: 14, y: -20 },
14939
+ },
14940
+ {
14941
+ id: 'offset-direction-parent-text',
14942
+ content: 'Parent port\ninternal 18 / external 18',
14943
+ ownerId: 'offset-direction-parent',
14944
+ position: { x: 48, y: -20 },
14945
+ },
14946
+ {
14947
+ id: 'offset-direction-child-text',
14948
+ content: 'Child port\nexternal 18 / internal 18',
14949
+ ownerId: 'offset-direction-child',
14950
+ position: { x: 6, y: -18 },
14951
+ },
14952
+ {
14953
+ id: 'offset-direction-links-text',
14954
+ content: 'Blue links: parent→child and child→parent should keep the host border side semantics even with offset attach coordinates.',
14955
+ position: { x: 620, y: 378 },
14956
+ },
14957
+ ],
14958
+ }); };
14959
+ var rerouteAllAction = {
14960
+ id: 'offset-reroute-links',
14961
+ label: 'Reroute All Links',
14962
+ run: function (editor) {
14963
+ editor.rerouteAllLinks();
14964
+ },
14965
+ };
14966
+ var shiftTargetsAction = {
14967
+ id: 'offset-shift-targets',
14968
+ label: 'Shift targets + reroute',
14969
+ run: function (editor) {
14970
+ editor.moveElementTo('offset-sibling-b', 320, 96);
14971
+ editor.moveElementTo('offset-direction-child', 74, 96);
14972
+ editor.rerouteAllLinks();
14973
+ },
14974
+ };
14975
+ var offsetAnchorAvoidanceDemoConfig = {
14976
+ id: 'offset-anchor-avoidance',
14977
+ title: 'Offset Anchor Avoidance',
14978
+ description: 'Visual QA for projected-boundary-equivalent offset attach anchors that must still keep endpoint host interiors forbidden.',
14979
+ createState: createOffsetAnchorAvoidanceState,
14980
+ elementShapes: offsetAnchorShapes,
14981
+ portShapes: basePortShapes,
14982
+ defaultElementShapeId: 'default',
14983
+ defaultPortShapeId: 'port-circle',
14984
+ actions: [rerouteAllAction, shiftTargetsAction],
14985
+ };
14986
+
14987
+ var OffsetAnchorAvoidanceDemo = function () { return (React.createElement(SimpleDemo, { demo: offsetAnchorAvoidanceDemoConfig, beforeStage: React.createElement("div", { style: {
14988
+ marginBottom: 12,
14989
+ padding: '10px 12px',
14990
+ borderRadius: 8,
14991
+ border: '1px solid #2d2d2d',
14992
+ background: '#f4f4f4',
14993
+ } },
14994
+ React.createElement("strong", null, "Visual checks"),
14995
+ React.createElement("ul", { style: { margin: '6px 0 0 16px' } },
14996
+ React.createElement("li", null, "Sibling link should route around both child interiors even though attach coordinates are offset outside the host edges."),
14997
+ React.createElement("li", null, "`parent\u2192child` should use the parent's internal side and the child's external side."),
14998
+ React.createElement("li", null, "`child\u2192parent` should invert the same endpoint semantics without crossing either endpoint host interior."),
14999
+ React.createElement("li", null, "Use `Shift targets + reroute` and `Reroute All Links` to verify stable behavior after layout changes."))) })); };
15000
+
15001
+ var createZoomToFitElementsState = function () { return ({
15002
+ elements: [
15003
+ {
15004
+ id: 'fit-node-a',
15005
+ position: { x: 40, y: 60 },
15006
+ size: { width: 140, height: 90 },
15007
+ shapeId: 'default',
15008
+ style: { fill: '#eef6ff', stroke: '#1d4ed8', strokeWidth: 2 },
15009
+ },
15010
+ {
15011
+ id: 'fit-node-b',
15012
+ position: { x: 760, y: 120 },
15013
+ size: { width: 170, height: 110 },
15014
+ shapeId: 'panel',
15015
+ style: { fill: '#fef3c7', stroke: '#b45309', strokeWidth: 2 },
15016
+ },
15017
+ {
15018
+ id: 'fit-node-c',
15019
+ position: { x: 140, y: 420 },
15020
+ size: { width: 220, height: 120 },
15021
+ shapeId: 'default',
15022
+ style: { fill: '#ecfdf5', stroke: '#047857', strokeWidth: 2 },
15023
+ },
15024
+ {
15025
+ id: 'fit-node-d',
15026
+ position: { x: 860, y: 430 },
15027
+ size: { width: 150, height: 90 },
15028
+ shapeId: 'default',
15029
+ style: { fill: '#f5f3ff', stroke: '#6d28d9', strokeWidth: 2 },
15030
+ },
15031
+ ],
15032
+ ports: [],
15033
+ links: [],
15034
+ texts: [
15035
+ {
15036
+ id: 'fit-text-intro',
15037
+ content: 'Use actions to spread nodes and run the zoom-to-fit viewport command.',
15038
+ position: { x: 40, y: 24 },
15039
+ },
15040
+ ],
15041
+ }); };
15042
+ var zoomFitAction = {
15043
+ id: 'fit-zoom-default',
15044
+ label: 'Run Zoom-To-Fit',
15045
+ run: function (editor) {
15046
+ editor.zoomToFitElements();
15047
+ },
15048
+ };
15049
+ var zoomFitPaddingAction = {
15050
+ id: 'fit-zoom-padding',
15051
+ label: 'Run Zoom-To-Fit (Padding 48)',
15052
+ run: function (editor) {
15053
+ editor.zoomToFitElements({ padding: 48 });
15054
+ },
15055
+ };
15056
+ var spreadSceneAction = {
15057
+ id: 'fit-spread-scene',
15058
+ label: 'Spread Scene',
15059
+ run: function (editor) {
15060
+ editor.moveElementTo('fit-node-b', 880, 80);
15061
+ editor.moveElementTo('fit-node-d', 980, 500);
15062
+ editor.moveElementTo('fit-node-c', 80, 520);
15063
+ },
15064
+ };
15065
+ var zoomToFitElementsDemoConfig = {
15066
+ id: 'zoom-to-fit-elements',
15067
+ title: 'Zoom To Fit Elements',
15068
+ description: 'Calls a viewport command that zooms and centers so all elements are visible.',
15069
+ createState: createZoomToFitElementsState,
15070
+ elementShapes: baseElementShapes,
15071
+ portShapes: basePortShapes,
15072
+ defaultElementShapeId: 'default',
15073
+ defaultPortShapeId: 'port-circle',
15074
+ actions: [zoomFitAction, zoomFitPaddingAction, spreadSceneAction],
15075
+ };
15076
+
15077
+ var ZoomToFitElementsDemo = function () { return (React.createElement(SimpleDemo, { demo: zoomToFitElementsDemoConfig, beforeStage: (React.createElement("div", { style: {
15078
+ marginBottom: 12,
15079
+ padding: '10px 12px',
15080
+ borderRadius: 8,
15081
+ border: '1px solid #2d2d2d',
15082
+ background: '#f4f4f4',
15083
+ } },
15084
+ React.createElement("strong", null, "Visual checks"),
15085
+ React.createElement("ul", { style: { margin: '6px 0 0 16px' } },
15086
+ React.createElement("li", null, "Click `Run Zoom-To-Fit` and ensure every node is visible and centered."),
15087
+ React.createElement("li", null, "Run `Spread Scene` then fit again to verify viewport recomputes from the updated layout."),
15088
+ React.createElement("li", null, "Use `Run Zoom-To-Fit (Padding 48)` to confirm optional padding keeps extra breathing room around content.")))) })); };
15089
+
13963
15090
  var initialPayloads = {
13964
15091
  elementDeleted: null,
13965
15092
  portDeleted: null,
@@ -15037,6 +16164,18 @@ var demoTabs = [
15037
16164
  description: obstacleRoutingDemoConfig.description,
15038
16165
  Component: ObstacleRoutingDemo,
15039
16166
  },
16167
+ {
16168
+ id: offsetAnchorAvoidanceDemoConfig.id,
16169
+ title: offsetAnchorAvoidanceDemoConfig.title,
16170
+ description: offsetAnchorAvoidanceDemoConfig.description,
16171
+ Component: OffsetAnchorAvoidanceDemo,
16172
+ },
16173
+ {
16174
+ id: zoomToFitElementsDemoConfig.id,
16175
+ title: zoomToFitElementsDemoConfig.title,
16176
+ description: zoomToFitElementsDemoConfig.description,
16177
+ Component: ZoomToFitElementsDemo,
16178
+ },
15040
16179
  {
15041
16180
  id: linkBendHandlesDemoConfig.id,
15042
16181
  title: linkBendHandlesDemoConfig.title,