dockview-core 6.0.3 → 6.0.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.
@@ -725,10 +725,12 @@ var Tabs = /** @class */ (function (_super) {
725
725
  var index = this.indexOf(id);
726
726
  var tabToRemove = this._tabs.splice(index, 1)[0];
727
727
  this._tabMap.delete(id);
728
- var value = tabToRemove.value, disposable = tabToRemove.disposable;
729
- disposable.dispose();
730
- value.dispose();
731
- value.element.remove();
728
+ if (tabToRemove) {
729
+ var value = tabToRemove.value, disposable = tabToRemove.disposable;
730
+ disposable.dispose();
731
+ value.dispose();
732
+ value.element.remove();
733
+ }
732
734
  // If a non-source tab was removed during active drag, refresh positions
733
735
  if (this._animState) {
734
736
  this._animState.tabPositions = this.snapshotTabPositions();
@@ -1605,6 +1607,14 @@ var Tabs = /** @class */ (function (_super) {
1605
1607
  // handles panel transfer and tab group recreation.
1606
1608
  // Use the REAL tab group ID from transfer data, not the
1607
1609
  // potentially stale one from _animState.
1610
+ //
1611
+ // Clear any inline gap margin / shifting class applied to
1612
+ // destination tabs during dragover. Cross-group moves don't
1613
+ // run the FLIP path, and `moveGroupOrPanel` only inserts new
1614
+ // panels — it doesn't recreate existing destination tabs, so
1615
+ // their inline `margin-left` would otherwise persist as a
1616
+ // visible gap (issue #1243).
1617
+ this.resetTabTransforms();
1608
1618
  this.accessor.moveGroupOrPanel({
1609
1619
  from: {
1610
1620
  groupId: data.groupId,
@@ -1125,7 +1125,7 @@ var DockviewComponent = /** @class */ (function (_super) {
1125
1125
  // Collapse when the group becomes empty
1126
1126
  var autoCollapseDisposable = group.model.onDidRemovePanel(function () {
1127
1127
  if (group.model.isEmpty) {
1128
- _this._shellManager.setEdgeGroupCollapsed(position, true);
1128
+ _this.setEdgeGroupCollapsed(group, true);
1129
1129
  }
1130
1130
  });
1131
1131
  this._edgeGroupDisposables.set(position, autoCollapseDisposable);
@@ -1183,6 +1183,13 @@ var DockviewComponent = /** @class */ (function (_super) {
1183
1183
  for (var _b = __values(this._edgeGroups), _c = _b.next(); !_c.done; _c = _b.next()) {
1184
1184
  var _d = __read(_c.value, 2), position = _d[0], edgeGroup = _d[1];
1185
1185
  if (edgeGroup === group) {
1186
+ if (this._shellManager.isEdgeGroupCollapsed(position) ===
1187
+ collapsed) {
1188
+ // Skip the splitview resize on a no-op: with non-zero
1189
+ // theme gap, redundant resizeView calls accumulate
1190
+ // rounding drift that gradually shrinks the group.
1191
+ return;
1192
+ }
1186
1193
  this._shellManager.setEdgeGroupCollapsed(position, collapsed);
1187
1194
  edgeGroup.api._onDidCollapsedChange.fire({
1188
1195
  isCollapsed: collapsed,
@@ -2360,7 +2367,14 @@ var DockviewComponent = /** @class */ (function (_super) {
2360
2367
  var label = tabGroup.label;
2361
2368
  var color = tabGroup.color;
2362
2369
  var collapsed = tabGroup.collapsed;
2370
+ var componentParams = tabGroup.componentParams;
2363
2371
  var panelIds = __spreadArray([], __read(tabGroup.panelIds), false);
2372
+ // Capture the destination's grid location BEFORE potentially
2373
+ // removing the source group, in case source === destination and
2374
+ // the source becomes empty after panel removal.
2375
+ var referenceLocation = destinationTarget && destinationTarget !== 'center'
2376
+ ? (0, gridview_1.getGridLocation)(destinationGroup.element)
2377
+ : undefined;
2364
2378
  // Remove panels from the source group
2365
2379
  var removedPanels = this.movingLock(function () {
2366
2380
  return panelIds
@@ -2375,11 +2389,6 @@ var DockviewComponent = /** @class */ (function (_super) {
2375
2389
  if (removedPanels.length === 0) {
2376
2390
  return;
2377
2391
  }
2378
- if (!options.keepEmptyGroups &&
2379
- sourceGroup.model.size === 0 &&
2380
- sourceGroup !== destinationGroup) {
2381
- this.doRemoveGroup(sourceGroup, { skipActive: true });
2382
- }
2383
2392
  var addPanelsToGroup = function (targetGroup) {
2384
2393
  var e_28, _a, e_29, _b;
2385
2394
  _this.movingLock(function () {
@@ -2407,6 +2416,7 @@ var DockviewComponent = /** @class */ (function (_super) {
2407
2416
  label: label,
2408
2417
  color: color,
2409
2418
  collapsed: collapsed,
2419
+ componentParams: componentParams,
2410
2420
  });
2411
2421
  try {
2412
2422
  for (var removedPanels_1 = __values(removedPanels), removedPanels_1_1 = removedPanels_1.next(); !removedPanels_1_1.done; removedPanels_1_1 = removedPanels_1.next()) {
@@ -2441,17 +2451,30 @@ var DockviewComponent = /** @class */ (function (_super) {
2441
2451
  finally { if (e_29) throw e_29.error; }
2442
2452
  }
2443
2453
  };
2444
- if (!destinationTarget || destinationTarget === 'center') {
2445
- addPanelsToGroup(destinationGroup);
2454
+ var targetGroup;
2455
+ if (!destinationTarget ||
2456
+ destinationTarget === 'center' ||
2457
+ !referenceLocation) {
2458
+ targetGroup = destinationGroup;
2446
2459
  }
2447
2460
  else {
2448
- var referenceLocation = (0, gridview_1.getGridLocation)(destinationGroup.element);
2449
2461
  var dropLocation = (0, gridview_1.getRelativeLocation)(this.gridview.orientation, referenceLocation, destinationTarget);
2450
- var newGroup = this.createGroupAtLocation(dropLocation);
2451
- addPanelsToGroup(newGroup);
2462
+ targetGroup = this.createGroupAtLocation(dropLocation);
2452
2463
  }
2464
+ // Remove the source group if it became empty. We compare against
2465
+ // the actual targetGroup (which is a freshly-created group for
2466
+ // edge drops) rather than the originally-passed destinationGroup,
2467
+ // so a tab-group drag onto its own group's edge still cleans up
2468
+ // the now-empty source.
2469
+ if (!options.keepEmptyGroups &&
2470
+ sourceGroup.model.size === 0 &&
2471
+ sourceGroup !== targetGroup) {
2472
+ this.doRemoveGroup(sourceGroup, { skipActive: true });
2473
+ }
2474
+ addPanelsToGroup(targetGroup);
2453
2475
  };
2454
2476
  DockviewComponent.prototype.moveGroup = function (options) {
2477
+ var e_31, _a, e_32, _b, e_33, _c, e_34, _d;
2455
2478
  var _this = this;
2456
2479
  var from = options.from.group;
2457
2480
  var to = options.to.group;
@@ -2462,6 +2485,16 @@ var DockviewComponent = /** @class */ (function (_super) {
2462
2485
  var source = from;
2463
2486
  if (target === 'center') {
2464
2487
  var activePanel_1 = from.activePanel;
2488
+ // Snapshot tab group metadata before removing panels so we
2489
+ // can recreate the tab groups in the destination after the
2490
+ // panels are merged in.
2491
+ var tabGroupSnapshots = from.model.getTabGroups().map(function (tg) { return ({
2492
+ label: tg.label,
2493
+ color: tg.color,
2494
+ collapsed: tg.collapsed,
2495
+ componentParams: tg.componentParams,
2496
+ panelIds: __spreadArray([], __read(tg.panelIds), false),
2497
+ }); });
2465
2498
  var panels_3 = this.movingLock(function () {
2466
2499
  return __spreadArray([], __read(from.panels), false).map(function (p) {
2467
2500
  return from.model.removePanel(p.id, {
@@ -2473,7 +2506,7 @@ var DockviewComponent = /** @class */ (function (_super) {
2473
2506
  this.doRemoveGroup(from, { skipActive: true });
2474
2507
  }
2475
2508
  this.movingLock(function () {
2476
- var e_31, _a;
2509
+ var e_35, _a;
2477
2510
  try {
2478
2511
  for (var panels_4 = __values(panels_3), panels_4_1 = panels_4.next(); !panels_4_1.done; panels_4_1 = panels_4.next()) {
2479
2512
  var panel = panels_4_1.value;
@@ -2483,14 +2516,45 @@ var DockviewComponent = /** @class */ (function (_super) {
2483
2516
  });
2484
2517
  }
2485
2518
  }
2486
- catch (e_31_1) { e_31 = { error: e_31_1 }; }
2519
+ catch (e_35_1) { e_35 = { error: e_35_1 }; }
2487
2520
  finally {
2488
2521
  try {
2489
2522
  if (panels_4_1 && !panels_4_1.done && (_a = panels_4.return)) _a.call(panels_4);
2490
2523
  }
2491
- finally { if (e_31) throw e_31.error; }
2524
+ finally { if (e_35) throw e_35.error; }
2492
2525
  }
2493
2526
  });
2527
+ try {
2528
+ for (var tabGroupSnapshots_1 = __values(tabGroupSnapshots), tabGroupSnapshots_1_1 = tabGroupSnapshots_1.next(); !tabGroupSnapshots_1_1.done; tabGroupSnapshots_1_1 = tabGroupSnapshots_1.next()) {
2529
+ var snapshot = tabGroupSnapshots_1_1.value;
2530
+ var newTabGroup = to.model.createTabGroup({
2531
+ label: snapshot.label,
2532
+ color: snapshot.color,
2533
+ collapsed: snapshot.collapsed,
2534
+ componentParams: snapshot.componentParams,
2535
+ });
2536
+ try {
2537
+ for (var _e = (e_32 = void 0, __values(snapshot.panelIds)), _f = _e.next(); !_f.done; _f = _e.next()) {
2538
+ var panelId = _f.value;
2539
+ to.model.addPanelToTabGroup(newTabGroup.id, panelId);
2540
+ }
2541
+ }
2542
+ catch (e_32_1) { e_32 = { error: e_32_1 }; }
2543
+ finally {
2544
+ try {
2545
+ if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
2546
+ }
2547
+ finally { if (e_32) throw e_32.error; }
2548
+ }
2549
+ }
2550
+ }
2551
+ catch (e_31_1) { e_31 = { error: e_31_1 }; }
2552
+ finally {
2553
+ try {
2554
+ if (tabGroupSnapshots_1_1 && !tabGroupSnapshots_1_1.done && (_a = tabGroupSnapshots_1.return)) _a.call(tabGroupSnapshots_1);
2555
+ }
2556
+ finally { if (e_31) throw e_31.error; }
2557
+ }
2494
2558
  // Ensure group becomes active after move
2495
2559
  if (options.skipSetActive !== true) {
2496
2560
  // For center moves (merges), we need to ensure the target group is active
@@ -2514,6 +2578,17 @@ var DockviewComponent = /** @class */ (function (_super) {
2514
2578
  * positions `source` like any other moved group.
2515
2579
  */
2516
2580
  var activePanel_2 = from.activePanel;
2581
+ // Snapshot tab group metadata so the new group inherits
2582
+ // the tab grouping from the edge slot.
2583
+ var tabGroupSnapshots = from.model
2584
+ .getTabGroups()
2585
+ .map(function (tg) { return ({
2586
+ label: tg.label,
2587
+ color: tg.color,
2588
+ collapsed: tg.collapsed,
2589
+ componentParams: tg.componentParams,
2590
+ panelIds: __spreadArray([], __read(tg.panelIds), false),
2591
+ }); });
2517
2592
  var movedPanels_1 = this.movingLock(function () {
2518
2593
  return __spreadArray([], __read(from.panels), false).map(function (p) {
2519
2594
  return from.model.removePanel(p.id, { skipSetActive: true });
@@ -2521,7 +2596,7 @@ var DockviewComponent = /** @class */ (function (_super) {
2521
2596
  });
2522
2597
  source = this.createGroup();
2523
2598
  this.movingLock(function () {
2524
- var e_32, _a;
2599
+ var e_36, _a;
2525
2600
  try {
2526
2601
  for (var movedPanels_2 = __values(movedPanels_1), movedPanels_2_1 = movedPanels_2.next(); !movedPanels_2_1.done; movedPanels_2_1 = movedPanels_2.next()) {
2527
2602
  var panel = movedPanels_2_1.value;
@@ -2531,14 +2606,45 @@ var DockviewComponent = /** @class */ (function (_super) {
2531
2606
  });
2532
2607
  }
2533
2608
  }
2534
- catch (e_32_1) { e_32 = { error: e_32_1 }; }
2609
+ catch (e_36_1) { e_36 = { error: e_36_1 }; }
2535
2610
  finally {
2536
2611
  try {
2537
2612
  if (movedPanels_2_1 && !movedPanels_2_1.done && (_a = movedPanels_2.return)) _a.call(movedPanels_2);
2538
2613
  }
2539
- finally { if (e_32) throw e_32.error; }
2614
+ finally { if (e_36) throw e_36.error; }
2540
2615
  }
2541
2616
  });
2617
+ try {
2618
+ for (var tabGroupSnapshots_2 = __values(tabGroupSnapshots), tabGroupSnapshots_2_1 = tabGroupSnapshots_2.next(); !tabGroupSnapshots_2_1.done; tabGroupSnapshots_2_1 = tabGroupSnapshots_2.next()) {
2619
+ var snapshot = tabGroupSnapshots_2_1.value;
2620
+ var newTabGroup = source.model.createTabGroup({
2621
+ label: snapshot.label,
2622
+ color: snapshot.color,
2623
+ collapsed: snapshot.collapsed,
2624
+ componentParams: snapshot.componentParams,
2625
+ });
2626
+ try {
2627
+ for (var _g = (e_34 = void 0, __values(snapshot.panelIds)), _h = _g.next(); !_h.done; _h = _g.next()) {
2628
+ var panelId = _h.value;
2629
+ source.model.addPanelToTabGroup(newTabGroup.id, panelId);
2630
+ }
2631
+ }
2632
+ catch (e_34_1) { e_34 = { error: e_34_1 }; }
2633
+ finally {
2634
+ try {
2635
+ if (_h && !_h.done && (_d = _g.return)) _d.call(_g);
2636
+ }
2637
+ finally { if (e_34) throw e_34.error; }
2638
+ }
2639
+ }
2640
+ }
2641
+ catch (e_33_1) { e_33 = { error: e_33_1 }; }
2642
+ finally {
2643
+ try {
2644
+ if (tabGroupSnapshots_2_1 && !tabGroupSnapshots_2_1.done && (_c = tabGroupSnapshots_2.return)) _c.call(tabGroupSnapshots_2);
2645
+ }
2646
+ finally { if (e_33) throw e_33.error; }
2647
+ }
2542
2648
  }
2543
2649
  else {
2544
2650
  switch (from.api.location.type) {
@@ -2841,7 +2947,7 @@ var DockviewComponent = /** @class */ (function (_super) {
2841
2947
  }
2842
2948
  };
2843
2949
  DockviewComponent.prototype.updateTheme = function () {
2844
- var e_33, _a;
2950
+ var e_37, _a;
2845
2951
  var _b, _c, _d, _e, _f, _g, _h, _j, _k;
2846
2952
  var theme = (_b = this._options.theme) !== null && _b !== void 0 ? _b : theme_1.themeAbyss;
2847
2953
  // Apply the theme class only to the shell so edge groups and the
@@ -2882,12 +2988,12 @@ var DockviewComponent = /** @class */ (function (_super) {
2882
2988
  group.model.updateTabGroups();
2883
2989
  }
2884
2990
  }
2885
- catch (e_33_1) { e_33 = { error: e_33_1 }; }
2991
+ catch (e_37_1) { e_37 = { error: e_37_1 }; }
2886
2992
  finally {
2887
2993
  try {
2888
2994
  if (_m && !_m.done && (_a = _l.return)) _a.call(_l);
2889
2995
  }
2890
- finally { if (e_33) throw e_33.error; }
2996
+ finally { if (e_37) throw e_37.error; }
2891
2997
  }
2892
2998
  };
2893
2999
  return DockviewComponent;
@@ -1335,15 +1335,17 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
1335
1335
  if (position === 'center') {
1336
1336
  return;
1337
1337
  }
1338
- if (data.panelId === null) {
1339
- // don't allow group move to drop anywhere on self
1338
+ if (data.panelId === null && !data.tabGroupId) {
1339
+ // Full-group drops on self are a no-op.
1340
+ // Tab-group drags are partial moves: an edge drop
1341
+ // splits the layout and creates a new group.
1340
1342
  return;
1341
1343
  }
1342
1344
  }
1343
1345
  }
1344
1346
  if (type === 'header') {
1345
1347
  if (data.groupId === this.id) {
1346
- if (data.panelId === null) {
1348
+ if (data.panelId === null && !data.tabGroupId) {
1347
1349
  return;
1348
1350
  }
1349
1351
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * dockview-core
3
- * @version 6.0.3
3
+ * @version 6.0.6
4
4
  * @link https://github.com/mathuo/dockview
5
5
  * @license MIT
6
6
  */
@@ -7235,10 +7235,12 @@
7235
7235
  const index = this.indexOf(id);
7236
7236
  const tabToRemove = this._tabs.splice(index, 1)[0];
7237
7237
  this._tabMap.delete(id);
7238
- const { value, disposable } = tabToRemove;
7239
- disposable.dispose();
7240
- value.dispose();
7241
- value.element.remove();
7238
+ if (tabToRemove) {
7239
+ const { value, disposable } = tabToRemove;
7240
+ disposable.dispose();
7241
+ value.dispose();
7242
+ value.element.remove();
7243
+ }
7242
7244
  // If a non-source tab was removed during active drag, refresh positions
7243
7245
  if (this._animState) {
7244
7246
  this._animState.tabPositions = this.snapshotTabPositions();
@@ -7910,6 +7912,14 @@
7910
7912
  // handles panel transfer and tab group recreation.
7911
7913
  // Use the REAL tab group ID from transfer data, not the
7912
7914
  // potentially stale one from _animState.
7915
+ //
7916
+ // Clear any inline gap margin / shifting class applied to
7917
+ // destination tabs during dragover. Cross-group moves don't
7918
+ // run the FLIP path, and `moveGroupOrPanel` only inserts new
7919
+ // panels — it doesn't recreate existing destination tabs, so
7920
+ // their inline `margin-left` would otherwise persist as a
7921
+ // visible gap (issue #1243).
7922
+ this.resetTabTransforms();
7913
7923
  this.accessor.moveGroupOrPanel({
7914
7924
  from: {
7915
7925
  groupId: data.groupId,
@@ -9690,15 +9700,17 @@
9690
9700
  if (position === 'center') {
9691
9701
  return;
9692
9702
  }
9693
- if (data.panelId === null) {
9694
- // don't allow group move to drop anywhere on self
9703
+ if (data.panelId === null && !data.tabGroupId) {
9704
+ // Full-group drops on self are a no-op.
9705
+ // Tab-group drags are partial moves: an edge drop
9706
+ // splits the layout and creates a new group.
9695
9707
  return;
9696
9708
  }
9697
9709
  }
9698
9710
  }
9699
9711
  if (type === 'header') {
9700
9712
  if (data.groupId === this.id) {
9701
- if (data.panelId === null) {
9713
+ if (data.panelId === null && !data.tabGroupId) {
9702
9714
  return;
9703
9715
  }
9704
9716
  }
@@ -13566,7 +13578,7 @@
13566
13578
  // Collapse when the group becomes empty
13567
13579
  const autoCollapseDisposable = group.model.onDidRemovePanel(() => {
13568
13580
  if (group.model.isEmpty) {
13569
- this._shellManager.setEdgeGroupCollapsed(position, true);
13581
+ this.setEdgeGroupCollapsed(group, true);
13570
13582
  }
13571
13583
  });
13572
13584
  this._edgeGroupDisposables.set(position, autoCollapseDisposable);
@@ -13610,6 +13622,13 @@
13610
13622
  setEdgeGroupCollapsed(group, collapsed) {
13611
13623
  for (const [position, edgeGroup] of this._edgeGroups) {
13612
13624
  if (edgeGroup === group) {
13625
+ if (this._shellManager.isEdgeGroupCollapsed(position) ===
13626
+ collapsed) {
13627
+ // Skip the splitview resize on a no-op: with non-zero
13628
+ // theme gap, redundant resizeView calls accumulate
13629
+ // rounding drift that gradually shrinks the group.
13630
+ return;
13631
+ }
13613
13632
  this._shellManager.setEdgeGroupCollapsed(position, collapsed);
13614
13633
  edgeGroup.api._onDidCollapsedChange.fire({
13615
13634
  isCollapsed: collapsed,
@@ -14562,7 +14581,14 @@
14562
14581
  const label = tabGroup.label;
14563
14582
  const color = tabGroup.color;
14564
14583
  const collapsed = tabGroup.collapsed;
14584
+ const componentParams = tabGroup.componentParams;
14565
14585
  const panelIds = [...tabGroup.panelIds];
14586
+ // Capture the destination's grid location BEFORE potentially
14587
+ // removing the source group, in case source === destination and
14588
+ // the source becomes empty after panel removal.
14589
+ const referenceLocation = destinationTarget && destinationTarget !== 'center'
14590
+ ? getGridLocation(destinationGroup.element)
14591
+ : undefined;
14566
14592
  // Remove panels from the source group
14567
14593
  const removedPanels = this.movingLock(() => panelIds
14568
14594
  .map((pid) => sourceGroup.model.removePanel(pid, {
@@ -14573,11 +14599,6 @@
14573
14599
  if (removedPanels.length === 0) {
14574
14600
  return;
14575
14601
  }
14576
- if (!options.keepEmptyGroups &&
14577
- sourceGroup.model.size === 0 &&
14578
- sourceGroup !== destinationGroup) {
14579
- this.doRemoveGroup(sourceGroup, { skipActive: true });
14580
- }
14581
14602
  const addPanelsToGroup = (targetGroup) => {
14582
14603
  this.movingLock(() => {
14583
14604
  for (const panel of removedPanels) {
@@ -14593,6 +14614,7 @@
14593
14614
  label,
14594
14615
  color,
14595
14616
  collapsed,
14617
+ componentParams,
14596
14618
  });
14597
14619
  for (const panel of removedPanels) {
14598
14620
  targetGroup.model.addPanelToTabGroup(newTabGroup.id, panel.id);
@@ -14607,15 +14629,27 @@
14607
14629
  });
14608
14630
  }
14609
14631
  };
14610
- if (!destinationTarget || destinationTarget === 'center') {
14611
- addPanelsToGroup(destinationGroup);
14632
+ let targetGroup;
14633
+ if (!destinationTarget ||
14634
+ destinationTarget === 'center' ||
14635
+ !referenceLocation) {
14636
+ targetGroup = destinationGroup;
14612
14637
  }
14613
14638
  else {
14614
- const referenceLocation = getGridLocation(destinationGroup.element);
14615
14639
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
14616
- const newGroup = this.createGroupAtLocation(dropLocation);
14617
- addPanelsToGroup(newGroup);
14640
+ targetGroup = this.createGroupAtLocation(dropLocation);
14618
14641
  }
14642
+ // Remove the source group if it became empty. We compare against
14643
+ // the actual targetGroup (which is a freshly-created group for
14644
+ // edge drops) rather than the originally-passed destinationGroup,
14645
+ // so a tab-group drag onto its own group's edge still cleans up
14646
+ // the now-empty source.
14647
+ if (!options.keepEmptyGroups &&
14648
+ sourceGroup.model.size === 0 &&
14649
+ sourceGroup !== targetGroup) {
14650
+ this.doRemoveGroup(sourceGroup, { skipActive: true });
14651
+ }
14652
+ addPanelsToGroup(targetGroup);
14619
14653
  }
14620
14654
  moveGroup(options) {
14621
14655
  const from = options.from.group;
@@ -14627,6 +14661,16 @@
14627
14661
  let source = from;
14628
14662
  if (target === 'center') {
14629
14663
  const activePanel = from.activePanel;
14664
+ // Snapshot tab group metadata before removing panels so we
14665
+ // can recreate the tab groups in the destination after the
14666
+ // panels are merged in.
14667
+ const tabGroupSnapshots = from.model.getTabGroups().map((tg) => ({
14668
+ label: tg.label,
14669
+ color: tg.color,
14670
+ collapsed: tg.collapsed,
14671
+ componentParams: tg.componentParams,
14672
+ panelIds: [...tg.panelIds],
14673
+ }));
14630
14674
  const panels = this.movingLock(() => [...from.panels].map((p) => from.model.removePanel(p.id, {
14631
14675
  skipSetActive: true,
14632
14676
  })));
@@ -14641,6 +14685,17 @@
14641
14685
  });
14642
14686
  }
14643
14687
  });
14688
+ for (const snapshot of tabGroupSnapshots) {
14689
+ const newTabGroup = to.model.createTabGroup({
14690
+ label: snapshot.label,
14691
+ color: snapshot.color,
14692
+ collapsed: snapshot.collapsed,
14693
+ componentParams: snapshot.componentParams,
14694
+ });
14695
+ for (const panelId of snapshot.panelIds) {
14696
+ to.model.addPanelToTabGroup(newTabGroup.id, panelId);
14697
+ }
14698
+ }
14644
14699
  // Ensure group becomes active after move
14645
14700
  if (options.skipSetActive !== true) {
14646
14701
  // For center moves (merges), we need to ensure the target group is active
@@ -14664,6 +14719,17 @@
14664
14719
  * positions `source` like any other moved group.
14665
14720
  */
14666
14721
  const activePanel = from.activePanel;
14722
+ // Snapshot tab group metadata so the new group inherits
14723
+ // the tab grouping from the edge slot.
14724
+ const tabGroupSnapshots = from.model
14725
+ .getTabGroups()
14726
+ .map((tg) => ({
14727
+ label: tg.label,
14728
+ color: tg.color,
14729
+ collapsed: tg.collapsed,
14730
+ componentParams: tg.componentParams,
14731
+ panelIds: [...tg.panelIds],
14732
+ }));
14667
14733
  const movedPanels = this.movingLock(() => [...from.panels].map((p) => from.model.removePanel(p.id, { skipSetActive: true })));
14668
14734
  source = this.createGroup();
14669
14735
  this.movingLock(() => {
@@ -14674,6 +14740,17 @@
14674
14740
  });
14675
14741
  }
14676
14742
  });
14743
+ for (const snapshot of tabGroupSnapshots) {
14744
+ const newTabGroup = source.model.createTabGroup({
14745
+ label: snapshot.label,
14746
+ color: snapshot.color,
14747
+ collapsed: snapshot.collapsed,
14748
+ componentParams: snapshot.componentParams,
14749
+ });
14750
+ for (const panelId of snapshot.panelIds) {
14751
+ source.model.addPanelToTabGroup(newTabGroup.id, panelId);
14752
+ }
14753
+ }
14677
14754
  }
14678
14755
  else {
14679
14756
  switch (from.api.location.type) {