orcasvn-react-diagrams 0.2.7 → 0.2.9

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 (37) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +7 -12
  3. package/ai/api-contract.json +16 -0
  4. package/ai/invariants.json +8 -0
  5. package/ai/manifest.json +1 -1
  6. package/dist/cjs/examples.js +604 -39
  7. package/dist/cjs/index.js +227 -28
  8. package/dist/cjs/types/api/types.d.ts +2 -0
  9. package/dist/cjs/types/displaybox/demos/elementVisibilitySelectionDemo.d.ts +4 -0
  10. package/dist/cjs/types/engine/DiagramEngine.d.ts +8 -0
  11. package/dist/cjs/types/models/DiagramModel.d.ts +5 -0
  12. package/dist/cjs/types/models/ElementModel.d.ts +2 -0
  13. package/dist/esm/examples.js +604 -39
  14. package/dist/esm/examples.js.map +1 -1
  15. package/dist/esm/index.js +227 -28
  16. package/dist/esm/index.js.map +1 -1
  17. package/dist/esm/types/api/types.d.ts +2 -0
  18. package/dist/esm/types/displaybox/demos/elementVisibilitySelectionDemo.d.ts +4 -0
  19. package/dist/esm/types/engine/DiagramEngine.d.ts +8 -0
  20. package/dist/esm/types/models/DiagramModel.d.ts +5 -0
  21. package/dist/esm/types/models/ElementModel.d.ts +2 -0
  22. package/dist/examples.d.ts +2 -0
  23. package/dist/index.d.ts +9 -0
  24. package/docs/API_CONTRACT.md +16 -1
  25. package/docs/CAPABILITIES.md +1 -0
  26. package/docs/COMMANDS_EVENTS.md +3 -1
  27. package/docs/DOCUMENTATION_WORKFLOW.md +3 -1
  28. package/docs/INTEGRATION_PLAYBOOK.md +1 -0
  29. package/docs/PORTING_CHECKLIST.md +1 -0
  30. package/docs/STATE_INVARIANTS.md +9 -1
  31. package/package.json +1 -1
  32. package/src/displaybox/demos/AutoLayoutDemoTab.tsx +11 -5
  33. package/src/displaybox/demos/autoLayoutDemo.ts +233 -0
  34. package/src/displaybox/demos/basicDemo.ts +6 -6
  35. package/src/displaybox/demos/elementVisibilitySelectionDemo.ts +128 -0
  36. package/src/displaybox/demos/index.tsx +14 -7
  37. package/src/displaybox/demos/selectionDemo.ts +12 -12
