dockview-core 4.4.0 → 4.5.0

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/dist/cjs/api/dockviewGroupPanelApi.d.ts +4 -0
  2. package/dist/cjs/api/dockviewGroupPanelApi.js +4 -3
  3. package/dist/cjs/api/dockviewPanelApi.js +1 -0
  4. package/dist/cjs/dockview/components/tab/tab.d.ts +1 -0
  5. package/dist/cjs/dockview/components/tab/tab.js +4 -1
  6. package/dist/cjs/dockview/components/titlebar/tabs.d.ts +1 -0
  7. package/dist/cjs/dockview/components/titlebar/tabs.js +16 -0
  8. package/dist/cjs/dockview/components/titlebar/tabsContainer.d.ts +2 -0
  9. package/dist/cjs/dockview/components/titlebar/tabsContainer.js +4 -0
  10. package/dist/cjs/dockview/components/titlebar/voidContainer.d.ts +1 -0
  11. package/dist/cjs/dockview/components/titlebar/voidContainer.js +4 -1
  12. package/dist/cjs/dockview/dockviewComponent.d.ts +3 -0
  13. package/dist/cjs/dockview/dockviewComponent.js +142 -37
  14. package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts +10 -8
  15. package/dist/cjs/dockview/dockviewGroupPanelModel.js +3 -0
  16. package/dist/dockview-core.amd.js +131 -15
  17. package/dist/dockview-core.amd.js.map +1 -1
  18. package/dist/dockview-core.amd.min.js +2 -2
  19. package/dist/dockview-core.amd.min.js.map +1 -1
  20. package/dist/dockview-core.amd.min.noStyle.js +2 -2
  21. package/dist/dockview-core.amd.min.noStyle.js.map +1 -1
  22. package/dist/dockview-core.amd.noStyle.js +131 -15
  23. package/dist/dockview-core.amd.noStyle.js.map +1 -1
  24. package/dist/dockview-core.cjs.js +131 -15
  25. package/dist/dockview-core.cjs.js.map +1 -1
  26. package/dist/dockview-core.esm.js +131 -15
  27. package/dist/dockview-core.esm.js.map +1 -1
  28. package/dist/dockview-core.esm.min.js +2 -2
  29. package/dist/dockview-core.esm.min.js.map +1 -1
  30. package/dist/dockview-core.js +131 -15
  31. package/dist/dockview-core.js.map +1 -1
  32. package/dist/dockview-core.min.js +2 -2
  33. package/dist/dockview-core.min.js.map +1 -1
  34. package/dist/dockview-core.min.noStyle.js +2 -2
  35. package/dist/dockview-core.min.noStyle.js.map +1 -1
  36. package/dist/dockview-core.noStyle.js +131 -15
  37. package/dist/dockview-core.noStyle.js.map +1 -1
  38. package/dist/esm/api/dockviewGroupPanelApi.d.ts +4 -0
  39. package/dist/esm/api/dockviewGroupPanelApi.js +4 -3
  40. package/dist/esm/api/dockviewPanelApi.js +1 -0
  41. package/dist/esm/dockview/components/tab/tab.d.ts +1 -0
  42. package/dist/esm/dockview/components/tab/tab.js +4 -1
  43. package/dist/esm/dockview/components/titlebar/tabs.d.ts +1 -0
  44. package/dist/esm/dockview/components/titlebar/tabs.js +5 -0
  45. package/dist/esm/dockview/components/titlebar/tabsContainer.d.ts +2 -0
  46. package/dist/esm/dockview/components/titlebar/tabsContainer.js +4 -0
  47. package/dist/esm/dockview/components/titlebar/voidContainer.d.ts +1 -0
  48. package/dist/esm/dockview/components/titlebar/voidContainer.js +4 -1
  49. package/dist/esm/dockview/dockviewComponent.d.ts +3 -0
  50. package/dist/esm/dockview/dockviewComponent.js +105 -9
  51. package/dist/esm/dockview/dockviewGroupPanelModel.d.ts +10 -8
  52. package/dist/esm/dockview/dockviewGroupPanelModel.js +3 -0
  53. package/package.json +1 -1
@@ -11,6 +11,10 @@ export interface DockviewGroupMoveParams {
11
11
  * The index to place the panel within a group, only applicable if the placement is within an existing group
12
12
  */
13
13
  index?: number;
14
+ /**
15
+ * Whether to skip setting the group as active after moving
16
+ */
17
+ skipSetActive?: boolean;
14
18
  }
