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.
@@ -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
  */
@@ -7199,10 +7199,12 @@ class Tabs extends CompositeDisposable {
7199
7199
  const index = this.indexOf(id);
7200
7200
  const tabToRemove = this._tabs.splice(index, 1)[0];
7201
7201
  this._tabMap.delete(id);
7202
- const { value, disposable } = tabToRemove;
7203
- disposable.dispose();
7204
- value.dispose();
7205
- value.element.remove();
7202
+ if (tabToRemove) {
7203
+ const { value, disposable } = tabToRemove;
7204
+ disposable.dispose();
7205
+ value.dispose();
7206
+ value.element.remove();
7207
+ }
7206
7208
  // If a non-source tab was removed during active drag, refresh positions
7207
7209
  if (this._animState) {
7208
7210
  this._animState.tabPositions = this.snapshotTabPositions();
@@ -7874,6 +7876,14 @@ class Tabs extends CompositeDisposable {
7874
7876
  // handles panel transfer and tab group recreation.
7875
7877
  // Use the REAL tab group ID from transfer data, not the
7876
7878
  // potentially stale one from _animState.
7879
+ //
7880
+ // Clear any inline gap margin / shifting class applied to
7881
+ // destination tabs during dragover. Cross-group moves don't
7882
+ // run the FLIP path, and `moveGroupOrPanel` only inserts new
7883
+ // panels — it doesn't recreate existing destination tabs, so
7884
+ // their inline `margin-left` would otherwise persist as a
7885
+ // visible gap (issue #1243).
7886
+ this.resetTabTransforms();
7877
7887
  this.accessor.moveGroupOrPanel({
7878
7888
  from: {
7879
7889
  groupId: data.groupId,
@@ -9654,15 +9664,17 @@ class DockviewGroupPanelModel extends CompositeDisposable {
9654
9664
  if (position === 'center') {
9655
9665
  return;
9656
9666
  }
9657
- if (data.panelId === null) {
9658
- // don't allow group move to drop anywhere on self
9667
+ if (data.panelId === null && !data.tabGroupId) {
9668
+ // Full-group drops on self are a no-op.
9669
+ // Tab-group drags are partial moves: an edge drop
9670
+ // splits the layout and creates a new group.
9659
9671
  return;
9660
9672
  }
9661
9673
  }
9662
9674
  }
9663
9675
  if (type === 'header') {
9664
9676
  if (data.groupId === this.id) {
9665
- if (data.panelId === null) {
9677
+ if (data.panelId === null && !data.tabGroupId) {
9666
9678
  return;
9667
9679
  }
9668
9680
  }
@@ -13530,7 +13542,7 @@ class DockviewComponent extends BaseGrid {
13530
13542
  // Collapse when the group becomes empty
13531
13543
  const autoCollapseDisposable = group.model.onDidRemovePanel(() => {
13532
13544
  if (group.model.isEmpty) {
13533
- this._shellManager.setEdgeGroupCollapsed(position, true);
13545
+ this.setEdgeGroupCollapsed(group, true);
13534
13546
  }
13535
13547
  });
13536
13548
  this._edgeGroupDisposables.set(position, autoCollapseDisposable);
@@ -13574,6 +13586,13 @@ class DockviewComponent extends BaseGrid {
13574
13586
  setEdgeGroupCollapsed(group, collapsed) {
13575
13587
  for (const [position, edgeGroup] of this._edgeGroups) {
13576
13588
  if (edgeGroup === group) {
13589
+ if (this._shellManager.isEdgeGroupCollapsed(position) ===
13590
+ collapsed) {
13591
+ // Skip the splitview resize on a no-op: with non-zero
13592
+ // theme gap, redundant resizeView calls accumulate
13593
+ // rounding drift that gradually shrinks the group.
13594
+ return;
13595
+ }
13577
13596
  this._shellManager.setEdgeGroupCollapsed(position, collapsed);
13578
13597
  edgeGroup.api._onDidCollapsedChange.fire({
13579
13598
  isCollapsed: collapsed,
@@ -14526,7 +14545,14 @@ class DockviewComponent extends BaseGrid {
14526
14545
  const label = tabGroup.label;
14527
14546
  const color = tabGroup.color;
14528
14547
  const collapsed = tabGroup.collapsed;
14548
+ const componentParams = tabGroup.componentParams;
14529
14549
  const panelIds = [...tabGroup.panelIds];
14550
+ // Capture the destination's grid location BEFORE potentially
14551
+ // removing the source group, in case source === destination and
14552
+ // the source becomes empty after panel removal.
14553
+ const referenceLocation = destinationTarget && destinationTarget !== 'center'
14554
+ ? getGridLocation(destinationGroup.element)
14555
+ : undefined;
14530
14556
  // Remove panels from the source group
14531
14557
  const removedPanels = this.movingLock(() => panelIds
14532
14558
  .map((pid) => sourceGroup.model.removePanel(pid, {
@@ -14537,11 +14563,6 @@ class DockviewComponent extends BaseGrid {
14537
14563
  if (removedPanels.length === 0) {
14538
14564
  return;
14539
14565
  }
14540
- if (!options.keepEmptyGroups &&
14541
- sourceGroup.model.size === 0 &&
14542
- sourceGroup !== destinationGroup) {
14543
- this.doRemoveGroup(sourceGroup, { skipActive: true });
14544
- }
14545
14566
  const addPanelsToGroup = (targetGroup) => {
14546
14567
  this.movingLock(() => {
14547
14568
  for (const panel of removedPanels) {
@@ -14557,6 +14578,7 @@ class DockviewComponent extends BaseGrid {
14557
14578
  label,
14558
14579
  color,
14559
14580
  collapsed,
14581
+ componentParams,
14560
14582
  });
14561
14583
  for (const panel of removedPanels) {
14562
14584
  targetGroup.model.addPanelToTabGroup(newTabGroup.id, panel.id);
@@ -14571,15 +14593,27 @@ class DockviewComponent extends BaseGrid {
14571
14593
  });
14572
14594
  }
14573
14595
  };
14574
- if (!destinationTarget || destinationTarget === 'center') {
14575
- addPanelsToGroup(destinationGroup);
14596
+ let targetGroup;
14597
+ if (!destinationTarget ||
14598
+ destinationTarget === 'center' ||
14599
+ !referenceLocation) {
14600
+ targetGroup = destinationGroup;
14576
14601
  }
14577
14602
  else {
14578
- const referenceLocation = getGridLocation(destinationGroup.element);
14579
14603
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
14580
- const newGroup = this.createGroupAtLocation(dropLocation);
14581
- addPanelsToGroup(newGroup);
14604
+ targetGroup = this.createGroupAtLocation(dropLocation);
14582
14605
  }
14606
+ // Remove the source group if it became empty. We compare against
14607
+ // the actual targetGroup (which is a freshly-created group for
14608
+ // edge drops) rather than the originally-passed destinationGroup,
14609
+ // so a tab-group drag onto its own group's edge still cleans up
14610
+ // the now-empty source.
14611
+ if (!options.keepEmptyGroups &&
14612
+ sourceGroup.model.size === 0 &&
14613
+ sourceGroup !== targetGroup) {
14614
+ this.doRemoveGroup(sourceGroup, { skipActive: true });
14615
+ }
14616
+ addPanelsToGroup(targetGroup);
14583
14617
  }
14584
14618
  moveGroup(options) {
14585
14619
  const from = options.from.group;
@@ -14591,6 +14625,16 @@ class DockviewComponent extends BaseGrid {
14591
14625
  let source = from;
14592
14626
  if (target === 'center') {
14593
14627
  const activePanel = from.activePanel;
14628
+ // Snapshot tab group metadata before removing panels so we
14629
+ // can recreate the tab groups in the destination after the
14630
+ // panels are merged in.
14631
+ const tabGroupSnapshots = from.model.getTabGroups().map((tg) => ({
14632
+ label: tg.label,
14633
+ color: tg.color,
14634
+ collapsed: tg.collapsed,
14635
+ componentParams: tg.componentParams,
14636
+ panelIds: [...tg.panelIds],
14637
+ }));
14594
14638
  const panels = this.movingLock(() => [...from.panels].map((p) => from.model.removePanel(p.id, {
14595
14639
  skipSetActive: true,
14596
14640
  })));
@@ -14605,6 +14649,17 @@ class DockviewComponent extends BaseGrid {
14605
14649
  });
14606
14650
  }
14607
14651
  });
14652
+ for (const snapshot of tabGroupSnapshots) {
14653
+ const newTabGroup = to.model.createTabGroup({
14654
+ label: snapshot.label,
14655
+ color: snapshot.color,
14656
+ collapsed: snapshot.collapsed,
14657
+ componentParams: snapshot.componentParams,
14658
+ });
14659
+ for (const panelId of snapshot.panelIds) {
14660
+ to.model.addPanelToTabGroup(newTabGroup.id, panelId);
14661
+ }
14662
+ }
14608
14663
  // Ensure group becomes active after move
14609
14664
  if (options.skipSetActive !== true) {
14610
14665
  // For center moves (merges), we need to ensure the target group is active
@@ -14628,6 +14683,17 @@ class DockviewComponent extends BaseGrid {
14628
14683
  * positions `source` like any other moved group.
14629
14684
  */
14630
14685
  const activePanel = from.activePanel;
14686
+ // Snapshot tab group metadata so the new group inherits
14687
+ // the tab grouping from the edge slot.
14688
+ const tabGroupSnapshots = from.model
14689
+ .getTabGroups()
14690
+ .map((tg) => ({
14691
+ label: tg.label,
14692
+ color: tg.color,
14693
+ collapsed: tg.collapsed,
14694
+ componentParams: tg.componentParams,
14695
+ panelIds: [...tg.panelIds],
14696
+ }));
14631
14697
  const movedPanels = this.movingLock(() => [...from.panels].map((p) => from.model.removePanel(p.id, { skipSetActive: true })));
14632
14698
  source = this.createGroup();
14633
14699
  this.movingLock(() => {
@@ -14638,6 +14704,17 @@ class DockviewComponent extends BaseGrid {
14638
14704
  });
14639
14705
  }
14640
14706
  });
14707
+ for (const snapshot of tabGroupSnapshots) {
14708
+ const newTabGroup = source.model.createTabGroup({
14709
+ label: snapshot.label,
14710
+ color: snapshot.color,
14711
+ collapsed: snapshot.collapsed,
14712
+ componentParams: snapshot.componentParams,
14713
+ });
14714
+ for (const panelId of snapshot.panelIds) {
14715
+ source.model.addPanelToTabGroup(newTabGroup.id, panelId);
14716
+ }
14717
+ }
14641
14718
  }
14642
14719
  else {
14643
14720
  switch (from.api.location.type) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dockview-core",
3
- "version": "6.0.3",
3
+ "version": "6.0.6",
4
4
  "description": "Zero dependency layout manager supporting tabs, groups, grids and splitviews for vanilla TypeScript",
5
5
  "keywords": [
6
6
  "splitview",