@@ -741,7 +741,7 @@ var createBasicState = function () { return ({
741
741
  var basicDemoConfig = ({
742
742
  id: 'basic',
743
743
  title: 'Basic Diagram',
744
- description: 'Elements, ports, link, and labels.',
744
+ description: 'Elements, ports, link, and labels. Drag empty paper to pan; use Shift + drag for marquee selection.',
745
745
  createState: createBasicState,
746
746
  elementShapes: baseElementShapes,
747
747
  portShapes: basePortShapes,
@@ -1119,7 +1119,7 @@ var createSelectionState = function () { return ({
1119
1119
  texts: [
1120
1120
  {
1121
1121
  id: 'select-tip',
1122
- content: 'Click to select, drag to move, Delete/Backspace to remove.',
1122
+ content: 'Click to select, drag to move, drag empty paper to pan, Shift + drag to marquee-select.',
1123
1123
  position: { x: 80, y: 80 },
1124
1124
  },
1125
1125
  ],
@@ -1127,7 +1127,7 @@ var createSelectionState = function () { return ({
1127
1127
  var selectionDemoConfig = ({
1128
1128
  id: 'selection',
1129
1129
  title: 'Selection + Interaction',
1130
- description: 'Click to select, drag to move, marquee-select on empty space, delete to remove.',
1130
+ description: 'Click to select, drag to move, drag empty paper to pan, Shift + drag to marquee-select, delete to remove.',
1131
1131
  createState: createSelectionState,
1132
1132
  elementShapes: baseElementShapes,
1133
1133
  portShapes: basePortShapes,
@@ -1144,6 +1144,128 @@ var selectionDemoConfig = ({
1144
1144
  ],
1145
1145
  });
1146
1146
 
1147
+ var createElementVisibilitySelectionState = function () { return ({
1148
+ elements: [
1149
+ {
1150
+ id: 'policy-normal',
1151
+ position: { x: 120, y: 160 },
1152
+ size: { width: 180, height: 120 },
1153
+ shapeId: 'default',
1154
+ style: { fill: '#dbeafe', stroke: '#1d4ed8', strokeWidth: 2 },
1155
+ },
1156
+ {
1157
+ id: 'policy-unselectable',
1158
+ position: { x: 410, y: 160 },
1159
+ size: { width: 180, height: 120 },
1160
+ shapeId: 'default',
1161
+ selectable: false,
1162
+ style: { fill: '#e2e8f0', stroke: '#334155', strokeWidth: 2 },
1163
+ },
1164
+ {
1165
+ id: 'policy-hidden',
1166
+ position: { x: 700, y: 140 },
1167
+ size: { width: 180, height: 120 },
1168
+ shapeId: 'default',
1169
+ visible: false,
1170
+ style: { fill: '#fee2e2', stroke: '#dc2626', strokeWidth: 2 },
1171
+ },
1172
+ ],
1173
+ ports: [
1174
+ {
1175
+ id: 'policy-normal-port',
1176
+ elementId: 'policy-normal',
1177
+ position: { x: 180, y: 60 },
1178
+ shapeId: 'port-circle',
1179
+ },
1180
+ {
1181
+ id: 'policy-unselectable-port',
1182
+ elementId: 'policy-unselectable',
1183
+ position: { x: 0, y: 60 },
1184
+ shapeId: 'port-circle',
1185
+ },
1186
+ {
1187
+ id: 'policy-hidden-port',
1188
+ elementId: 'policy-hidden',
1189
+ position: { x: 0, y: 60 },
1190
+ shapeId: 'port-circle',
1191
+ },
1192
+ ],
1193
+ links: [
1194
+ {
1195
+ id: 'policy-visible-link',
1196
+ sourcePortId: 'policy-normal-port',
1197
+ targetPortId: 'policy-unselectable-port',
1198
+ points: [
1199
+ { x: 300, y: 220 },
1200
+ { x: 410, y: 220 },
1201
+ ],
1202
+ style: { stroke: '#2563eb', strokeWidth: 3 },
1203
+ },
1204
+ {
1205
+ id: 'policy-hidden-link',
1206
+ sourcePortId: 'policy-normal-port',
1207
+ targetPortId: 'policy-hidden-port',
1208
+ points: [
1209
+ { x: 300, y: 220 },
1210
+ { x: 700, y: 200 },
1211
+ ],
1212
+ style: { stroke: '#dc2626', strokeWidth: 3 },
1213
+ },
1214
+ ],
1215
+ texts: [
1216
+ {
1217
+ id: 'policy-tip',
1218
+ content: 'Blue node is normal. Slate node is visible but its body ignores click and marquee. Its port stays interactive. Hidden node, its port, and its attached red link stay in state but are suppressed from scene, selection, zoom-to-fit, and fit-to-content export.',
1219
+ position: { x: 80, y: 72 },
1220
+ size: { width: 760, height: 44 },
1221
+ style: { fontSize: 14, fill: '#0f172a' },
1222
+ },
1223
+ {
1224
+ id: 'policy-normal-label',
1225
+ content: 'Normal selectable element',
1226
+ position: { x: 16, y: 14 },
1227
+ ownerId: 'policy-normal',
1228
+ },
1229
+ {
1230
+ id: 'policy-unselectable-label',
1231
+ content: 'Visible but body is unselectable',
1232
+ position: { x: 16, y: 14 },
1233
+ ownerId: 'policy-unselectable',
1234
+ },
1235
+ {
1236
+ id: 'policy-hidden-label',
1237
+ content: 'Hidden in state',
1238
+ position: { x: 16, y: 14 },
1239
+ ownerId: 'policy-hidden',
1240
+ },
1241
+ ],
1242
+ }); };
1243
+ var elementVisibilitySelectionDemoConfig = {
1244
+ id: 'element-visibility-selection',
1245
+ title: 'Element Visibility + Selectability',
1246
+ description: 'QA scene for visible-but-unselectable element bodies, hidden-in-state elements, and port/link propagation. Shift + drag marquee to confirm only eligible items are collected.',
1247
+ createState: createElementVisibilitySelectionState,
1248
+ elementShapes: baseElementShapes,
1249
+ portShapes: basePortShapes,
1250
+ defaultElementShapeId: 'default',
1251
+ defaultPortShapeId: 'port-circle',
1252
+ actions: [
1253
+ {
1254
+ id: 'policy-filtered-selection',
1255
+ label: 'Try filtered API selection',
1256
+ run: function (editor) {
1257
+ editor.setSelection([
1258
+ 'policy-normal',
1259
+ 'policy-unselectable',
1260
+ 'policy-hidden',
1261
+ 'policy-unselectable-port',
1262
+ 'policy-hidden-link',
1263
+ ]);
1264
+ },
1265
+ },
1266
+ ],
1267
+ };
1268
+
1147
1269
  var createEventHandlersState = function () { return ({
1148
1270
  elements: [
1149
1271
  {
@@ -1427,6 +1549,192 @@ var createAutoLayoutState = function (lockComparisonChildren) {
1427
1549
  { id: 'deep-grid-b', position: { x: 0, y: 0 }, size: { width: 40, height: 28 }, shapeId: 'default', parentId: 'deep-grid-nested-parent' },
1428
1550
  { id: 'deep-grid-c', position: { x: 0, y: 0 }, size: { width: 52, height: 24 }, shapeId: 'default', parentId: 'deep-grid-nested-parent' },
1429
1551
  { id: 'deep-grid-d', position: { x: 0, y: 0 }, size: { width: 28, height: 30 }, shapeId: 'default', parentId: 'deep-grid-nested-parent' },
1552
+ {
1553
+ id: 'layout-grid-empty-compare',
1554
+ position: { x: 930, y: 70 },
1555
+ size: { width: 280, height: 190 },
1556
+ shapeId: 'panel',
1557
+ layout: {
1558
+ mode: 'grid',
1559
+ padding: { x: 12, y: 12 },
1560
+ gap: 12,
1561
+ align: 'center',
1562
+ autoResize: 'grow-shrink',
1563
+ gridTemplate: [4, 4, 4],
1564
+ gridChildWidthResizeEnabled: true,
1565
+ childMinWidth: 44,
1566
+ childMinHeight: 52,
1567
+ },
1568
+ },
1569
+ {
1570
+ id: 'empty-grid-slot',
1571
+ position: { x: 0, y: 0 },
1572
+ size: { width: 28, height: 18 },
1573
+ shapeId: 'default',
1574
+ parentId: 'layout-grid-empty-compare',
1575
+ layout: {
1576
+ mode: 'grid',
1577
+ padding: { x: 8, y: 8 },
1578
+ gap: 8,
1579
+ align: 'center',
1580
+ autoResize: 'grow-shrink',
1581
+ gridTemplate: [6, 6],
1582
+ gridChildWidthResizeEnabled: true,
1583
+ },
1584
+ },
1585
+ {
1586
+ id: 'filled-grid-slot',
1587
+ position: { x: 0, y: 0 },
1588
+ size: { width: 92, height: 88 },
1589
+ shapeId: 'default',
1590
+ parentId: 'layout-grid-empty-compare',
1591
+ layout: {
1592
+ mode: 'grid',
1593
+ padding: { x: 8, y: 8 },
1594
+ gap: 8,
1595
+ align: 'center',
1596
+ autoResize: 'grow-shrink',
1597
+ gridTemplate: [6, 6],
1598
+ gridChildWidthResizeEnabled: true,
1599
+ childMinWidth: 18,
1600
+ childMinHeight: 18,
1601
+ },
1602
+ },
1603
+ {
1604
+ id: 'empty-grid-compare-leaf',
1605
+ position: { x: 0, y: 0 },
1606
+ size: { width: 60, height: 70 },
1607
+ shapeId: 'default',
1608
+ parentId: 'layout-grid-empty-compare',
1609
+ },
1610
+ { id: 'filled-grid-slot-a', position: { x: 0, y: 0 }, size: { width: 34, height: 22 }, shapeId: 'default', parentId: 'filled-grid-slot' },
1611
+ { id: 'filled-grid-slot-b', position: { x: 0, y: 0 }, size: { width: 40, height: 24 }, shapeId: 'default', parentId: 'filled-grid-slot' },
1612
+ { id: 'filled-grid-slot-c', position: { x: 0, y: 0 }, size: { width: 48, height: 22 }, shapeId: 'default', parentId: 'filled-grid-slot' },
1613
+ {
1614
+ id: 'layout-grid-mixed-modes',
1615
+ position: { x: 930, y: 320 },
1616
+ size: { width: 340, height: 240 },
1617
+ shapeId: 'panel',
1618
+ layout: {
1619
+ mode: 'grid',
1620
+ padding: { x: 12, y: 12 },
1621
+ gap: 12,
1622
+ align: 'center',
1623
+ autoResize: 'grow-shrink',
1624
+ gridTemplate: [4, 4, 4],
1625
+ gridChildWidthResizeEnabled: true,
1626
+ childMinWidth: 52,
1627
+ childMinHeight: 64,
1628
+ },
1629
+ },
1630
+ {
1631
+ id: 'mixed-grid-child',
1632
+ position: { x: 0, y: 0 },
1633
+ size: { width: 88, height: 88 },
1634
+ shapeId: 'default',
1635
+ parentId: 'layout-grid-mixed-modes',
1636
+ layout: {
1637
+ mode: 'grid',
1638
+ padding: { x: 8, y: 8 },
1639
+ gap: 8,
1640
+ align: 'center',
1641
+ autoResize: 'grow-shrink',
1642
+ gridTemplate: [6, 6],
1643
+ gridChildWidthResizeEnabled: true,
1644
+ childMinWidth: 18,
1645
+ childMinHeight: 18,
1646
+ },
1647
+ },
1648
+ {
1649
+ id: 'mixed-column-child',
1650
+ position: { x: 0, y: 0 },
1651
+ size: { width: 92, height: 96 },
1652
+ shapeId: 'default',
1653
+ parentId: 'layout-grid-mixed-modes',
1654
+ layout: {
1655
+ mode: 'vertical',
1656
+ padding: { x: 8, y: 8 },
1657
+ gap: 8,
1658
+ align: 'center',
1659
+ autoResize: 'grow-shrink',
1660
+ },
1661
+ },
1662
+ {
1663
+ id: 'mixed-row-child',
1664
+ position: { x: 0, y: 0 },
1665
+ size: { width: 104, height: 84 },
1666
+ shapeId: 'default',
1667
+ parentId: 'layout-grid-mixed-modes',
1668
+ layout: {
1669
+ mode: 'horizontal',
1670
+ padding: { x: 8, y: 8 },
1671
+ gap: 8,
1672
+ align: 'center',
1673
+ autoResize: 'grow-shrink',
1674
+ },
1675
+ },
1676
+ { id: 'mixed-grid-a', position: { x: 0, y: 0 }, size: { width: 34, height: 22 }, shapeId: 'default', parentId: 'mixed-grid-child' },
1677
+ { id: 'mixed-grid-b', position: { x: 0, y: 0 }, size: { width: 44, height: 24 }, shapeId: 'default', parentId: 'mixed-grid-child' },
1678
+ { id: 'mixed-column-a', position: { x: 0, y: 0 }, size: { width: 60, height: 20 }, shapeId: 'default', parentId: 'mixed-column-child' },
1679
+ { id: 'mixed-column-b', position: { x: 0, y: 0 }, size: { width: 68, height: 24 }, shapeId: 'default', parentId: 'mixed-column-child' },
1680
+ { id: 'mixed-row-a', position: { x: 0, y: 0 }, size: { width: 32, height: 28 }, shapeId: 'default', parentId: 'mixed-row-child' },
1681
+ { id: 'mixed-row-b', position: { x: 0, y: 0 }, size: { width: 44, height: 24 }, shapeId: 'default', parentId: 'mixed-row-child' },
1682
+ {
1683
+ id: 'layout-column-grid-tree',
1684
+ position: { x: 40, y: 520 },
1685
+ size: { width: 340, height: 220 },
1686
+ shapeId: 'panel',
1687
+ layout: { mode: 'vertical', padding: { x: 12, y: 12 }, gap: 12, align: 'start', autoResize: 'grow-shrink' },
1688
+ },
1689
+ {
1690
+ id: 'column-grid-tree-top',
1691
+ position: { x: 0, y: 0 },
1692
+ size: { width: 180, height: 88 },
1693
+ shapeId: 'default',
1694
+ parentId: 'layout-column-grid-tree',
1695
+ layout: {
1696
+ mode: 'grid',
1697
+ padding: { x: 8, y: 8 },
1698
+ gap: 8,
1699
+ align: 'center',
1700
+ autoResize: 'grow-shrink',
1701
+ gridTemplate: [6, 6],
1702
+ gridChildWidthResizeEnabled: true,
1703
+ childMinWidth: 18,
1704
+ childMinHeight: 18,
1705
+ },
1706
+ },
1707
+ {
1708
+ id: 'column-grid-tree-branch',
1709
+ position: { x: 0, y: 0 },
1710
+ size: { width: 220, height: 96 },
1711
+ shapeId: 'default',
1712
+ parentId: 'layout-column-grid-tree',
1713
+ layout: { mode: 'horizontal', padding: { x: 8, y: 8 }, gap: 8, align: 'center', autoResize: 'grow-shrink' },
1714
+ },
1715
+ { id: 'column-grid-top-a', position: { x: 0, y: 0 }, size: { width: 52, height: 22 }, shapeId: 'default', parentId: 'column-grid-tree-top' },
1716
+ { id: 'column-grid-top-b', position: { x: 0, y: 0 }, size: { width: 44, height: 24 }, shapeId: 'default', parentId: 'column-grid-tree-top' },
1717
+ {
1718
+ id: 'column-grid-tree-inner-grid',
1719
+ position: { x: 0, y: 0 },
1720
+ size: { width: 120, height: 84 },
1721
+ shapeId: 'default',
1722
+ parentId: 'column-grid-tree-branch',
1723
+ layout: {
1724
+ mode: 'grid',
1725
+ padding: { x: 8, y: 8 },
1726
+ gap: 8,
1727
+ align: 'center',
1728
+ autoResize: 'grow-shrink',
1729
+ gridTemplate: [6, 6],
1730
+ gridChildWidthResizeEnabled: true,
1731
+ childMinWidth: 18,
1732
+ childMinHeight: 18,
1733
+ },
1734
+ },
1735
+ { id: 'column-grid-tree-leaf', position: { x: 0, y: 0 }, size: { width: 58, height: 62 }, shapeId: 'default', parentId: 'column-grid-tree-branch' },
1736
+ { id: 'column-grid-inner-a', position: { x: 0, y: 0 }, size: { width: 30, height: 22 }, shapeId: 'default', parentId: 'column-grid-tree-inner-grid' },
1737
+ { id: 'column-grid-inner-b', position: { x: 0, y: 0 }, size: { width: 42, height: 24 }, shapeId: 'default', parentId: 'column-grid-tree-inner-grid' },
1430
1738
  {
1431
1739
  id: 'layout-lock-compare',
1432
1740
  position: { x: 420, y: 410 },
@@ -1524,6 +1832,50 @@ var createAutoLayoutState = function (lockComparisonChildren) {
1524
1832
  { id: 'label-deep-grid-b', content: 'grid-b', position: { x: 6, y: -14 }, ownerId: 'deep-grid-b' },
1525
1833
  { id: 'label-deep-grid-c', content: 'grid-c', position: { x: 6, y: -14 }, ownerId: 'deep-grid-c' },
1526
1834
  { id: 'label-deep-grid-d', content: 'grid-d', position: { x: 6, y: -14 }, ownerId: 'deep-grid-d' },
1835
+ {
1836
+ id: 'label-layout-grid-empty-compare',
1837
+ content: 'Grid owner: empty vs filled nested grids',
1838
+ position: { x: 8, y: 6 },
1839
+ ownerId: 'layout-grid-empty-compare',
1840
+ layout: { boundsMode: 'owner-width', wrap: 'word', overflow: 'clip', padding: 0 },
1841
+ },
1842
+ { id: 'label-empty-grid-slot', content: 'empty nested grid', position: { x: 6, y: -16 }, ownerId: 'empty-grid-slot' },
1843
+ { id: 'label-filled-grid-slot', content: 'nested grid with children', position: { x: 6, y: -16 }, ownerId: 'filled-grid-slot' },
1844
+ { id: 'label-empty-grid-compare-leaf', content: 'leaf sibling', position: { x: 6, y: -16 }, ownerId: 'empty-grid-compare-leaf' },
1845
+ { id: 'label-filled-grid-slot-a', content: 'slot-a', position: { x: 6, y: -14 }, ownerId: 'filled-grid-slot-a' },
1846
+ { id: 'label-filled-grid-slot-b', content: 'slot-b', position: { x: 6, y: -14 }, ownerId: 'filled-grid-slot-b' },
1847
+ { id: 'label-filled-grid-slot-c', content: 'slot-c', position: { x: 6, y: -14 }, ownerId: 'filled-grid-slot-c' },
1848
+ {
1849
+ id: 'label-layout-grid-mixed-modes',
1850
+ content: 'Grid owner: mixed child layout modes',
1851
+ position: { x: 8, y: 6 },
1852
+ ownerId: 'layout-grid-mixed-modes',
1853
+ layout: { boundsMode: 'owner-width', wrap: 'word', overflow: 'clip', padding: 0 },
1854
+ },
1855
+ { id: 'label-mixed-grid-child', content: 'grid child', position: { x: 6, y: -16 }, ownerId: 'mixed-grid-child' },
1856
+ { id: 'label-mixed-column-child', content: 'vertical child', position: { x: 6, y: -16 }, ownerId: 'mixed-column-child' },
1857
+ { id: 'label-mixed-row-child', content: 'horizontal child', position: { x: 6, y: -16 }, ownerId: 'mixed-row-child' },
1858
+ { id: 'label-mixed-grid-a', content: 'grid-a', position: { x: 6, y: -14 }, ownerId: 'mixed-grid-a' },
1859
+ { id: 'label-mixed-grid-b', content: 'grid-b', position: { x: 6, y: -14 }, ownerId: 'mixed-grid-b' },
1860
+ { id: 'label-mixed-column-a', content: 'col-a', position: { x: 6, y: -14 }, ownerId: 'mixed-column-a' },
1861
+ { id: 'label-mixed-column-b', content: 'col-b', position: { x: 6, y: -14 }, ownerId: 'mixed-column-b' },
1862
+ { id: 'label-mixed-row-a', content: 'row-a', position: { x: 6, y: -14 }, ownerId: 'mixed-row-a' },
1863
+ { id: 'label-mixed-row-b', content: 'row-b', position: { x: 6, y: -14 }, ownerId: 'mixed-row-b' },
1864
+ {
1865
+ id: 'label-layout-column-grid-tree',
1866
+ content: 'Vertical owner with grid descendants',
1867
+ position: { x: 8, y: 6 },
1868
+ ownerId: 'layout-column-grid-tree',
1869
+ layout: { boundsMode: 'owner-width', wrap: 'word', overflow: 'clip', padding: 0 },
1870
+ },
1871
+ { id: 'label-column-grid-tree-top', content: 'top-level grid child', position: { x: 6, y: -16 }, ownerId: 'column-grid-tree-top' },
1872
+ { id: 'label-column-grid-tree-branch', content: 'row branch with inner grid', position: { x: 6, y: -16 }, ownerId: 'column-grid-tree-branch' },
1873
+ { id: 'label-column-grid-top-a', content: 'top-a', position: { x: 6, y: -14 }, ownerId: 'column-grid-top-a' },
1874
+ { id: 'label-column-grid-top-b', content: 'top-b', position: { x: 6, y: -14 }, ownerId: 'column-grid-top-b' },
1875
+ { id: 'label-column-grid-tree-inner-grid', content: 'nested grid descendant', position: { x: 6, y: -16 }, ownerId: 'column-grid-tree-inner-grid' },
1876
+ { id: 'label-column-grid-tree-leaf', content: 'branch leaf', position: { x: 6, y: -14 }, ownerId: 'column-grid-tree-leaf' },
1877
+ { id: 'label-column-grid-inner-a', content: 'inner-a', position: { x: 6, y: -14 }, ownerId: 'column-grid-inner-a' },
1878
+ { id: 'label-column-grid-inner-b', content: 'inner-b', position: { x: 6, y: -14 }, ownerId: 'column-grid-inner-b' },
1527
1879
  {
1528
1880
  id: 'label-layout-lock-compare',
1529
1881
  content: 'Child drag lock comparison',
@@ -4380,6 +4732,8 @@ var ElementModel = /** @class */ (function () {
4380
4732
  this.style = data.style;
4381
4733
  this.portIds = data.portIds ? __spreadArray([], data.portIds, true) : [];
4382
4734
  this.textIds = data.textIds ? __spreadArray([], data.textIds, true) : [];
4735
+ this.visible = data.visible;
4736
+ this.selectable = data.selectable;
4383
4737
  this.parentId = (_a = data.parentId) !== null && _a !== void 0 ? _a : null;
4384
4738
  this.moveMode = data.moveMode;
4385
4739
  this.anchorCenter = data.anchorCenter;
@@ -4418,6 +4772,8 @@ var ElementModel = /** @class */ (function () {
4418
4772
  style: this.style,
4419
4773
  portIds: __spreadArray([], this.portIds, true),
4420
4774
  textIds: __spreadArray([], this.textIds, true),
4775
+ visible: this.visible,
4776
+ selectable: this.selectable,
4421
4777
  parentId: this.parentId,
4422
4778
  moveMode: this.moveMode,
4423
4779
  anchorCenter: this.anchorCenter,
@@ -4821,6 +5177,29 @@ var DiagramModel = /** @class */ (function () {
4821
5177
  DiagramModel.prototype.getElement = function (id) {
4822
5178
  return this.elements.get(id);
4823
5179
  };
5180
+ DiagramModel.prototype.isElementVisible = function (id) {
5181
+ var element = this.elements.get(id);
5182
+ if (!element)
5183
+ return false;
5184
+ if (element.visible === false)
5185
+ return false;
5186
+ var currentParentId = element.parentId;
5187
+ while (currentParentId) {
5188
+ var parent_1 = this.elements.get(currentParentId);
5189
+ if (!parent_1)
5190
+ break;
5191
+ if (parent_1.visible === false)
5192
+ return false;
5193
+ currentParentId = parent_1.parentId;
5194
+ }
5195
+ return true;
5196
+ };
5197
+ DiagramModel.prototype.isElementSelectable = function (id) {
5198
+ var element = this.elements.get(id);
5199
+ if (!element)
5200
+ return false;
5201
+ return this.isElementVisible(id) && element.selectable !== false;
5202
+ };
4824
5203
  DiagramModel.prototype.setElementLayout = function (id, layout) {
4825
5204
  var element = this.elements.get(id);
4826
5205
  if (!element)
@@ -4839,6 +5218,12 @@ var DiagramModel = /** @class */ (function () {
4839
5218
  DiagramModel.prototype.getPort = function (id) {
4840
5219
  return this.ports.get(id);
4841
5220
  };
5221
+ DiagramModel.prototype.isPortVisible = function (id) {
5222
+ var port = this.ports.get(id);
5223
+ if (!port)
5224
+ return false;
5225
+ return this.isElementVisible(port.elementId);
5226
+ };
4842
5227
  DiagramModel.prototype.getPortWorldPosition = function (id) {
4843
5228
  var port = this.ports.get(id);
4844
5229
  if (!port)
@@ -4854,6 +5239,16 @@ var DiagramModel = /** @class */ (function () {
4854
5239
  DiagramModel.prototype.getLink = function (id) {
4855
5240
  return this.links.get(id);
4856
5241
  };
5242
+ DiagramModel.prototype.isLinkVisible = function (id) {
5243
+ var link = this.links.get(id);
5244
+ if (!link)
5245
+ return false;
5246
+ var sourcePort = this.ports.get(link.sourcePortId);
5247
+ var targetPort = this.ports.get(link.targetPortId);
5248
+ var sourceVisible = sourcePort ? this.isPortVisible(sourcePort.id) : true;
5249
+ var targetVisible = targetPort ? this.isPortVisible(targetPort.id) : true;
5250
+ return sourceVisible && targetVisible;
5251
+ };
4857
5252
  DiagramModel.prototype.getLinkMidpoint = function (id) {
4858
5253
  var link = this.links.get(id);
4859
5254
  if (!link)
@@ -4863,6 +5258,23 @@ var DiagramModel = /** @class */ (function () {
4863
5258
  DiagramModel.prototype.getText = function (id) {
4864
5259
  return this.texts.get(id);
4865
5260
  };
5261
+ DiagramModel.prototype.isTextVisible = function (id) {
5262
+ var text = this.texts.get(id);
5263
+ if (!text)
5264
+ return false;
5265
+ if (!text.ownerId)
5266
+ return true;
5267
+ if (this.elements.has(text.ownerId)) {
5268
+ return this.isElementVisible(text.ownerId);
5269
+ }
5270
+ if (this.ports.has(text.ownerId)) {
5271
+ return this.isPortVisible(text.ownerId);
5272
+ }
5273
+ if (this.links.has(text.ownerId)) {
5274
+ return this.isLinkVisible(text.ownerId);
5275
+ }
5276
+ return true;
5277
+ };
4866
5278
  DiagramModel.prototype.getTextWorldPosition = function (id) {
4867
5279
  var text = this.texts.get(id);
4868
5280
  if (!text)
@@ -5051,18 +5463,18 @@ var DiagramModel = /** @class */ (function () {
5051
5463
  }
5052
5464
  var current = element;
5053
5465
  while (current === null || current === void 0 ? void 0 : current.parentId) {
5054
- var parent_1 = this.elements.get(current.parentId);
5055
- if (!parent_1)
5466
+ var parent_2 = this.elements.get(current.parentId);
5467
+ if (!parent_2)
5056
5468
  break;
5057
- var parentX = parent_1.position.x;
5058
- var parentY = parent_1.position.y;
5059
- if (parent_1.anchorCenter) {
5060
- parentX -= parent_1.size.width / 2;
5061
- parentY -= parent_1.size.height / 2;
5469
+ var parentX = parent_2.position.x;
5470
+ var parentY = parent_2.position.y;
5471
+ if (parent_2.anchorCenter) {
5472
+ parentX -= parent_2.size.width / 2;
5473
+ parentY -= parent_2.size.height / 2;
5062
5474
  }
5063
5475
  x += parentX;
5064
5476
  y += parentY;
5065
- current = parent_1;
5477
+ current = parent_2;
5066
5478
  }
5067
5479
  return { x: x, y: y };
5068
5480
  };
@@ -6286,6 +6698,8 @@ var AutoLayoutService = /** @class */ (function () {
6286
6698
  return this.applyResolvedLayout(parentId, parent, desiredPositions, desiredSizes, {
6287
6699
  width: newParentWidth,
6288
6700
  height: newParentHeight,
6701
+ }, {
6702
+ preserveResizedLayoutParentSize: true,
6289
6703
  });
6290
6704
  };
6291
6705
  AutoLayoutService.prototype.resolveGridCellWidths = function (rowInnerWidth, weights) {
@@ -6295,7 +6709,7 @@ var AutoLayoutService = /** @class */ (function () {
6295
6709
  var safeWeights = weights.map(function (weight) { return _this.clampGridUnits(weight); });
6296
6710
  return this.distributeWeightedSizes(Math.max(0, rowInnerWidth), safeWeights);
6297
6711
  };
6298
- AutoLayoutService.prototype.applyResolvedLayout = function (parentId, parent, desiredPositions, desiredSizes, parentSize) {
6712
+ AutoLayoutService.prototype.applyResolvedLayout = function (parentId, parent, desiredPositions, desiredSizes, parentSize, options) {
6299
6713
  var _this = this;
6300
6714
  var _a;
6301
6715
  var patches = [];
@@ -6314,7 +6728,7 @@ var AutoLayoutService = /** @class */ (function () {
6314
6728
  var resizePatches = _this.commandQueue.run(createResizeElementCommand(childId, fittedSize), _this.model);
6315
6729
  patches.push.apply(patches, resizePatches);
6316
6730
  movedPortIds.push.apply(movedPortIds, _this.collectElementPortIds(childId));
6317
- var nested = _this.applyLayoutForParent(childId);
6731
+ var nested = _this.applyLayoutForParent(childId, (options === null || options === void 0 ? void 0 : options.preserveResizedLayoutParentSize) ? { preserveParentSize: true } : undefined);
6318
6732
  patches.push.apply(patches, nested.patches);
6319
6733
  movedPortIds.push.apply(movedPortIds, nested.movedPortIds);
6320
6734
  }
@@ -8175,16 +8589,38 @@ var DiagramEngine = /** @class */ (function () {
8175
8589
  this.emitEntityDeletionEvents(removal.removed);
8176
8590
  };
8177
8591
  DiagramEngine.prototype.setSelection = function (ids) {
8178
- this.selection.set(ids);
8592
+ this.selection.set(this.normalizeSelectionIds(ids));
8179
8593
  this.emitSelection();
8180
8594
  };
8181
8595
  DiagramEngine.prototype.toggleSelection = function (id) {
8182
- this.selection.toggle(id);
8596
+ var current = new Set(this.selection.get());
8597
+ if (current.has(id)) {
8598
+ current.delete(id);
8599
+ }
8600
+ else if (this.isSelectableId(id)) {
8601
+ current.add(id);
8602
+ }
8603
+ this.selection.set(Array.from(current));
8183
8604
  this.emitSelection();
8184
8605
  };
8185
8606
  DiagramEngine.prototype.getSelection = function () {
8186
8607
  return this.selection.get();
8187
8608
  };
8609
+ DiagramEngine.prototype.isElementVisible = function (id) {
8610
+ return this.model.isElementVisible(id);
8611
+ };
8612
+ DiagramEngine.prototype.isElementSelectable = function (id) {
8613
+ return this.model.isElementSelectable(id);
8614
+ };
8615
+ DiagramEngine.prototype.isPortVisible = function (id) {
8616
+ return this.model.isPortVisible(id);
8617
+ };
8618
+ DiagramEngine.prototype.isLinkVisible = function (id) {
8619
+ return this.model.isLinkVisible(id);
8620
+ };
8621
+ DiagramEngine.prototype.isTextVisible = function (id) {
8622
+ return this.model.isTextVisible(id);
8623
+ };
8188
8624
  DiagramEngine.prototype.getElementWorldPosition = function (id) {
8189
8625
  return this.model.getElementWorldPosition(id);
8190
8626
  };
@@ -8446,11 +8882,15 @@ var DiagramEngine = /** @class */ (function () {
8446
8882
  var _this = this;
8447
8883
  var _a;
8448
8884
  var allPatches = this.appendTextLayoutPatches(patches, (_a = options === null || options === void 0 ? void 0 : options.emitTextUpdated) !== null && _a !== void 0 ? _a : true);
8885
+ var selectionChanged = this.syncSelectionToPolicies();
8449
8886
  var state = this.model.toState();
8450
8887
  this.events.emit('change', { patches: allPatches, state: state });
8451
- if ((options === null || options === void 0 ? void 0 : options.render) === false)
8452
- return;
8453
- this.scheduler.requestRender(function () { return _this.renderer.render(_this.model); });
8888
+ if ((options === null || options === void 0 ? void 0 : options.render) !== false) {
8889
+ this.scheduler.requestRender(function () { return _this.renderer.render(_this.model); });
8890
+ }
8891
+ if (selectionChanged) {
8892
+ this.emitSelection();
8893
+ }
8454
8894
  };
8455
8895
  DiagramEngine.prototype.appendTextLayoutPatches = function (patches, emitTextUpdated) {
8456
8896
  var _this = this;
@@ -8896,6 +9336,31 @@ var DiagramEngine = /** @class */ (function () {
8896
9336
  });
8897
9337
  this.renderer.renderSelection(selectedIds);
8898
9338
  };
9339
+ DiagramEngine.prototype.normalizeSelectionIds = function (ids) {
9340
+ var _this = this;
9341
+ return ids.filter(function (id, index) { return ids.indexOf(id) === index && _this.isSelectableId(id); });
9342
+ };
9343
+ DiagramEngine.prototype.isSelectableId = function (id) {
9344
+ if (this.model.getElement(id))
9345
+ return this.model.isElementSelectable(id);
9346
+ if (this.model.getPort(id))
9347
+ return this.model.isPortVisible(id);
9348
+ if (this.model.getLink(id))
9349
+ return this.model.isLinkVisible(id);
9350
+ if (this.model.getText(id))
9351
+ return this.model.isTextVisible(id);
9352
+ return false;
9353
+ };
9354
+ DiagramEngine.prototype.syncSelectionToPolicies = function () {
9355
+ var current = this.selection.get();
9356
+ var normalized = this.normalizeSelectionIds(current);
9357
+ if (current.length === normalized.length &&
9358
+ current.every(function (id, index) { return id === normalized[index]; })) {
9359
+ return false;
9360
+ }
9361
+ this.selection.set(normalized);
9362
+ return true;
9363
+ };
8899
9364
  DiagramEngine.prototype.applyLayoutForParent = function (parentId, options) {
8900
9365
  return this.autoLayoutService.applyLayoutForParent(parentId, options);
8901
9366
  };
@@ -9813,7 +10278,9 @@ var KonvaRenderer = /** @class */ (function () {
9813
10278
  };
9814
10279
  KonvaRenderer.prototype.syncElements = function (model) {
9815
10280
  var _this = this;
9816
- var elements = Array.from(model.elements.values()).map(function (element, index) { return ({
10281
+ var elements = Array.from(model.elements.values())
10282
+ .filter(function (element) { return model.isElementVisible(element.id); })
10283
+ .map(function (element, index) { return ({
9817
10284
  element: element,
9818
10285
  depth: _this.getElementDepth(model, element),
9819
10286
  order: index,
@@ -9846,6 +10313,10 @@ var KonvaRenderer = /** @class */ (function () {
9846
10313
  node.setAttrs({ __depth: depth });
9847
10314
  }
9848
10315
  });
10316
+ var visibleElementIds = new Set(elements.map(function (_a) {
10317
+ var element = _a.element;
10318
+ return element.id;
10319
+ }));
9849
10320
  elements.forEach(function (_a) {
9850
10321
  var _b;
9851
10322
  var element = _a.element;
@@ -9854,7 +10325,7 @@ var KonvaRenderer = /** @class */ (function () {
9854
10325
  });
9855
10326
  Array.from(this.elementNodes.keys()).forEach(function (id) {
9856
10327
  var _a;
9857
- if (!model.elements.has(id)) {
10328
+ if (!visibleElementIds.has(id)) {
9858
10329
  var node = _this.elementNodes.get(id);
9859
10330
  (_a = node === null || node === void 0 ? void 0 : node.destroy) === null || _a === void 0 ? void 0 : _a.call(node);
9860
10331
  _this.elementNodes.delete(id);
@@ -9877,7 +10348,7 @@ var KonvaRenderer = /** @class */ (function () {
9877
10348
  };
9878
10349
  KonvaRenderer.prototype.syncPorts = function (model) {
9879
10350
  var _this = this;
9880
- var ports = Array.from(model.ports.values());
10351
+ var ports = Array.from(model.ports.values()).filter(function (port) { return model.isPortVisible(port.id); });
9881
10352
  ports.forEach(function (port) {
9882
10353
  var _a, _b, _c, _d, _e;
9883
10354
  var data = port.toData();
@@ -9895,9 +10366,10 @@ var KonvaRenderer = /** @class */ (function () {
9895
10366
  _this.updatePosition(node, position);
9896
10367
  _this.applyPortOrientation(node, data, position, model);
9897
10368
  });
10369
+ var visiblePortIds = new Set(ports.map(function (port) { return port.id; }));
9898
10370
  Array.from(this.portNodes.keys()).forEach(function (id) {
9899
10371
  var _a;
9900
- if (!model.ports.has(id)) {
10372
+ if (!visiblePortIds.has(id)) {
9901
10373
  var node = _this.portNodes.get(id);
9902
10374
  (_a = node === null || node === void 0 ? void 0 : node.destroy) === null || _a === void 0 ? void 0 : _a.call(node);
9903
10375
  _this.portNodes.delete(id);
@@ -9908,7 +10380,7 @@ var KonvaRenderer = /** @class */ (function () {
9908
10380
  };
9909
10381
  KonvaRenderer.prototype.syncLinks = function (model) {
9910
10382
  var _this = this;
9911
- var links = Array.from(model.links.values());
10383
+ var links = Array.from(model.links.values()).filter(function (link) { return model.isLinkVisible(link.id); });
9912
10384
  links.forEach(function (link) {
9913
10385
  var _a, _b;
9914
10386
  var node = _this.linkNodes.get(link.id);
@@ -9919,9 +10391,10 @@ var KonvaRenderer = /** @class */ (function () {
9919
10391
  }
9920
10392
  _this.updateLine(node, link.toData());
9921
10393
  });
10394
+ var visibleLinkIds = new Set(links.map(function (link) { return link.id; }));
9922
10395
  Array.from(this.linkNodes.keys()).forEach(function (id) {
9923
10396
  var _a;
9924
- if (!model.links.has(id)) {
10397
+ if (!visibleLinkIds.has(id)) {
9925
10398
  var node = _this.linkNodes.get(id);
9926
10399
  (_a = node === null || node === void 0 ? void 0 : node.destroy) === null || _a === void 0 ? void 0 : _a.call(node);
9927
10400
  _this.linkNodes.delete(id);
@@ -9932,7 +10405,7 @@ var KonvaRenderer = /** @class */ (function () {
9932
10405
  };
9933
10406
  KonvaRenderer.prototype.syncTexts = function (model) {
9934
10407
  var _this = this;
9935
- var texts = Array.from(model.texts.values());
10408
+ var texts = Array.from(model.texts.values()).filter(function (text) { return model.isTextVisible(text.id); });
9936
10409
  texts.forEach(function (text) {
9937
10410
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
9938
10411
  var node = _this.textNodes.get(text.id);
@@ -10021,9 +10494,10 @@ var KonvaRenderer = /** @class */ (function () {
10021
10494
  _this.textBackgroundNodes.delete(text.id);
10022
10495
  }
10023
10496
  });
10497
+ var visibleTextIds = new Set(texts.map(function (text) { return text.id; }));
10024
10498
  Array.from(this.textNodes.keys()).forEach(function (id) {
10025
10499
  var _a, _b;
10026
- if (!model.texts.has(id)) {
10500
+ if (!visibleTextIds.has(id)) {
10027
10501
  var backgroundNode = _this.textBackgroundNodes.get(id);
10028
10502
  (_a = backgroundNode === null || backgroundNode === void 0 ? void 0 : backgroundNode.destroy) === null || _a === void 0 ? void 0 : _a.call(backgroundNode);
10029
10503
  _this.textBackgroundNodes.delete(id);
@@ -11015,15 +11489,21 @@ var KonvaInteraction = /** @class */ (function () {
11015
11489
  KonvaInteraction.prototype.normalizeHit = function (hit) {
11016
11490
  if (!hit || hit.type === 'none')
11017
11491
  return null;
11018
- if (hit.type === 'port' ||
11019
- hit.type === 'link' ||
11020
- hit.type === 'text' ||
11021
- hit.type === 'resize-handle' ||
11492
+ if (hit.type === 'port') {
11493
+ return this.engine.isPortVisible(hit.id) ? hit : null;
11494
+ }
11495
+ if (hit.type === 'link') {
11496
+ return this.engine.isLinkVisible(hit.id) ? hit : null;
11497
+ }
11498
+ if (hit.type === 'text') {
11499
+ return this.engine.isTextVisible(hit.id) ? hit : null;
11500
+ }
11501
+ if (hit.type === 'resize-handle' ||
11022
11502
  hit.type === 'link-handle' ||
11023
11503
  hit.type === 'shape-hover-control') {
11024
11504
  return hit;
11025
11505
  }
11026
- return __assign(__assign({}, hit), { type: 'element' });
11506
+ return this.engine.isElementSelectable(hit.id) ? __assign(__assign({}, hit), { type: 'element' }) : null;
11027
11507
  };
11028
11508
  KonvaInteraction.prototype.resolveHit = function (point) {
11029
11509
  var _this = this;
@@ -11089,6 +11569,8 @@ var KonvaInteraction = /** @class */ (function () {
11089
11569
  var best = null;
11090
11570
  state.elements.forEach(function (element) {
11091
11571
  var _a, _b, _c;
11572
+ if (!_this.engine.isElementSelectable(element.id))
11573
+ return;
11092
11574
  var world = (_a = _this.engine.getElementWorldPosition(element.id)) !== null && _a !== void 0 ? _a : element.position;
11093
11575
  var rotation = _this.engine.getElementRotation(element.id);
11094
11576
  if (!pointInRotatedRect(point, world, element.size, rotation, (_b = element.anchorCenter) !== null && _b !== void 0 ? _b : false))
@@ -11118,6 +11600,8 @@ var KonvaInteraction = /** @class */ (function () {
11118
11600
  var bestDistance = Number.POSITIVE_INFINITY;
11119
11601
  links.forEach(function (link) {
11120
11602
  var _a, _b;
11603
+ if (!_this.engine.isLinkVisible(link.id))
11604
+ return;
11121
11605
  if (link.points.length < 2)
11122
11606
  return;
11123
11607
  var tolerance = ((_b = (_a = link.style) === null || _a === void 0 ? void 0 : _a.hitStrokeWidth) !== null && _b !== void 0 ? _b : 15) / 2;
@@ -12132,6 +12616,8 @@ var KonvaInteraction = /** @class */ (function () {
12132
12616
  };
12133
12617
  state.elements.forEach(function (element) {
12134
12618
  var _a, _b;
12619
+ if (!_this.engine.isElementSelectable(element.id))
12620
+ return;
12135
12621
  var position = (_a = _this.engine.getElementWorldPosition(element.id)) !== null && _a !== void 0 ? _a : element.position;
12136
12622
  var rotation = _this.engine.getElementRotation(element.id);
12137
12623
  var anchorCenter = (_b = element.anchorCenter) !== null && _b !== void 0 ? _b : false;
@@ -12149,6 +12635,8 @@ var KonvaInteraction = /** @class */ (function () {
12149
12635
  });
12150
12636
  state.ports.forEach(function (port) {
12151
12637
  var _a;
12638
+ if (!_this.engine.isPortVisible(port.id))
12639
+ return;
12152
12640
  var position = (_a = _this.engine.getPortWorldPosition(port.id)) !== null && _a !== void 0 ? _a : port.position;
12153
12641
  if (containsPoint(position)) {
12154
12642
  selected.add(port.id);
@@ -12156,6 +12644,8 @@ var KonvaInteraction = /** @class */ (function () {
12156
12644
  });
12157
12645
  state.texts.forEach(function (text) {
12158
12646
  var _a, _b, _c, _d, _e;
12647
+ if (!_this.engine.isTextVisible(text.id))
12648
+ return;
12159
12649
  var position = (_a = _this.engine.getTextWorldPosition(text.id)) !== null && _a !== void 0 ? _a : text.position;
12160
12650
  var width = (_c = (_b = text.size) === null || _b === void 0 ? void 0 : _b.width) !== null && _c !== void 0 ? _c : 0;
12161
12651
  var height = (_e = (_d = text.size) === null || _d === void 0 ? void 0 : _d.height) !== null && _e !== void 0 ? _e : 0;
@@ -12165,6 +12655,8 @@ var KonvaInteraction = /** @class */ (function () {
12165
12655
  }
12166
12656
  });
12167
12657
  state.links.forEach(function (link) {
12658
+ if (!_this.engine.isLinkVisible(link.id))
12659
+ return;
12168
12660
  if (link.points.length === 0)
12169
12661
  return;
12170
12662
  var xs = link.points.map(function (point) { return point.x; });
@@ -13096,13 +13588,65 @@ var resolveViewportFitOptions = function (options) {
13096
13588
  return { padding: padding, minZoom: minZoom, maxZoom: maxZoom };
13097
13589
  };
13098
13590
  var clamp = function (value, min, max) { return Math.max(min, Math.min(max, value)); };
13591
+ var isElementVisibleInState = function (elementId, elementsById) {
13592
+ var _a, _b;
13593
+ var element = elementsById.get(elementId);
13594
+ if (!element)
13595
+ return false;
13596
+ if (element.visible === false)
13597
+ return false;
13598
+ var currentParentId = (_a = element.parentId) !== null && _a !== void 0 ? _a : null;
13599
+ while (currentParentId) {
13600
+ var parent_1 = elementsById.get(currentParentId);
13601
+ if (!parent_1)
13602
+ break;
13603
+ if (parent_1.visible === false)
13604
+ return false;
13605
+ currentParentId = (_b = parent_1.parentId) !== null && _b !== void 0 ? _b : null;
13606
+ }
13607
+ return true;
13608
+ };
13609
+ var isPortVisibleInState = function (portId, portsById, elementsById) {
13610
+ var port = portsById.get(portId);
13611
+ if (!port)
13612
+ return false;
13613
+ return isElementVisibleInState(port.elementId, elementsById);
13614
+ };
13615
+ var isLinkVisibleInState = function (linkId, linksById, portsById, elementsById) {
13616
+ var link = linksById.get(linkId);
13617
+ if (!link)
13618
+ return false;
13619
+ var sourcePort = portsById.get(link.sourcePortId);
13620
+ var targetPort = portsById.get(link.targetPortId);
13621
+ var sourceVisible = sourcePort ? isPortVisibleInState(sourcePort.id, portsById, elementsById) : true;
13622
+ var targetVisible = targetPort ? isPortVisibleInState(targetPort.id, portsById, elementsById) : true;
13623
+ return sourceVisible && targetVisible;
13624
+ };
13625
+ var isTextVisibleInState = function (text, elementsById, portsById, linksById) {
13626
+ if (!text.ownerId)
13627
+ return true;
13628
+ if (elementsById.has(text.ownerId))
13629
+ return isElementVisibleInState(text.ownerId, elementsById);
13630
+ if (portsById.has(text.ownerId))
13631
+ return isPortVisibleInState(text.ownerId, portsById, elementsById);
13632
+ if (linksById.has(text.ownerId))
13633
+ return isLinkVisibleInState(text.ownerId, linksById, portsById, elementsById);
13634
+ return true;
13635
+ };
13099
13636
  var resolveStateWorldBounds = function (state) {
13100
13637
  var bounds = createBounds();
13638
+ var elementsById = new Map(state.elements.map(function (element) { return [element.id, element]; }));
13639
+ var portsById = new Map(state.ports.map(function (port) { return [port.id, port]; }));
13640
+ var linksById = new Map(state.links.map(function (link) { return [link.id, link]; }));
13101
13641
  state.elements.forEach(function (element) {
13642
+ if (!isElementVisibleInState(element.id, elementsById))
13643
+ return;
13102
13644
  includeRect(bounds, element.position.x, element.position.y, element.size.width, element.size.height);
13103
13645
  });
13104
13646
  state.ports.forEach(function (port) {
13105
13647
  var _a;
13648
+ if (!isPortVisibleInState(port.id, portsById, elementsById))
13649
+ return;
13106
13650
  var size = port.size;
13107
13651
  if (!size) {
13108
13652
  expandBounds(bounds, port.position.x, port.position.y);
@@ -13114,12 +13658,16 @@ var resolveStateWorldBounds = function (state) {
13114
13658
  includeRect(bounds, x, y, size.width, size.height);
13115
13659
  });
13116
13660
  state.links.forEach(function (link) {
13661
+ if (!isLinkVisibleInState(link.id, linksById, portsById, elementsById))
13662
+ return;
13117
13663
  link.points.forEach(function (point) {
13118
13664
  expandBounds(bounds, point.x, point.y);
13119
13665
  });
13120
13666
  });
13121
13667
  state.texts.forEach(function (text) {
13122
13668
  var _a;
13669
+ if (!isTextVisibleInState(text, elementsById, portsById, linksById))
13670
+ return;
13123
13671
  var offset = (_a = text.displayOffset) !== null && _a !== void 0 ? _a : { x: 0, y: 0 };
13124
13672
  var position = { x: text.position.x + offset.x, y: text.position.y + offset.y };
13125
13673
  var clipSize = text.displayClipSize;
@@ -13134,7 +13682,10 @@ var resolveStateWorldBounds = function (state) {
13134
13682
  };
13135
13683
  var resolveElementWorldBounds = function (state) {
13136
13684
  var bounds = createBounds();
13685
+ var elementsById = new Map(state.elements.map(function (element) { return [element.id, element]; }));
13137
13686
  state.elements.forEach(function (element) {
13687
+ if (!isElementVisibleInState(element.id, elementsById))
13688
+ return;
13138
13689
  includeRect(bounds, element.position.x, element.position.y, element.size.width, element.size.height);
13139
13690
  });
13140
13691
  return hasBounds(bounds) ? bounds : null;
@@ -13892,6 +14443,9 @@ var parentOptions = [
13892
14443
  { id: 'layout-grid', label: 'Grid layout' },
13893
14444
  { id: 'layout-nested', label: 'Nested layout' },
13894
14445
  { id: 'layout-grid-deep', label: 'Nested grid' },
14446
+ { id: 'layout-grid-empty-compare', label: 'Grid empty vs filled' },
14447
+ { id: 'layout-grid-mixed-modes', label: 'Grid mixed child modes' },
14448
+ { id: 'layout-column-grid-tree', label: 'Non-grid with grid descendants' },
13895
14449
  { id: 'layout-lock-compare', label: 'Child lock compare' },
13896
14450
  { id: 'layout-manual', label: 'Manual (compare)' },
13897
14451
  ];
@@ -14220,15 +14774,17 @@ var AutoLayoutDemo = function () {
14220
14774
  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."),
14221
14775
  React.createElement("p", { style: { marginTop: 0, fontSize: 13, color: '#333' } }, "Grid child width resize starts enabled for the seeded grid parents in this demo. With the capability on, horizontal drag can wrap rows automatically from a flat 12-unit slot array, resize direct grid children in 1/12 steps, and reorder peers by drag position. That now includes nested layout parents as well as leaf children. Turn the checkbox off on a selected grid parent to compare the older locked-width behavior where a mostly downward drag keeps width stable while height changes."),
14222
14776
  React.createElement("p", { style: { marginTop: 0, marginBottom: 0, fontSize: 13, color: '#333' } },
14223
- "The ",
14777
+ "The seeded scenarios now cover empty nested grids, mixed child layout modes under one grid owner, and grid descendants inside a non-grid tree. Use ",
14224
14778
  React.createElement("code", null, "layout-grid-deep"),
14225
- " scenario now keeps the outer container focused on grid behavior with three direct grid children, including one nested grid parent that also follows the enabled 12-unit resize path. The child drag lock comparison lives beside it in ",
14226
- React.createElement("code", null, " layout-lock-compare"),
14227
- "; toggle the lock, try dragging",
14228
- React.createElement("code", null, " deep-lock-child-a"),
14229
- " versus ",
14230
- React.createElement("code", null, " deep-free-child-a"),
14231
- ", then use the API move shortcut to confirm the policy suppresses built-in drag without freezing geometry.")),
14779
+ " for enabled 12-unit nested-child resize,",
14780
+ React.createElement("code", null, "layout-grid-empty-compare"),
14781
+ " for empty-versus-filled nested grid comparison, ",
14782
+ React.createElement("code", null, "layout-grid-mixed-modes"),
14783
+ "for direct-child layout mixing, and ",
14784
+ React.createElement("code", null, "layout-column-grid-tree"),
14785
+ " for a non-grid owner that still contains grid-layout descendants. The child drag lock comparison lives beside them in ",
14786
+ React.createElement("code", null, "layout-lock-compare"),
14787
+ ".")),
14232
14788
  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 }),
14233
14789
  React.createElement("div", { style: { display: 'grid', gap: 12, marginBottom: 12 } },
14234
14790
  React.createElement("div", { style: { display: 'flex', flexWrap: 'wrap', gap: 12, alignItems: 'center' } },
@@ -14344,6 +14900,9 @@ var AutoLayoutDemo = function () {
14344
14900
  React.createElement("ul", { style: { marginTop: 0, paddingLeft: 18, fontSize: 13 } },
14345
14901
  React.createElement("li", null, "Nested grid: target layout-grid-deep to inspect an outer grid where all three direct children, including the nested grid parent, use enabled 12-unit resize."),
14346
14902
  React.createElement("li", null, "Select deep-grid-nested-parent and drag a horizontal resize handle; it should snap in grid units and then reflow inner children inside the resized container."),
14903
+ React.createElement("li", null, "Empty nested grid: target layout-grid-empty-compare and compare empty-grid-slot against filled-grid-slot. The empty nested grid should still occupy its assigned outer slot."),
14904
+ React.createElement("li", null, "Mixed grid children: target layout-grid-mixed-modes to inspect one grid owner whose direct children use grid, vertical, and horizontal auto-layout modes side by side."),
14905
+ React.createElement("li", null, "Non-grid with grid descendants: target layout-column-grid-tree to inspect a vertical parent that still contains grid-layout containers deeper in the subtree."),
14347
14906
  React.createElement("li", null, "Lock comparison: target layout-lock-compare, toggle Lock comparison child drag, then compare deep-lock-child-a and deep-free-child-a."),
14348
14907
  React.createElement("li", null, "Use Move lock target via API after locking; the child should still reposition because the policy only suppresses built-in drag."),
14349
14908
  React.createElement("li", null, "Resize lock: with grid child width resize off, select grid-b and drag diagonally; width should stay fixed."),
@@ -16278,6 +16837,12 @@ var demoTabs = [
16278
16837
  description: selectionDemoConfig.description,
16279
16838
  Component: wrapSimpleDemo(selectionDemoConfig),
16280
16839
  },
16840
+ {
16841
+ id: elementVisibilitySelectionDemoConfig.id,
16842
+ title: elementVisibilitySelectionDemoConfig.title,
16843
+ description: elementVisibilitySelectionDemoConfig.description,
16844
+ Component: wrapSimpleDemo(elementVisibilitySelectionDemoConfig),
16845
+ },
16281
16846
  {
16282
16847
  id: eventHandlersDemoConfig.id,
16283
16848
  title: eventHandlersDemoConfig.title,