15
19
  export interface DockviewGroupPanelApi extends GridviewPanelApi {
16
20
  readonly onDidLocationChange: Event<DockviewGroupPanelFloatingChangeEvent>;
@@ -30,23 +30,24 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
30
30
  : window;
31
31
  }
32
32
  moveTo(options) {
33
- var _a, _b, _c;
33
+ var _a, _b, _c, _d;
34
34
  if (!this._group) {
35
35
  throw new Error(NOT_INITIALIZED_MESSAGE);
36
36
  }
37
37
  const group = (_a = options.group) !== null && _a !== void 0 ? _a : this.accessor.addGroup({
38
38
  direction: positionToDirection((_b = options.position) !== null && _b !== void 0 ? _b : 'right'),
39
- skipSetActive: true,
39
+ skipSetActive: (_c = options.skipSetActive) !== null && _c !== void 0 ? _c : false,
40
40
  });
41
41
  this.accessor.moveGroupOrPanel({
42
42
  from: { groupId: this._group.id },
43
43
  to: {
44
44
  group,
45
45
  position: options.group
46
- ? (_c = options.position) !== null && _c !== void 0 ? _c : 'center'
46
+ ? (_d = options.position) !== null && _d !== void 0 ? _d : 'center'
47
47
  : 'center',
48
48
  index: options.index,
49
49
  },
50
+ skipSetActive: options.skipSetActive,
50
51
  });
51
52
  }
52
53
  maximize() {
@@ -66,6 +66,7 @@ export class DockviewPanelApiImpl extends GridviewPanelApiImpl {
66
66
  : 'center',
67
67
  index: options.index,
68
68
  },
69
+ skipSetActive: options.skipSetActive,
69
70
  });
70
71
  }
71
72
  setTitle(title) {
@@ -23,5 +23,6 @@ export declare class Tab extends CompositeDisposable {
23
23
  constructor(panel: IDockviewPanel, accessor: DockviewComponent, group: DockviewGroupPanel);
24
24
  setActive(isActive: boolean): void;
25
25
  setContent(part: ITabRenderer): void;
26
+ updateDragAndDropState(): void;
26
27
  dispose(): void;
27
28
  }
@@ -41,7 +41,7 @@ export class Tab extends CompositeDisposable {
41
41
  this._element = document.createElement('div');
42
42
  this._element.className = 'dv-tab';
43
43
  this._element.tabIndex = 0;
44
- this._element.draggable = true;
44
+ this._element.draggable = !this.accessor.options.disableDnd;
45
45
  toggleClass(this.element, 'dv-inactive-tab', true);
46
46
  const dragHandler = new TabDragHandler(this._element, this.accessor, this.group, this.panel);
47
47
  this.dropTarget = new Droptarget(this._element, {
@@ -89,6 +89,9 @@ export class Tab extends CompositeDisposable {
89
89
  this.content = part;
90
90
  this._element.appendChild(this.content.element);
91
91
  }
92
+ updateDragAndDropState() {
93
+ this._element.draggable = !this.accessor.options.disableDnd;
94
+ }
92
95
  dispose() {
93
96
  super.dispose();
94
97
  }
@@ -42,4 +42,5 @@ export declare class Tabs extends CompositeDisposable {
42
42
  delete(id: string): void;
43
43
  private addTab;
44
44
  private toggleDropdown;
45
+ updateDragAndDropState(): void;
45
46
  }
@@ -186,4 +186,9 @@ export class Tabs extends CompositeDisposable {
186
186
  .map((x) => x.value.panel.id);
187
187
  this._onOverflowTabsChange.fire({ tabs, reset: options.reset });
188
188
  }
189
+ updateDragAndDropState() {
190
+ for (const tab of this._tabs) {
191
+ tab.value.updateDragAndDropState();
192
+ }
193
+ }
189
194
  }
@@ -38,6 +38,7 @@ export interface ITabsContainer extends IDisposable {
38
38
  setPrefixActionsElement(element: HTMLElement | undefined): void;
39
39
  show(): void;
40
40
  hide(): void;
41
+ updateDragAndDropState(): void;
41
42
  }
42
43
  export declare class TabsContainer extends CompositeDisposable implements ITabsContainer {
43
44
  private readonly accessor;
@@ -82,4 +83,5 @@ export declare class TabsContainer extends CompositeDisposable implements ITabsC
82
83
  closePanel(panel: IDockviewPanel): void;
83
84
  private updateClassnames;
84
85
  private toggleDropdown;
86
+ updateDragAndDropState(): void;
85
87
  }
@@ -228,4 +228,8 @@ export class TabsContainer extends CompositeDisposable {
228
228
  });
229
229
  }));
230
230
  }
231
+ updateDragAndDropState() {
232
+ this.tabs.updateDragAndDropState();
233
+ this.voidContainer.updateDragAndDropState();
234
+ }
231
235
  }
@@ -15,4 +15,5 @@ export declare class VoidContainer extends CompositeDisposable {
15
15
  readonly onWillShowOverlay: Event<WillShowOverlayEvent>;
16
16
  get element(): HTMLElement;
17
17
  constructor(accessor: DockviewComponent, group: DockviewGroupPanel);
18
+ updateDragAndDropState(): void;
18
19
  }
@@ -17,7 +17,7 @@ export class VoidContainer extends CompositeDisposable {
17
17
  this.onDragStart = this._onDragStart.event;
18
18
  this._element = document.createElement('div');
19
19
  this._element.className = 'dv-void-container';
20
- this._element.draggable = true;
20
+ this._element.draggable = !this.accessor.options.disableDnd;
21
21
  this.addDisposables(this._onDrop, this._onDragStart, addDisposableListener(this._element, 'pointerdown', () => {
22
22
  this.accessor.doSetGroupActive(this.group);
23
23
  }));
@@ -40,4 +40,7 @@ export class VoidContainer extends CompositeDisposable {
40
40
  this._onDrop.fire(event);
41
41
  }), this.dropTarget);
42
42
  }
43
+ updateDragAndDropState() {
44
+ this._element.draggable = !this.accessor.options.disableDnd;
45
+ }
43
46
  }
@@ -80,6 +80,7 @@ type MoveGroupOptions = {
80
80
  group: DockviewGroupPanel;
81
81
  position: Position;
82
82
  };
83
+ skipSetActive?: boolean;
83
84
  };
84
85
  type MoveGroupOrPanelOptions = {
85
86
  from: {
@@ -91,6 +92,7 @@ type MoveGroupOrPanelOptions = {
91
92
  position: Position;
92
93
  index?: number;
93
94
  };
95
+ skipSetActive?: boolean;
94
96
  };
95
97
  export interface FloatingGroupOptions {
96
98
  x?: number;
@@ -239,6 +241,7 @@ export declare class DockviewComponent extends BaseGrid<DockviewGroupPanel> impl
239
241
  private orthogonalize;
240
242
  updateOptions(options: Partial<DockviewComponentOptions>): void;
241
243
  layout(width: number, height: number, forceResize?: boolean | undefined): void;
244
+ private updateDragAndDropState;
242
245
  focus(): void;
243
246
  getGroupPanel(id: string): IDockviewPanel | undefined;
244
247
  setActivePanel(panel: IDockviewPanel): void;
@@ -728,7 +728,12 @@ export class DockviewComponent extends BaseGrid {
728
728
  }
729
729
  }
730
730
  this.updateDropTargetModel(options);
731
+ const oldDisableDnd = this.options.disableDnd;
731
732
  this._options = Object.assign(Object.assign({}, this.options), options);
733
+ const newDisableDnd = this.options.disableDnd;
734
+ if (oldDisableDnd !== newDisableDnd) {
735
+ this.updateDragAndDropState();
736
+ }
732
737
  if ('theme' in options) {
733
738
  this.updateTheme();
734
739
  }
@@ -743,6 +748,12 @@ export class DockviewComponent extends BaseGrid {
743
748
  }
744
749
  }
745
750
  }
751
+ updateDragAndDropState() {
752
+ // Update draggable state for all tabs and void containers
753
+ for (const group of this.groups) {
754
+ group.model.updateDragAndDropState();
755
+ }
756
+ }
746
757
  focus() {
747
758
  var _a;
748
759
  (_a = this.activeGroup) === null || _a === void 0 ? void 0 : _a.focus();
@@ -1330,6 +1341,7 @@ export class DockviewComponent extends BaseGrid {
1330
1341
  group: destinationGroup,
1331
1342
  position: destinationTarget,
1332
1343
  },
1344
+ skipSetActive: options.skipSetActive,
1333
1345
  });
1334
1346
  return;
1335
1347
  }
@@ -1348,11 +1360,17 @@ export class DockviewComponent extends BaseGrid {
1348
1360
  // remove the group and do not set a new group as active
1349
1361
  this.doRemoveGroup(sourceGroup, { skipActive: true });
1350
1362
  }
1351
- this.movingLock(() => destinationGroup.model.openPanel(removedPanel, {
1352
- index: destinationIndex,
1353
- skipSetGroupActive: true,
1354
- }));
1355
- this.doSetGroupAndPanelActive(destinationGroup);
1363
+ this.movingLock(() => {
1364
+ var _a;
1365
+ return destinationGroup.model.openPanel(removedPanel, {
1366
+ index: destinationIndex,
1367
+ skipSetActive: (_a = options.skipSetActive) !== null && _a !== void 0 ? _a : false,
1368
+ skipSetGroupActive: true,
1369
+ });
1370
+ });
1371
+ if (!options.skipSetActive) {
1372
+ this.doSetGroupAndPanelActive(destinationGroup);
1373
+ }
1356
1374
  this._onDidMovePanel.fire({
1357
1375
  panel: removedPanel,
1358
1376
  from: sourceGroup,
@@ -1455,6 +1473,7 @@ export class DockviewComponent extends BaseGrid {
1455
1473
  const target = options.to.position;
1456
1474
  if (target === 'center') {
1457
1475
  const activePanel = from.activePanel;
1476
+ const targetActivePanel = to.activePanel;
1458
1477
  const panels = this.movingLock(() => [...from.panels].map((p) => from.model.removePanel(p.id, {
1459
1478
  skipSetActive: true,
1460
1479
  })));
@@ -1464,12 +1483,23 @@ export class DockviewComponent extends BaseGrid {
1464
1483
  this.movingLock(() => {
1465
1484
  for (const panel of panels) {
1466
1485
  to.model.openPanel(panel, {
1467
- skipSetActive: panel !== activePanel,
1486
+ skipSetActive: true, // Always skip setting panels active during move
1468
1487
  skipSetGroupActive: true,
1469
1488
  });
1470
1489
  }
1471
1490
  });
1472
- this.doSetGroupAndPanelActive(to);
1491
+ if (!options.skipSetActive) {
1492
+ // Make the moved panel (from the source group) active
1493
+ if (activePanel) {
1494
+ this.doSetGroupAndPanelActive(to);
1495
+ }
1496
+ }
1497
+ else if (targetActivePanel) {
1498
+ // Ensure the target group's original active panel remains active
1499
+ to.model.openPanel(targetActivePanel, {
1500
+ skipSetGroupActive: true
1501
+ });
1502
+ }
1473
1503
  }
1474
1504
  else {
1475
1505
  switch (from.api.location.type) {
@@ -1489,12 +1519,39 @@ export class DockviewComponent extends BaseGrid {
1489
1519
  if (!selectedPopoutGroup) {
1490
1520
  throw new Error('failed to find popout group');
1491
1521
  }
1492
- selectedPopoutGroup.disposable.dispose();
1522
+ // Remove from popout groups list to prevent automatic restoration
1523
+ const index = this._popoutGroups.indexOf(selectedPopoutGroup);
1524
+ if (index >= 0) {
1525
+ this._popoutGroups.splice(index, 1);
1526
+ }
1527
+ // Clean up the reference group (ghost) if it exists and is hidden
1528
+ if (selectedPopoutGroup.referenceGroup) {
1529
+ const referenceGroup = this.getPanel(selectedPopoutGroup.referenceGroup);
1530
+ if (referenceGroup && !referenceGroup.api.isVisible) {
1531
+ this.doRemoveGroup(referenceGroup, { skipActive: true });
1532
+ }
1533
+ }
1534
+ // Manually dispose the window without triggering restoration
1535
+ selectedPopoutGroup.window.dispose();
1536
+ // Update group's location and containers for target
1537
+ if (to.api.location.type === 'grid') {
1538
+ from.model.renderContainer = this.overlayRenderContainer;
1539
+ from.model.dropTargetContainer = this.rootDropTargetContainer;
1540
+ from.model.location = { type: 'grid' };
1541
+ }
1542
+ else if (to.api.location.type === 'floating') {
1543
+ from.model.renderContainer = this.overlayRenderContainer;
1544
+ from.model.dropTargetContainer = this.rootDropTargetContainer;
1545
+ from.model.location = { type: 'floating' };
1546
+ }
1547
+ break;
1493
1548
  }
1494
1549
  }
1495
- if (from.api.location.type !== 'popout') {
1550
+ // For moves to grid locations
1551
+ if (to.api.location.type === 'grid') {
1496
1552
  const referenceLocation = getGridLocation(to.element);
1497
1553
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, target);
1554
+ // Add to grid for all moves targeting grid location
1498
1555
  let size;
1499
1556
  switch (this.gridview.orientation) {
1500
1557
  case Orientation.VERTICAL:
@@ -1512,10 +1569,49 @@ export class DockviewComponent extends BaseGrid {
1512
1569
  }
1513
1570
  this.gridview.addView(from, size, dropLocation);
1514
1571
  }
1572
+ else if (to.api.location.type === 'floating') {
1573
+ // For moves to floating locations, add as floating group
1574
+ // Get the position/size from the target floating group
1575
+ const targetFloatingGroup = this._floatingGroups.find((x) => x.group === to);
1576
+ if (targetFloatingGroup) {
1577
+ const box = targetFloatingGroup.overlay.toJSON();
1578
+ // Calculate position based on available properties
1579
+ let left, top;
1580
+ if ('left' in box) {
1581
+ left = box.left + 50;
1582
+ }
1583
+ else if ('right' in box) {
1584
+ left = Math.max(0, box.right - box.width - 50);
1585
+ }
1586
+ else {
1587
+ left = 50; // Default fallback
1588
+ }
1589
+ if ('top' in box) {
1590
+ top = box.top + 50;
1591
+ }
1592
+ else if ('bottom' in box) {
1593
+ top = Math.max(0, box.bottom - box.height - 50);
1594
+ }
1595
+ else {
1596
+ top = 50; // Default fallback
1597
+ }
1598
+ this.addFloatingGroup(from, {
1599
+ height: box.height,
1600
+ width: box.width,
1601
+ position: {
1602
+ left,
1603
+ top,
1604
+ },
1605
+ });
1606
+ }
1607
+ }
1515
1608
  }
1516
1609
  from.panels.forEach((panel) => {
1517
1610
  this._onDidMovePanel.fire({ panel, from });
1518
1611
  });
1612
+ if (!options.skipSetActive) {
1613
+ this.doSetGroupAndPanelActive(from);
1614
+ }
1519
1615
  }
1520
1616
  doSetGroupActive(group) {
1521
1617
  super.doSetGroupActive(group);
@@ -123,9 +123,16 @@ export type DockviewGroupLocation = {
123
123
  getWindow: () => Window;
124
124
  popoutUrl?: string;
125
125
  };
126
+ export interface WillShowOverlayLocationEventOptions {
127
+ readonly kind: DockviewGroupDropLocation;
128
+ readonly panel: IDockviewPanel | undefined;
129
+ readonly api: DockviewApi;
130
+ readonly group: DockviewGroupPanel | undefined;
131
+ getData: () => PanelTransfer | undefined;
132
+ }
126
133
  export declare class WillShowOverlayLocationEvent implements IDockviewEvent {
127
134
  private readonly event;
128
- private readonly options;
135
+ readonly options: WillShowOverlayLocationEventOptions;
129
136
  get kind(): DockviewGroupDropLocation;
130
137
  get nativeEvent(): DragEvent;
131
138
  get position(): Position;
@@ -135,13 +142,7 @@ export declare class WillShowOverlayLocationEvent implements IDockviewEvent {
135
142
  get group(): DockviewGroupPanel | undefined;
136
143
  preventDefault(): void;
137
144
  getData(): PanelTransfer | undefined;
138
- constructor(event: WillShowOverlayEvent, options: {
139
- kind: DockviewGroupDropLocation;
140
- panel: IDockviewPanel | undefined;
141
- api: DockviewApi;
142
- group: DockviewGroupPanel | undefined;
143
- getData: () => PanelTransfer | undefined;
144
- });
145
+ constructor(event: WillShowOverlayEvent, options: WillShowOverlayLocationEventOptions);
145
146
  }
146
147
  export declare class DockviewGroupPanelModel extends CompositeDisposable implements IDockviewGroupPanelModel {
147
148
  private readonly container;
@@ -252,6 +253,7 @@ export declare class DockviewGroupPanelModel extends CompositeDisposable impleme
252
253
  private updateContainer;
253
254
  canDisplayOverlay(event: DragEvent, position: Position, target: DockviewGroupDropLocation): boolean;
254
255
  private handleDropEvent;
256
+ updateDragAndDropState(): void;
255
257
  dispose(): void;
256
258
  }
257
259
  export {};
@@ -648,6 +648,9 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
648
648
  }));
649
649
  }
650
650
  }
651
+ updateDragAndDropState() {
652
+ this.tabsContainer.updateDragAndDropState();
653
+ }
651
654
  dispose() {
652
655
  var _a, _b, _c;
653
656
  super.dispose();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dockview-core",
3
- "version": "4.4.0",
3
+ "version": "4.5.0",
4
4
  "description": "Zero dependency layout manager supporting tabs, grids and splitviews",
5
5
  "keywords": [
6
6
  "splitview",