dockview 1.7.5 → 1.8.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 (50) hide show
  1. package/README.md +2 -1
  2. package/dist/cjs/dockview/dockview.d.ts +4 -2
  3. package/dist/cjs/dockview/dockview.d.ts.map +1 -1
  4. package/dist/cjs/dockview/dockview.js +23 -5
  5. package/dist/cjs/dockview/dockview.js.map +1 -1
  6. package/dist/cjs/dockview/{groupControlsRenderer.d.ts → headerActionsRenderer.d.ts} +6 -5
  7. package/dist/cjs/dockview/headerActionsRenderer.d.ts.map +1 -0
  8. package/dist/cjs/dockview/{groupControlsRenderer.js → headerActionsRenderer.js} +17 -16
  9. package/dist/cjs/dockview/{groupControlsRenderer.js.map → headerActionsRenderer.js.map} +1 -1
  10. package/dist/cjs/index.d.ts +1 -1
  11. package/dist/cjs/index.d.ts.map +1 -1
  12. package/dist/cjs/svg.d.ts +3 -3
  13. package/dist/cjs/svg.d.ts.map +1 -1
  14. package/dist/dockview.amd.js +839 -163
  15. package/dist/dockview.amd.js.map +1 -0
  16. package/dist/dockview.amd.min.js +3 -2
  17. package/dist/dockview.amd.min.js.map +1 -0
  18. package/dist/dockview.amd.min.noStyle.js +3 -2
  19. package/dist/dockview.amd.min.noStyle.js.map +1 -0
  20. package/dist/dockview.amd.noStyle.js +839 -163
  21. package/dist/dockview.amd.noStyle.js.map +1 -0
  22. package/dist/dockview.cjs.js +839 -163
  23. package/dist/dockview.cjs.js.map +1 -0
  24. package/dist/dockview.esm.js +840 -163
  25. package/dist/dockview.esm.js.map +1 -0
  26. package/dist/dockview.esm.min.js +3 -2
  27. package/dist/dockview.esm.min.js.map +1 -0
  28. package/dist/dockview.js +839 -163
  29. package/dist/dockview.js.map +1 -0
  30. package/dist/dockview.min.js +3 -2
  31. package/dist/dockview.min.js.map +1 -0
  32. package/dist/dockview.min.noStyle.js +3 -2
  33. package/dist/dockview.min.noStyle.js.map +1 -0
  34. package/dist/dockview.noStyle.js +839 -163
  35. package/dist/dockview.noStyle.js.map +1 -0
  36. package/dist/esm/dockview/dockview.d.ts +4 -2
  37. package/dist/esm/dockview/dockview.d.ts.map +1 -1
  38. package/dist/esm/dockview/dockview.js +23 -5
  39. package/dist/esm/dockview/dockview.js.map +1 -1
  40. package/dist/esm/dockview/{groupControlsRenderer.d.ts → headerActionsRenderer.d.ts} +6 -5
  41. package/dist/esm/dockview/headerActionsRenderer.d.ts.map +1 -0
  42. package/dist/esm/dockview/{groupControlsRenderer.js → headerActionsRenderer.js} +3 -2
  43. package/dist/esm/dockview/{groupControlsRenderer.js.map → headerActionsRenderer.js.map} +1 -1
  44. package/dist/esm/index.d.ts +1 -1
  45. package/dist/esm/index.d.ts.map +1 -1
  46. package/dist/esm/svg.d.ts +3 -3
  47. package/dist/esm/svg.d.ts.map +1 -1
  48. package/package.json +6 -6
  49. package/dist/cjs/dockview/groupControlsRenderer.d.ts.map +0 -1
  50. package/dist/esm/dockview/groupControlsRenderer.d.ts.map +0 -1
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * dockview
3
- * @version 1.7.5
3
+ * @version 1.8.0
4
4
  * @link https://github.com/mathuo/dockview
5
5
  * @license MIT
6
6
  */
@@ -304,6 +304,31 @@ class MutableDisposable {
304
304
  }
305
305
  }
306
306
 
307
+ function createComponent(id, componentName, components = {}, frameworkComponents = {}, createFrameworkComponent, fallback) {
308
+ const Component = typeof componentName === 'string'
309
+ ? components[componentName]
310
+ : undefined;
311
+ const FrameworkComponent = typeof componentName === 'string'
312
+ ? frameworkComponents[componentName]
313
+ : undefined;
314
+ if (Component && FrameworkComponent) {
315
+ throw new Error(`Cannot create '${id}'. component '${componentName}' registered as both a component and frameworkComponent`);
316
+ }
317
+ if (FrameworkComponent) {
318
+ if (!createFrameworkComponent) {
319
+ throw new Error(`Cannot create '${id}' for framework component '${componentName}'. you must register a frameworkPanelWrapper to use framework components`);
320
+ }
321
+ return createFrameworkComponent.createComponent(id, componentName, FrameworkComponent);
322
+ }
323
+ if (!Component) {
324
+ if (fallback) {
325
+ return fallback();
326
+ }
327
+ throw new Error(`Cannot create '${id}', no component '${componentName}' provided`);
328
+ }
329
+ return new Component(id, componentName);
330
+ }
331
+
307
332
  function watchElementResize(element, cb) {
308
333
  const observer = new ResizeObserver((entires) => {
309
334
  /**
@@ -417,31 +442,16 @@ class FocusTracker extends CompositeDisposable {
417
442
  refreshState() {
418
443
  this._refreshStateHandler();
419
444
  }
420
- }
421
-
422
- function createComponent(id, componentName, components = {}, frameworkComponents = {}, createFrameworkComponent, fallback) {
423
- const Component = typeof componentName === 'string'
424
- ? components[componentName]
425
- : undefined;
426
- const FrameworkComponent = typeof componentName === 'string'
427
- ? frameworkComponents[componentName]
428
- : undefined;
429
- if (Component && FrameworkComponent) {
430
- throw new Error(`Cannot create '${id}'. component '${componentName}' registered as both a component and frameworkComponent`);
431
- }
432
- if (FrameworkComponent) {
433
- if (!createFrameworkComponent) {
434
- throw new Error(`Cannot create '${id}' for framework component '${componentName}'. you must register a frameworkPanelWrapper to use framework components`);
435
- }
436
- return createFrameworkComponent.createComponent(id, componentName, FrameworkComponent);
437
- }
438
- if (!Component) {
439
- if (fallback) {
440
- return fallback();
441
- }
442
- throw new Error(`Cannot create '${id}', no component '${componentName}' provided`);
443
- }
444
- return new Component(id, componentName);
445
+ }
446
+ // quasi: apparently, but not really; seemingly
447
+ const QUASI_PREVENT_DEFAULT_KEY = 'dv-quasiPreventDefault';
448
+ // mark an event directly for other listeners to check
449
+ function quasiPreventDefault(event) {
450
+ event[QUASI_PREVENT_DEFAULT_KEY] = true;
451
+ }
452
+ // check if this event has been marked
453
+ function quasiDefaultPrevented(event) {
454
+ return event[QUASI_PREVENT_DEFAULT_KEY];
445
455
  }
446
456
 
447
457
  function tail(arr) {
@@ -492,6 +502,14 @@ function firstIndex(array, fn) {
492
502
  }
493
503
  }
494
504
  return -1;
505
+ }
506
+ function remove(array, value) {
507
+ const index = array.findIndex((t) => t === value);
508
+ if (index > -1) {
509
+ array.splice(index, 1);
510
+ return true;
511
+ }
512
+ return false;
495
513
  }
496
514
 
497
515
  const clamp = (value, min, max) => {
@@ -921,7 +939,7 @@ class Splitview {
921
939
  //add sash
922
940
  const sash = document.createElement('div');
923
941
  sash.className = 'sash';
924
- const onStart = (event) => {
942
+ const onPointerStart = (event) => {
925
943
  for (const item of this.viewItems) {
926
944
  item.enabled = false;
927
945
  }
@@ -980,11 +998,10 @@ class Splitview {
980
998
  size: snappedViewItem.size,
981
999
  };
982
1000
  }
983
- //
984
- const mousemove = (mousemoveEvent) => {
1001
+ const onPointerMove = (event) => {
985
1002
  const current = this._orientation === Orientation.HORIZONTAL
986
- ? mousemoveEvent.clientX
987
- : mousemoveEvent.clientY;
1003
+ ? event.clientX
1004
+ : event.clientY;
988
1005
  const delta = current - start;
989
1006
  this.resize(sashIndex, delta, sizes, undefined, undefined, minDelta, maxDelta, snapBefore, snapAfter);
990
1007
  this.distributeEmptySpace();
@@ -998,18 +1015,20 @@ class Splitview {
998
1015
  iframe.style.pointerEvents = 'auto';
999
1016
  }
1000
1017
  this.saveProportions();
1001
- document.removeEventListener('mousemove', mousemove);
1002
- document.removeEventListener('mouseup', end);
1018
+ document.removeEventListener('pointermove', onPointerMove);
1019
+ document.removeEventListener('pointerup', end);
1020
+ document.removeEventListener('pointercancel', end);
1003
1021
  this._onDidSashEnd.fire(undefined);
1004
1022
  };
1005
- document.addEventListener('mousemove', mousemove);
1006
- document.addEventListener('mouseup', end);
1023
+ document.addEventListener('pointermove', onPointerMove);
1024
+ document.addEventListener('pointerup', end);
1025
+ document.addEventListener('pointercancel', end);
1007
1026
  };
1008
- sash.addEventListener('mousedown', onStart);
1027
+ sash.addEventListener('pointerdown', onPointerStart);
1009
1028
  const sashItem = {
1010
1029
  container: sash,
1011
1030
  disposable: () => {
1012
- sash.removeEventListener('mousedown', onStart);
1031
+ sash.removeEventListener('pointerdown', onPointerStart);
1013
1032
  this.sashContainer.removeChild(sash);
1014
1033
  },
1015
1034
  };
@@ -1633,7 +1652,7 @@ class BranchNode extends CompositeDisposable {
1633
1652
  : true,
1634
1653
  };
1635
1654
  }),
1636
- size: this.size,
1655
+ size: this.orthogonalSize,
1637
1656
  };
1638
1657
  this.children = childDescriptors.map((c) => c.node);
1639
1658
  this.splitview = new Splitview(this.element, {
@@ -1696,7 +1715,7 @@ class BranchNode extends CompositeDisposable {
1696
1715
  layout(size, orthogonalSize) {
1697
1716
  this._size = orthogonalSize;
1698
1717
  this._orthogonalSize = size;
1699
- this.splitview.layout(this.size, this.orthogonalSize);
1718
+ this.splitview.layout(orthogonalSize, size);
1700
1719
  }
1701
1720
  addChild(node, size, index, skipLayout) {
1702
1721
  if (index < 0 || index > this.children.length) {
@@ -1921,9 +1940,9 @@ class Gridview {
1921
1940
  this._deserialize(json.root, orientation, deserializer, height);
1922
1941
  }
1923
1942
  _deserialize(root, orientation, deserializer, orthogonalSize) {
1924
- this.root = this._deserializeNode(root, orientation, deserializer, orthogonalSize, true);
1943
+ this.root = this._deserializeNode(root, orientation, deserializer, orthogonalSize);
1925
1944
  }
1926
- _deserializeNode(node, orientation, deserializer, orthogonalSize, isRoot = false) {
1945
+ _deserializeNode(node, orientation, deserializer, orthogonalSize) {
1927
1946
  let result;
1928
1947
  if (node.type === 'branch') {
1929
1948
  const serializedChildren = node.data;
@@ -1933,9 +1952,9 @@ class Gridview {
1933
1952
  visible: serializedChild.visible,
1934
1953
  };
1935
1954
  });
1936
- // HORIZONTAL => height=orthogonalsize width=size
1937
- // VERTICAL => height=size width=orthogonalsize
1938
- result = new BranchNode(orientation, this.proportionalLayout, this.styles, isRoot ? orthogonalSize : node.size, isRoot ? node.size : orthogonalSize, children);
1955
+ result = new BranchNode(orientation, this.proportionalLayout, this.styles, node.size, // <- orthogonal size - flips at each depth
1956
+ orthogonalSize, // <- size - flips at each depth
1957
+ children);
1939
1958
  }
1940
1959
  else {
1941
1960
  result = new LeafNode(deserializer.fromJSON(node), orientation, orthogonalSize, node.size);
@@ -1968,7 +1987,8 @@ class Gridview {
1968
1987
  const oldRoot = this.root;
1969
1988
  oldRoot.element.remove();
1970
1989
  this._root = new BranchNode(orthogonal(oldRoot.orientation), this.proportionalLayout, this.styles, this.root.orthogonalSize, this.root.size);
1971
- if (oldRoot.children.length === 1) {
1990
+ if (oldRoot.children.length === 0) ;
1991
+ else if (oldRoot.children.length === 1) {
1972
1992
  // can remove one level of redundant branching if there is only a single child
1973
1993
  const childReference = oldRoot.children[0];
1974
1994
  const child = oldRoot.removeChild(0); // remove to prevent disposal when disposing of unwanted root
@@ -2102,52 +2122,70 @@ class Gridview {
2102
2122
  if (!(parent instanceof BranchNode)) {
2103
2123
  throw new Error('Invalid location');
2104
2124
  }
2105
- const node = parent.children[index];
2106
- if (!(node instanceof LeafNode)) {
2125
+ const nodeToRemove = parent.children[index];
2126
+ if (!(nodeToRemove instanceof LeafNode)) {
2107
2127
  throw new Error('Invalid location');
2108
2128
  }
2109
2129
  parent.removeChild(index, sizing);
2110
- if (parent.children.length === 0) {
2111
- return node.view;
2112
- }
2113
- if (parent.children.length > 1) {
2114
- return node.view;
2115
- }
2130
+ nodeToRemove.dispose();
2131
+ if (parent.children.length !== 1) {
2132
+ return nodeToRemove.view;
2133
+ }
2134
+ // if the parent has only one child and we know the parent is a BranchNode we can make the tree
2135
+ // more efficiently spaced by replacing the parent BranchNode with the child.
2136
+ // if that child is a LeafNode then we simply replace the BranchNode with the child otherwise if the child
2137
+ // is a BranchNode too we should spread it's children into the grandparent.
2138
+ // refer to the remaining child as the sibling
2116
2139
  const sibling = parent.children[0];
2117
2140
  if (pathToParent.length === 0) {
2118
- // parent is root
2141
+ // if the parent is root
2119
2142
  if (sibling instanceof LeafNode) {
2120
- return node.view;
2143
+ // if the sibling is a leaf node no action is required
2144
+ return nodeToRemove.view;
2121
2145
  }
2122
- // we must promote sibling to be the new root
2146
+ // otherwise the sibling is a branch node. since the parent is the root and the root has only one child
2147
+ // which is a branch node we can just set this branch node to be the new root node
2148
+ // for good housekeeping we'll removing the sibling from it's existing tree
2123
2149
  parent.removeChild(0, sizing);
2150
+ // and set that sibling node to be root
2124
2151
  this.root = sibling;
2125
- return node.view;
2152
+ return nodeToRemove.view;
2126
2153
  }
2154
+ // otherwise the parent is apart of a large sub-tree
2127
2155
  const [grandParent, ..._] = [...pathToParent].reverse();
2128
2156
  const [parentIndex, ...__] = [...rest].reverse();
2129
2157
  const isSiblingVisible = parent.isChildVisible(0);
2158
+ // either way we need to remove the sibling from it's existing tree
2130
2159
  parent.removeChild(0, sizing);
2160
+ // note the sizes of all of the grandparents children
2131
2161
  const sizes = grandParent.children.map((_size, i) => grandParent.getChildSize(i));
2132
- grandParent.removeChild(parentIndex, sizing);
2162
+ // remove the parent from the grandparent since we are moving the sibling to take the parents place
2163
+ // this parent is no longer used and can be disposed of
2164
+ grandParent.removeChild(parentIndex, sizing).dispose();
2133
2165
  if (sibling instanceof BranchNode) {
2166
+ // replace the parent with the siblings children
2134
2167
  sizes.splice(parentIndex, 1, ...sibling.children.map((c) => c.size));
2168
+ // and add those siblings to the grandparent
2135
2169
  for (let i = 0; i < sibling.children.length; i++) {
2136
2170
  const child = sibling.children[i];
2137
2171
  grandParent.addChild(child, child.size, parentIndex + i);
2138
2172
  }
2139
2173
  }
2140
2174
  else {
2175
+ // otherwise create a new leaf node and add that to the grandparent
2141
2176
  const newSibling = new LeafNode(sibling.view, orthogonal(sibling.orientation), sibling.size);
2142
2177
  const siblingSizing = isSiblingVisible
2143
2178
  ? sibling.orthogonalSize
2144
2179
  : Sizing.Invisible(sibling.orthogonalSize);
2145
2180
  grandParent.addChild(newSibling, siblingSizing, parentIndex);
2146
2181
  }
2182
+ // the containing node of the sibling is no longer required and can be disposed of
2183
+ sibling.dispose();
2184
+ // resize everything
2147
2185
  for (let i = 0; i < sizes.length; i++) {
2148
2186
  grandParent.resizeChild(i, sizes[i]);
2149
2187
  }
2150
- return node.view;
2188
+ return nodeToRemove.view;
2151
2189
  }
2152
2190
  layout(width, height) {
2153
2191
  const [size, orthogonalSize] = this.root.orientation === Orientation.HORIZONTAL
@@ -2466,6 +2504,9 @@ class DockviewApi {
2466
2504
  addPanel(options) {
2467
2505
  return this.component.addPanel(options);
2468
2506
  }
2507
+ removePanel(panel) {
2508
+ this.component.removePanel(panel);
2509
+ }
2469
2510
  addGroup(options) {
2470
2511
  return this.component.addGroup(options);
2471
2512
  }
@@ -2484,6 +2525,9 @@ class DockviewApi {
2484
2525
  getGroup(id) {
2485
2526
  return this.component.getPanel(id);
2486
2527
  }
2528
+ addFloatingGroup(item, coord) {
2529
+ return this.component.addFloatingGroup(item, coord);
2530
+ }
2487
2531
  fromJSON(data) {
2488
2532
  this.component.fromJSON(data);
2489
2533
  }
@@ -2576,10 +2620,14 @@ class Droptarget extends CompositeDisposable {
2576
2620
  this._onDrop = new Emitter();
2577
2621
  this.onDrop = this._onDrop.event;
2578
2622
  // use a set to take advantage of #<set>.has
2579
- const acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
2623
+ this._acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
2580
2624
  this.addDisposables(this._onDrop, new DragAndDropObserver(this.element, {
2581
2625
  onDragEnter: () => undefined,
2582
2626
  onDragOver: (e) => {
2627
+ if (this._acceptedTargetZonesSet.size === 0) {
2628
+ this.removeDropTarget();
2629
+ return;
2630
+ }
2583
2631
  const width = this.element.clientWidth;
2584
2632
  const height = this.element.clientHeight;
2585
2633
  if (width === 0 || height === 0) {
@@ -2588,20 +2636,28 @@ class Droptarget extends CompositeDisposable {
2588
2636
  const rect = e.currentTarget.getBoundingClientRect();
2589
2637
  const x = e.clientX - rect.left;
2590
2638
  const y = e.clientY - rect.top;
2591
- const quadrant = this.calculateQuadrant(acceptedTargetZonesSet, x, y, width, height);
2592
- if (quadrant === null) {
2639
+ const quadrant = this.calculateQuadrant(this._acceptedTargetZonesSet, x, y, width, height);
2640
+ /**
2641
+ * If the event has already been used by another DropTarget instance
2642
+ * then don't show a second drop target, only one target should be
2643
+ * active at any one time
2644
+ */
2645
+ if (this.isAlreadyUsed(e) || quadrant === null) {
2593
2646
  // no drop target should be displayed
2594
2647
  this.removeDropTarget();
2595
2648
  return;
2596
2649
  }
2597
2650
  if (typeof this.options.canDisplayOverlay === 'boolean') {
2598
2651
  if (!this.options.canDisplayOverlay) {
2652
+ this.removeDropTarget();
2599
2653
  return;
2600
2654
  }
2601
2655
  }
2602
2656
  else if (!this.options.canDisplayOverlay(e, quadrant)) {
2657
+ this.removeDropTarget();
2603
2658
  return;
2604
2659
  }
2660
+ this.markAsUsed(e);
2605
2661
  if (!this.targetElement) {
2606
2662
  this.targetElement = document.createElement('div');
2607
2663
  this.targetElement.className = 'drop-target-dropzone';
@@ -2612,12 +2668,6 @@ class Droptarget extends CompositeDisposable {
2612
2668
  this.element.classList.add('drop-target');
2613
2669
  this.element.append(this.targetElement);
2614
2670
  }
2615
- if (this.options.acceptedTargetZones.length === 0) {
2616
- return;
2617
- }
2618
- if (!this.targetElement || !this.overlayElement) {
2619
- return;
2620
- }
2621
2671
  this.toggleClasses(quadrant, width, height);
2622
2672
  this.setState(quadrant);
2623
2673
  },
@@ -2640,10 +2690,26 @@ class Droptarget extends CompositeDisposable {
2640
2690
  },
2641
2691
  }));
2642
2692
  }
2693
+ setTargetZones(acceptedTargetZones) {
2694
+ this._acceptedTargetZonesSet = new Set(acceptedTargetZones);
2695
+ }
2643
2696
  dispose() {
2644
2697
  this.removeDropTarget();
2645
2698
  super.dispose();
2646
2699
  }
2700
+ /**
2701
+ * Add a property to the event object for other potential listeners to check
2702
+ */
2703
+ markAsUsed(event) {
2704
+ event[Droptarget.USED_EVENT_ID] = true;
2705
+ }
2706
+ /**
2707
+ * Check is the event has already been used by another instance od DropTarget
2708
+ */
2709
+ isAlreadyUsed(event) {
2710
+ const value = event[Droptarget.USED_EVENT_ID];
2711
+ return typeof value === 'boolean' && value;
2712
+ }
2647
2713
  toggleClasses(quadrant, width, height) {
2648
2714
  var _a, _b, _c, _d;
2649
2715
  if (!this.overlayElement) {
@@ -2738,6 +2804,7 @@ class Droptarget extends CompositeDisposable {
2738
2804
  }
2739
2805
  }
2740
2806
  }
2807
+ Droptarget.USED_EVENT_ID = '__dockview_droptarget_event_is_used__';
2741
2808
  function calculateQuadrantAsPercentage(overlayType, x, y, width, height, threshold) {
2742
2809
  const xp = (100 * x) / width;
2743
2810
  const yp = (100 * y) / height;
@@ -2867,8 +2934,15 @@ class DragHandler extends CompositeDisposable {
2867
2934
  this.addDisposables(this._onDragStart, this.dataDisposable, this.pointerEventsDisposable);
2868
2935
  this.configure();
2869
2936
  }
2937
+ isCancelled(_event) {
2938
+ return false;
2939
+ }
2870
2940
  configure() {
2871
2941
  this.addDisposables(this._onDragStart, addDisposableListener(this.el, 'dragstart', (event) => {
2942
+ if (this.isCancelled(event)) {
2943
+ event.preventDefault();
2944
+ return;
2945
+ }
2872
2946
  const iframes = [
2873
2947
  ...getElementsByTagName('iframe'),
2874
2948
  ...getElementsByTagName('webview'),
@@ -2942,13 +3016,6 @@ class Tab extends CompositeDisposable {
2942
3016
  if (event.defaultPrevented) {
2943
3017
  return;
2944
3018
  }
2945
- /**
2946
- * TODO: alternative to stopPropagation
2947
- *
2948
- * I need to stop the event propagation here since otherwise it'll be intercepted by event handlers
2949
- * on the tabs-container. I cannot use event.preventDefault() since I need the on DragStart event to occur
2950
- */
2951
- event.stopPropagation();
2952
3019
  this._onChanged.fire(event);
2953
3020
  }));
2954
3021
  this.droptarget = new Droptarget(this._element, {
@@ -3006,6 +3073,22 @@ class GroupDragHandler extends DragHandler {
3006
3073
  this.accessorId = accessorId;
3007
3074
  this.group = group;
3008
3075
  this.panelTransfer = LocalSelectionTransfer.getInstance();
3076
+ this.addDisposables(addDisposableListener(element, 'mousedown', (e) => {
3077
+ if (e.shiftKey) {
3078
+ /**
3079
+ * You cannot call e.preventDefault() because that will prevent drag events from firing
3080
+ * but we also need to stop any group overlay drag events from occuring
3081
+ * Use a custom event marker that can be checked by the overlay drag events
3082
+ */
3083
+ quasiPreventDefault(e);
3084
+ }
3085
+ }, true));
3086
+ }
3087
+ isCancelled(_event) {
3088
+ if (this.group.api.isFloating && !_event.shiftKey) {
3089
+ return true;
3090
+ }
3091
+ return false;
3009
3092
  }
3010
3093
  getData(dataTransfer) {
3011
3094
  this.panelTransfer.setData([new PanelTransfer(this.accessorId, this.group.id, null)], PanelTransfer.prototype);
@@ -3096,17 +3179,30 @@ class TabsContainer extends CompositeDisposable {
3096
3179
  hide() {
3097
3180
  this._element.style.display = 'none';
3098
3181
  }
3099
- setActionElement(element) {
3100
- if (this.actions === element) {
3182
+ setRightActionsElement(element) {
3183
+ if (this.rightActions === element) {
3184
+ return;
3185
+ }
3186
+ if (this.rightActions) {
3187
+ this.rightActions.remove();
3188
+ this.rightActions = undefined;
3189
+ }
3190
+ if (element) {
3191
+ this.rightActionsContainer.appendChild(element);
3192
+ this.rightActions = element;
3193
+ }
3194
+ }
3195
+ setLeftActionsElement(element) {
3196
+ if (this.leftActions === element) {
3101
3197
  return;
3102
3198
  }
3103
- if (this.actions) {
3104
- this.actions.remove();
3105
- this.actions = undefined;
3199
+ if (this.leftActions) {
3200
+ this.leftActions.remove();
3201
+ this.leftActions = undefined;
3106
3202
  }
3107
3203
  if (element) {
3108
- this.actionContainer.appendChild(element);
3109
- this.actions = element;
3204
+ this.leftActionsContainer.appendChild(element);
3205
+ this.leftActions = element;
3110
3206
  }
3111
3207
  }
3112
3208
  get element() {
@@ -3141,19 +3237,35 @@ class TabsContainer extends CompositeDisposable {
3141
3237
  toggleClass(this._element, 'dv-single-tab', this.size === 1);
3142
3238
  }
3143
3239
  }));
3144
- this.actionContainer = document.createElement('div');
3145
- this.actionContainer.className = 'action-container';
3240
+ this.rightActionsContainer = document.createElement('div');
3241
+ this.rightActionsContainer.className = 'right-actions-container';
3242
+ this.leftActionsContainer = document.createElement('div');
3243
+ this.leftActionsContainer.className = 'left-actions-container';
3146
3244
  this.tabContainer = document.createElement('div');
3147
3245
  this.tabContainer.className = 'tabs-container';
3148
3246
  this.voidContainer = new VoidContainer(this.accessor, this.group);
3149
3247
  this._element.appendChild(this.tabContainer);
3248
+ this._element.appendChild(this.leftActionsContainer);
3150
3249
  this._element.appendChild(this.voidContainer.element);
3151
- this._element.appendChild(this.actionContainer);
3250
+ this._element.appendChild(this.rightActionsContainer);
3152
3251
  this.addDisposables(this.voidContainer, this.voidContainer.onDrop((event) => {
3153
3252
  this._onDrop.fire({
3154
3253
  event: event.nativeEvent,
3155
3254
  index: this.tabs.length,
3156
3255
  });
3256
+ }), addDisposableListener(this.voidContainer.element, 'mousedown', (event) => {
3257
+ const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3258
+ if (isFloatingGroupsEnabled &&
3259
+ event.shiftKey &&
3260
+ !this.group.api.isFloating) {
3261
+ event.preventDefault();
3262
+ const { top, left } = this.element.getBoundingClientRect();
3263
+ const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
3264
+ this.accessor.addFloatingGroup(this.group, {
3265
+ x: left - rootLeft + 20,
3266
+ y: top - rootTop + 20,
3267
+ }, { inDragMode: true });
3268
+ }
3157
3269
  }), addDisposableListener(this.tabContainer, 'mousedown', (event) => {
3158
3270
  if (event.defaultPrevented) {
3159
3271
  return;
@@ -3207,6 +3319,21 @@ class TabsContainer extends CompositeDisposable {
3207
3319
  tabToAdd.setContent(panel.view.tab);
3208
3320
  const disposable = CompositeDisposable.from(tabToAdd.onChanged((event) => {
3209
3321
  var _a;
3322
+ const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3323
+ const isFloatingWithOnePanel = this.group.api.isFloating && this.size === 1;
3324
+ if (isFloatingGroupsEnabled &&
3325
+ !isFloatingWithOnePanel &&
3326
+ event.shiftKey) {
3327
+ event.preventDefault();
3328
+ const panel = this.accessor.getGroupPanel(tabToAdd.panelId);
3329
+ const { top, left } = tabToAdd.element.getBoundingClientRect();
3330
+ const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
3331
+ this.accessor.addFloatingGroup(panel, {
3332
+ x: left - rootLeft,
3333
+ y: top - rootTop,
3334
+ }, { inDragMode: true });
3335
+ return;
3336
+ }
3210
3337
  const alreadyFocused = panel.id === ((_a = this.group.model.activePanel) === null || _a === void 0 ? void 0 : _a.id) &&
3211
3338
  this.group.model.isContentFocused;
3212
3339
  const isLeftClick = event.button === 0;
@@ -3276,6 +3403,17 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3276
3403
  }
3277
3404
  return isAncestor(document.activeElement, this.contentContainer.element);
3278
3405
  }
3406
+ get isFloating() {
3407
+ return this._isFloating;
3408
+ }
3409
+ set isFloating(value) {
3410
+ this._isFloating = value;
3411
+ this.dropTarget.setTargetZones(value ? ['center'] : ['top', 'bottom', 'left', 'right', 'center']);
3412
+ toggleClass(this.container, 'dv-groupview-floating', value);
3413
+ this.groupPanel.api._onDidFloatingStateChange.fire({
3414
+ isFloating: this.isFloating,
3415
+ });
3416
+ }
3279
3417
  constructor(container, accessor, id, options, groupPanel) {
3280
3418
  super();
3281
3419
  this.container = container;
@@ -3285,6 +3423,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3285
3423
  this.groupPanel = groupPanel;
3286
3424
  this._isGroupActive = false;
3287
3425
  this._locked = false;
3426
+ this._isFloating = false;
3288
3427
  this.mostRecentlyUsed = [];
3289
3428
  this._onDidChange = new Emitter();
3290
3429
  this.onDidChange = this._onDidChange.event;
@@ -3301,7 +3440,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3301
3440
  this.onDidRemovePanel = this._onDidRemovePanel.event;
3302
3441
  this._onDidActivePanelChange = new Emitter();
3303
3442
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
3304
- this.container.classList.add('groupview');
3443
+ toggleClass(this.container, 'groupview', true);
3305
3444
  this.tabsContainer = new TabsContainer(this.accessor, this.groupPanel);
3306
3445
  this.contentContainer = new ContentContainer();
3307
3446
  this.dropTarget = new Droptarget(this.contentContainer.element, {
@@ -3311,6 +3450,9 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3311
3450
  return false;
3312
3451
  }
3313
3452
  const data = getPanelData();
3453
+ if (!data && event.shiftKey && !this.isFloating) {
3454
+ return false;
3455
+ }
3314
3456
  if (data && data.viewId === this.accessor.id) {
3315
3457
  if (data.groupId === this.id) {
3316
3458
  if (position === 'center') {
@@ -3355,14 +3497,25 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3355
3497
  // correctly initialized
3356
3498
  this.setActive(this.isActive, true, true);
3357
3499
  this.updateContainer();
3358
- if (this.accessor.options.createGroupControlElement) {
3359
- this._control = this.accessor.options.createGroupControlElement(this.groupPanel);
3360
- this.addDisposables(this._control);
3361
- this._control.init({
3500
+ if (this.accessor.options.createRightHeaderActionsElement) {
3501
+ this._rightHeaderActions =
3502
+ this.accessor.options.createRightHeaderActionsElement(this.groupPanel);
3503
+ this.addDisposables(this._rightHeaderActions);
3504
+ this._rightHeaderActions.init({
3505
+ containerApi: new DockviewApi(this.accessor),
3506
+ api: this.groupPanel.api,
3507
+ });
3508
+ this.tabsContainer.setRightActionsElement(this._rightHeaderActions.element);
3509
+ }
3510
+ if (this.accessor.options.createLeftHeaderActionsElement) {
3511
+ this._leftHeaderActions =
3512
+ this.accessor.options.createLeftHeaderActionsElement(this.groupPanel);
3513
+ this.addDisposables(this._leftHeaderActions);
3514
+ this._leftHeaderActions.init({
3362
3515
  containerApi: new DockviewApi(this.accessor),
3363
3516
  api: this.groupPanel.api,
3364
3517
  });
3365
- this.tabsContainer.setActionElement(this._control.element);
3518
+ this.tabsContainer.setLeftActionsElement(this._leftHeaderActions.element);
3366
3519
  }
3367
3520
  }
3368
3521
  indexOf(panel) {
@@ -3495,7 +3648,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3495
3648
  return this._activePanel === panel;
3496
3649
  }
3497
3650
  updateActions(element) {
3498
- this.tabsContainer.setActionElement(element);
3651
+ this.tabsContainer.setRightActionsElement(element);
3499
3652
  }
3500
3653
  setActive(isGroupActive, skipFocus = false, force = false) {
3501
3654
  var _a, _b, _c, _d;
@@ -3667,9 +3820,10 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3667
3820
  }
3668
3821
  }
3669
3822
  dispose() {
3670
- var _a, _b;
3823
+ var _a, _b, _c;
3671
3824
  super.dispose();
3672
- (_b = (_a = this.watermark) === null || _a === void 0 ? void 0 : _a.dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
3825
+ (_a = this.watermark) === null || _a === void 0 ? void 0 : _a.element.remove();
3826
+ (_c = (_b = this.watermark) === null || _b === void 0 ? void 0 : _b.dispose) === null || _c === void 0 ? void 0 : _c.call(_b);
3673
3827
  for (const panel of this.panels) {
3674
3828
  panel.dispose();
3675
3829
  }
@@ -4463,8 +4617,8 @@ class GridviewPanel extends BasePanelView {
4463
4617
  get isActive() {
4464
4618
  return this.api.isActive;
4465
4619
  }
4466
- constructor(id, component, options) {
4467
- super(id, component, new GridviewPanelApiImpl(id));
4620
+ constructor(id, component, options, api) {
4621
+ super(id, component, api !== null && api !== void 0 ? api : new GridviewPanelApiImpl(id));
4468
4622
  this._evaluatedMinimumWidth = 0;
4469
4623
  this._evaluatedMaximumWidth = Number.MAX_SAFE_INTEGER;
4470
4624
  this._evaluatedMinimumHeight = 0;
@@ -4562,6 +4716,32 @@ class GridviewPanel extends BasePanelView {
4562
4716
  }
4563
4717
  }
4564
4718
 
4719
+ class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
4720
+ get isFloating() {
4721
+ if (!this._group) {
4722
+ throw new Error(`DockviewGroupPanelApiImpl not initialized`);
4723
+ }
4724
+ return this._group.model.isFloating;
4725
+ }
4726
+ constructor(id, accessor) {
4727
+ super(id);
4728
+ this.accessor = accessor;
4729
+ this._onDidFloatingStateChange = new Emitter();
4730
+ this.onDidFloatingStateChange = this._onDidFloatingStateChange.event;
4731
+ this.addDisposables(this._onDidFloatingStateChange);
4732
+ }
4733
+ moveTo(options) {
4734
+ var _a;
4735
+ if (!this._group) {
4736
+ throw new Error(`DockviewGroupPanelApiImpl not initialized`);
4737
+ }
4738
+ this.accessor.moveGroupOrPanel(options.group, this._group.id, undefined, (_a = options.position) !== null && _a !== void 0 ? _a : 'center');
4739
+ }
4740
+ initialize(group) {
4741
+ this._group = group;
4742
+ }
4743
+ }
4744
+
4565
4745
  class DockviewGroupPanel extends GridviewPanel {
4566
4746
  get panels() {
4567
4747
  return this._model.panels;
@@ -4588,7 +4768,8 @@ class DockviewGroupPanel extends GridviewPanel {
4588
4768
  super(id, 'groupview_default', {
4589
4769
  minimumHeight: 100,
4590
4770
  minimumWidth: 100,
4591
- });
4771
+ }, new DockviewGroupPanelApiImpl(id, accessor));
4772
+ this.api.initialize(this); // cannot use 'this' after after 'super' call
4592
4773
  this._model = new DockviewGroupPanelModel(this.element, accessor, id, options, this);
4593
4774
  }
4594
4775
  initialize() {
@@ -4606,7 +4787,6 @@ class DockviewGroupPanel extends GridviewPanel {
4606
4787
  return this._model;
4607
4788
  }
4608
4789
  toJSON() {
4609
- // TODO fix typing
4610
4790
  return this.model.toJSON();
4611
4791
  }
4612
4792
  }
@@ -4660,9 +4840,10 @@ class DockviewPanelApiImpl extends GridviewPanelApiImpl {
4660
4840
  get group() {
4661
4841
  return this._group;
4662
4842
  }
4663
- constructor(panel, group) {
4843
+ constructor(panel, group, accessor) {
4664
4844
  super(panel.id);
4665
4845
  this.panel = panel;
4846
+ this.accessor = accessor;
4666
4847
  this._onDidTitleChange = new Emitter();
4667
4848
  this.onDidTitleChange = this._onDidTitleChange.event;
4668
4849
  this._onDidActiveGroupChange = new Emitter();
@@ -4674,6 +4855,10 @@ class DockviewPanelApiImpl extends GridviewPanelApiImpl {
4674
4855
  this._group = group;
4675
4856
  this.addDisposables(this.disposable, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange);
4676
4857
  }
4858
+ moveTo(options) {
4859
+ var _a;
4860
+ this.accessor.moveGroupOrPanel(options.group, this._group.id, this.panel.id, (_a = options.position) !== null && _a !== void 0 ? _a : 'center', options.index);
4861
+ }
4677
4862
  setTitle(title) {
4678
4863
  this.panel.setTitle(title);
4679
4864
  }
@@ -4698,7 +4883,7 @@ class DockviewPanel extends CompositeDisposable {
4698
4883
  this.containerApi = containerApi;
4699
4884
  this.view = view;
4700
4885
  this._group = group;
4701
- this.api = new DockviewPanelApiImpl(this, this._group);
4886
+ this.api = new DockviewPanelApiImpl(this, this._group, accessor);
4702
4887
  this.addDisposables(this.api.onActiveChange(() => {
4703
4888
  accessor.setActivePanel(this);
4704
4889
  }), this.api.onDidSizeChange((event) => {
@@ -5039,6 +5224,296 @@ class Watermark extends CompositeDisposable {
5039
5224
  }
5040
5225
  }
5041
5226
 
5227
+ const bringElementToFront = (() => {
5228
+ let previous = null;
5229
+ function pushToTop(element) {
5230
+ if (previous !== element && previous !== null) {
5231
+ toggleClass(previous, 'dv-bring-to-front', false);
5232
+ }
5233
+ toggleClass(element, 'dv-bring-to-front', true);
5234
+ previous = element;
5235
+ }
5236
+ return pushToTop;
5237
+ })();
5238
+ class Overlay extends CompositeDisposable {
5239
+ constructor(options) {
5240
+ super();
5241
+ this.options = options;
5242
+ this._element = document.createElement('div');
5243
+ this._onDidChange = new Emitter();
5244
+ this.onDidChange = this._onDidChange.event;
5245
+ this._onDidChangeEnd = new Emitter();
5246
+ this.onDidChangeEnd = this._onDidChangeEnd.event;
5247
+ this.addDisposables(this._onDidChange, this._onDidChangeEnd);
5248
+ this._element.className = 'dv-resize-container';
5249
+ this.setupResize('top');
5250
+ this.setupResize('bottom');
5251
+ this.setupResize('left');
5252
+ this.setupResize('right');
5253
+ this.setupResize('topleft');
5254
+ this.setupResize('topright');
5255
+ this.setupResize('bottomleft');
5256
+ this.setupResize('bottomright');
5257
+ this._element.appendChild(this.options.content);
5258
+ this.options.container.appendChild(this._element);
5259
+ // if input bad resize within acceptable boundaries
5260
+ this.setBounds({
5261
+ height: this.options.height,
5262
+ width: this.options.width,
5263
+ top: this.options.top,
5264
+ left: this.options.left,
5265
+ });
5266
+ }
5267
+ setBounds(bounds = {}) {
5268
+ if (typeof bounds.height === 'number') {
5269
+ this._element.style.height = `${bounds.height}px`;
5270
+ }
5271
+ if (typeof bounds.width === 'number') {
5272
+ this._element.style.width = `${bounds.width}px`;
5273
+ }
5274
+ if (typeof bounds.top === 'number') {
5275
+ this._element.style.top = `${bounds.top}px`;
5276
+ }
5277
+ if (typeof bounds.left === 'number') {
5278
+ this._element.style.left = `${bounds.left}px`;
5279
+ }
5280
+ const containerRect = this.options.container.getBoundingClientRect();
5281
+ const overlayRect = this._element.getBoundingClientRect();
5282
+ // region: ensure bounds within allowable limits
5283
+ // a minimum width of minimumViewportWidth must be inside the viewport
5284
+ const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5285
+ // a minimum height of minimumViewportHeight must be inside the viewport
5286
+ const yOffset = Math.max(0, overlayRect.height - this.options.minimumInViewportHeight);
5287
+ const left = clamp(overlayRect.left - containerRect.left, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5288
+ const top = clamp(overlayRect.top - containerRect.top, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5289
+ this._element.style.left = `${left}px`;
5290
+ this._element.style.top = `${top}px`;
5291
+ this._onDidChange.fire();
5292
+ }
5293
+ toJSON() {
5294
+ const container = this.options.container.getBoundingClientRect();
5295
+ const element = this._element.getBoundingClientRect();
5296
+ return {
5297
+ top: element.top - container.top,
5298
+ left: element.left - container.left,
5299
+ width: element.width,
5300
+ height: element.height,
5301
+ };
5302
+ }
5303
+ setupDrag(dragTarget, options = { inDragMode: false }) {
5304
+ const move = new MutableDisposable();
5305
+ const track = () => {
5306
+ let offset = null;
5307
+ const iframes = [
5308
+ ...getElementsByTagName('iframe'),
5309
+ ...getElementsByTagName('webview'),
5310
+ ];
5311
+ for (const iframe of iframes) {
5312
+ iframe.style.pointerEvents = 'none';
5313
+ }
5314
+ move.value = new CompositeDisposable({
5315
+ dispose: () => {
5316
+ for (const iframe of iframes) {
5317
+ iframe.style.pointerEvents = 'auto';
5318
+ }
5319
+ },
5320
+ }, addDisposableWindowListener(window, 'mousemove', (e) => {
5321
+ const containerRect = this.options.container.getBoundingClientRect();
5322
+ const x = e.clientX - containerRect.left;
5323
+ const y = e.clientY - containerRect.top;
5324
+ toggleClass(this._element, 'dv-resize-container-dragging', true);
5325
+ const overlayRect = this._element.getBoundingClientRect();
5326
+ if (offset === null) {
5327
+ offset = {
5328
+ x: e.clientX - overlayRect.left,
5329
+ y: e.clientY - overlayRect.top,
5330
+ };
5331
+ }
5332
+ const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5333
+ const yOffset = Math.max(0, overlayRect.height -
5334
+ this.options.minimumInViewportHeight);
5335
+ const left = clamp(x - offset.x, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5336
+ const top = clamp(y - offset.y, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5337
+ this.setBounds({ top, left });
5338
+ }), addDisposableWindowListener(window, 'mouseup', () => {
5339
+ toggleClass(this._element, 'dv-resize-container-dragging', false);
5340
+ move.dispose();
5341
+ this._onDidChangeEnd.fire();
5342
+ }));
5343
+ };
5344
+ this.addDisposables(move, addDisposableListener(dragTarget, 'mousedown', (event) => {
5345
+ if (event.defaultPrevented) {
5346
+ event.preventDefault();
5347
+ return;
5348
+ }
5349
+ // if somebody has marked this event then treat as a defaultPrevented
5350
+ // without actually calling event.preventDefault()
5351
+ if (quasiDefaultPrevented(event)) {
5352
+ return;
5353
+ }
5354
+ track();
5355
+ }), addDisposableListener(this.options.content, 'mousedown', (event) => {
5356
+ if (event.defaultPrevented) {
5357
+ return;
5358
+ }
5359
+ // if somebody has marked this event then treat as a defaultPrevented
5360
+ // without actually calling event.preventDefault()
5361
+ if (quasiDefaultPrevented(event)) {
5362
+ return;
5363
+ }
5364
+ if (event.shiftKey) {
5365
+ track();
5366
+ }
5367
+ }), addDisposableListener(this.options.content, 'mousedown', () => {
5368
+ bringElementToFront(this._element);
5369
+ }, true));
5370
+ bringElementToFront(this._element);
5371
+ if (options.inDragMode) {
5372
+ track();
5373
+ }
5374
+ }
5375
+ setupResize(direction) {
5376
+ const resizeHandleElement = document.createElement('div');
5377
+ resizeHandleElement.className = `dv-resize-handle-${direction}`;
5378
+ this._element.appendChild(resizeHandleElement);
5379
+ const move = new MutableDisposable();
5380
+ this.addDisposables(move, addDisposableListener(resizeHandleElement, 'mousedown', (e) => {
5381
+ e.preventDefault();
5382
+ let startPosition = null;
5383
+ const iframes = [
5384
+ ...getElementsByTagName('iframe'),
5385
+ ...getElementsByTagName('webview'),
5386
+ ];
5387
+ for (const iframe of iframes) {
5388
+ iframe.style.pointerEvents = 'none';
5389
+ }
5390
+ move.value = new CompositeDisposable(addDisposableWindowListener(window, 'mousemove', (e) => {
5391
+ const containerRect = this.options.container.getBoundingClientRect();
5392
+ const overlayRect = this._element.getBoundingClientRect();
5393
+ const y = e.clientY - containerRect.top;
5394
+ const x = e.clientX - containerRect.left;
5395
+ if (startPosition === null) {
5396
+ // record the initial dimensions since as all subsequence moves are relative to this
5397
+ startPosition = {
5398
+ originalY: y,
5399
+ originalHeight: overlayRect.height,
5400
+ originalX: x,
5401
+ originalWidth: overlayRect.width,
5402
+ };
5403
+ }
5404
+ let top = undefined;
5405
+ let height = undefined;
5406
+ let left = undefined;
5407
+ let width = undefined;
5408
+ const minimumInViewportHeight = this.options.minimumInViewportHeight;
5409
+ const minimumInViewportWidth = this.options.minimumInViewportWidth;
5410
+ function moveTop() {
5411
+ top = clamp(y, -Number.MAX_VALUE, startPosition.originalY +
5412
+ startPosition.originalHeight >
5413
+ containerRect.height
5414
+ ? containerRect.height -
5415
+ minimumInViewportHeight
5416
+ : Math.max(0, startPosition.originalY +
5417
+ startPosition.originalHeight -
5418
+ Overlay.MINIMUM_HEIGHT));
5419
+ height =
5420
+ startPosition.originalY +
5421
+ startPosition.originalHeight -
5422
+ top;
5423
+ }
5424
+ function moveBottom() {
5425
+ top =
5426
+ startPosition.originalY -
5427
+ startPosition.originalHeight;
5428
+ height = clamp(y - top, top < 0
5429
+ ? -top + minimumInViewportHeight
5430
+ : Overlay.MINIMUM_HEIGHT, Number.MAX_VALUE);
5431
+ }
5432
+ function moveLeft() {
5433
+ left = clamp(x, -Number.MAX_VALUE, startPosition.originalX +
5434
+ startPosition.originalWidth >
5435
+ containerRect.width
5436
+ ? containerRect.width -
5437
+ minimumInViewportWidth
5438
+ : Math.max(0, startPosition.originalX +
5439
+ startPosition.originalWidth -
5440
+ Overlay.MINIMUM_WIDTH));
5441
+ width =
5442
+ startPosition.originalX +
5443
+ startPosition.originalWidth -
5444
+ left;
5445
+ }
5446
+ function moveRight() {
5447
+ left =
5448
+ startPosition.originalX -
5449
+ startPosition.originalWidth;
5450
+ width = clamp(x - left, left < 0
5451
+ ? -left + minimumInViewportWidth
5452
+ : Overlay.MINIMUM_WIDTH, Number.MAX_VALUE);
5453
+ }
5454
+ switch (direction) {
5455
+ case 'top':
5456
+ moveTop();
5457
+ break;
5458
+ case 'bottom':
5459
+ moveBottom();
5460
+ break;
5461
+ case 'left':
5462
+ moveLeft();
5463
+ break;
5464
+ case 'right':
5465
+ moveRight();
5466
+ break;
5467
+ case 'topleft':
5468
+ moveTop();
5469
+ moveLeft();
5470
+ break;
5471
+ case 'topright':
5472
+ moveTop();
5473
+ moveRight();
5474
+ break;
5475
+ case 'bottomleft':
5476
+ moveBottom();
5477
+ moveLeft();
5478
+ break;
5479
+ case 'bottomright':
5480
+ moveBottom();
5481
+ moveRight();
5482
+ break;
5483
+ }
5484
+ this.setBounds({ height, width, top, left });
5485
+ }), {
5486
+ dispose: () => {
5487
+ for (const iframe of iframes) {
5488
+ iframe.style.pointerEvents = 'auto';
5489
+ }
5490
+ },
5491
+ }, addDisposableWindowListener(window, 'mouseup', () => {
5492
+ move.dispose();
5493
+ this._onDidChangeEnd.fire();
5494
+ }));
5495
+ }));
5496
+ }
5497
+ dispose() {
5498
+ this._element.remove();
5499
+ super.dispose();
5500
+ }
5501
+ }
5502
+ Overlay.MINIMUM_HEIGHT = 20;
5503
+ Overlay.MINIMUM_WIDTH = 20;
5504
+
5505
+ class DockviewFloatingGroupPanel extends CompositeDisposable {
5506
+ constructor(group, overlay) {
5507
+ super();
5508
+ this.group = group;
5509
+ this.overlay = overlay;
5510
+ this.addDisposables(overlay);
5511
+ }
5512
+ position(bounds) {
5513
+ this.overlay.setBounds(bounds);
5514
+ }
5515
+ }
5516
+
5042
5517
  class DockviewComponent extends BaseGrid {
5043
5518
  get orientation() {
5044
5519
  return this.gridview.orientation;
@@ -5079,7 +5554,8 @@ class DockviewComponent extends BaseGrid {
5079
5554
  this.onDidLayoutFromJSON = this._onDidLayoutFromJSON.event;
5080
5555
  this._onDidActivePanelChange = new Emitter();
5081
5556
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
5082
- this.element.classList.add('dv-dockview');
5557
+ this.floatingGroups = [];
5558
+ toggleClass(this.gridview.element, 'dv-dockview', true);
5083
5559
  this.addDisposables(this._onDidDrop, Event.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
5084
5560
  this.updateWatermark();
5085
5561
  }), Event.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => {
@@ -5109,6 +5585,11 @@ class DockviewComponent extends BaseGrid {
5109
5585
  if (data.viewId !== this.id) {
5110
5586
  return false;
5111
5587
  }
5588
+ if (position === 'center') {
5589
+ // center drop target is only allowed if there are no panels in the grid
5590
+ // floating panels are allowed
5591
+ return this.gridview.length === 0;
5592
+ }
5112
5593
  return true;
5113
5594
  }
5114
5595
  if (this.options.showDndOverlay) {
@@ -5121,7 +5602,7 @@ class DockviewComponent extends BaseGrid {
5121
5602
  }
5122
5603
  return false;
5123
5604
  },
5124
- acceptedTargetZones: ['top', 'bottom', 'left', 'right'],
5605
+ acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
5125
5606
  overlayModel: {
5126
5607
  activationSize: { type: 'pixels', value: 10 },
5127
5608
  size: { type: 'pixels', value: 20 },
@@ -5139,6 +5620,75 @@ class DockviewComponent extends BaseGrid {
5139
5620
  this._api = new DockviewApi(this);
5140
5621
  this.updateWatermark();
5141
5622
  }
5623
+ addFloatingGroup(item, coord, options) {
5624
+ var _a, _b;
5625
+ let group;
5626
+ if (item instanceof DockviewPanel) {
5627
+ group = this.createGroup();
5628
+ this.removePanel(item, {
5629
+ removeEmptyGroup: true,
5630
+ skipDispose: true,
5631
+ });
5632
+ group.model.openPanel(item);
5633
+ }
5634
+ else {
5635
+ group = item;
5636
+ const skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' &&
5637
+ options.skipRemoveGroup;
5638
+ if (!skip) {
5639
+ this.doRemoveGroup(item, { skipDispose: true });
5640
+ }
5641
+ }
5642
+ group.model.isFloating = true;
5643
+ const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number' ? Math.max(coord.x, 0) : 100;
5644
+ const overlayTop = typeof (coord === null || coord === void 0 ? void 0 : coord.y) === 'number' ? Math.max(coord.y, 0) : 100;
5645
+ const overlay = new Overlay({
5646
+ container: this.gridview.element,
5647
+ content: group.element,
5648
+ height: (_a = coord === null || coord === void 0 ? void 0 : coord.height) !== null && _a !== void 0 ? _a : 300,
5649
+ width: (_b = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _b !== void 0 ? _b : 300,
5650
+ left: overlayLeft,
5651
+ top: overlayTop,
5652
+ minimumInViewportWidth: 100,
5653
+ minimumInViewportHeight: 100,
5654
+ });
5655
+ const el = group.element.querySelector('.void-container');
5656
+ if (!el) {
5657
+ throw new Error('failed to find drag handle');
5658
+ }
5659
+ overlay.setupDrag(el, {
5660
+ inDragMode: typeof (options === null || options === void 0 ? void 0 : options.inDragMode) === 'boolean'
5661
+ ? options.inDragMode
5662
+ : false,
5663
+ });
5664
+ const floatingGroupPanel = new DockviewFloatingGroupPanel(group, overlay);
5665
+ const disposable = watchElementResize(group.element, (entry) => {
5666
+ const { width, height } = entry.contentRect;
5667
+ group.layout(width, height); // let the group know it's size is changing so it can fire events to the panel
5668
+ });
5669
+ floatingGroupPanel.addDisposables(overlay.onDidChange(() => {
5670
+ // this is either a resize or a move
5671
+ // to inform the panels .layout(...) the group with it's current size
5672
+ // don't care about resize since the above watcher handles that
5673
+ group.layout(group.height, group.width);
5674
+ }), overlay.onDidChangeEnd(() => {
5675
+ this._bufferOnDidLayoutChange.fire();
5676
+ }), group.onDidChange((event) => {
5677
+ overlay.setBounds({
5678
+ height: event === null || event === void 0 ? void 0 : event.height,
5679
+ width: event === null || event === void 0 ? void 0 : event.width,
5680
+ });
5681
+ }), {
5682
+ dispose: () => {
5683
+ disposable.dispose();
5684
+ group.model.isFloating = false;
5685
+ remove(this.floatingGroups, floatingGroupPanel);
5686
+ this.updateWatermark();
5687
+ },
5688
+ });
5689
+ this.floatingGroups.push(floatingGroupPanel);
5690
+ this.updateWatermark();
5691
+ }
5142
5692
  orthogonalize(position) {
5143
5693
  switch (position) {
5144
5694
  case 'top':
@@ -5161,6 +5711,7 @@ class DockviewComponent extends BaseGrid {
5161
5711
  switch (position) {
5162
5712
  case 'top':
5163
5713
  case 'left':
5714
+ case 'center':
5164
5715
  return this.createGroupAtLocation([0]); // insert into first position
5165
5716
  case 'bottom':
5166
5717
  case 'right':
@@ -5178,6 +5729,15 @@ class DockviewComponent extends BaseGrid {
5178
5729
  }
5179
5730
  this.layout(this.gridview.width, this.gridview.height, true);
5180
5731
  }
5732
+ layout(width, height, forceResize) {
5733
+ super.layout(width, height, forceResize);
5734
+ if (this.floatingGroups) {
5735
+ for (const floating of this.floatingGroups) {
5736
+ // ensure floting groups stay within visible boundaries
5737
+ floating.overlay.setBounds();
5738
+ }
5739
+ }
5740
+ }
5181
5741
  focus() {
5182
5742
  var _a;
5183
5743
  (_a = this.activeGroup) === null || _a === void 0 ? void 0 : _a.focus();
@@ -5240,51 +5800,81 @@ class DockviewComponent extends BaseGrid {
5240
5800
  collection[panel.id] = panel.toJSON();
5241
5801
  return collection;
5242
5802
  }, {});
5243
- return {
5803
+ const floats = this.floatingGroups.map((floatingGroup) => {
5804
+ return {
5805
+ data: floatingGroup.group.toJSON(),
5806
+ position: floatingGroup.overlay.toJSON(),
5807
+ };
5808
+ });
5809
+ const result = {
5244
5810
  grid: data,
5245
5811
  panels,
5246
5812
  activeGroup: (_a = this.activeGroup) === null || _a === void 0 ? void 0 : _a.id,
5247
5813
  };
5814
+ if (floats.length > 0) {
5815
+ result.floatingGroups = floats;
5816
+ }
5817
+ return result;
5248
5818
  }
5249
5819
  fromJSON(data) {
5820
+ var _a;
5250
5821
  this.clear();
5251
5822
  const { grid, panels, activeGroup } = data;
5252
5823
  if (grid.root.type !== 'branch' || !Array.isArray(grid.root.data)) {
5253
5824
  throw new Error('root must be of type branch');
5254
5825
  }
5826
+ // take note of the existing dimensions
5827
+ const width = this.width;
5828
+ const height = this.height;
5829
+ const createGroupFromSerializedState = (data) => {
5830
+ const { id, locked, hideHeader, views, activeView } = data;
5831
+ const group = this.createGroup({
5832
+ id,
5833
+ locked: !!locked,
5834
+ hideHeader: !!hideHeader,
5835
+ });
5836
+ this._onDidAddGroup.fire(group);
5837
+ for (const child of views) {
5838
+ const panel = this._deserializer.fromJSON(panels[child], group);
5839
+ const isActive = typeof activeView === 'string' && activeView === panel.id;
5840
+ group.model.openPanel(panel, {
5841
+ skipSetPanelActive: !isActive,
5842
+ skipSetGroupActive: true,
5843
+ });
5844
+ }
5845
+ if (!group.activePanel && group.panels.length > 0) {
5846
+ group.model.openPanel(group.panels[group.panels.length - 1], {
5847
+ skipSetGroupActive: true,
5848
+ });
5849
+ }
5850
+ return group;
5851
+ };
5255
5852
  this.gridview.deserialize(grid, {
5256
5853
  fromJSON: (node) => {
5257
- const { id, locked, hideHeader, views, activeView } = node.data;
5258
- const group = this.createGroup({
5259
- id,
5260
- locked: !!locked,
5261
- hideHeader: !!hideHeader,
5262
- });
5263
- this._onDidAddGroup.fire(group);
5264
- for (const child of views) {
5265
- const panel = this._deserializer.fromJSON(panels[child], group);
5266
- const isActive = typeof activeView === 'string' &&
5267
- activeView === panel.id;
5268
- group.model.openPanel(panel, {
5269
- skipSetPanelActive: !isActive,
5270
- skipSetGroupActive: true,
5271
- });
5272
- }
5273
- if (!group.activePanel && group.panels.length > 0) {
5274
- group.model.openPanel(group.panels[group.panels.length - 1], {
5275
- skipSetGroupActive: true,
5276
- });
5277
- }
5278
- return group;
5854
+ return createGroupFromSerializedState(node.data);
5279
5855
  },
5280
5856
  });
5857
+ this.layout(width, height, true);
5858
+ const serializedFloatingGroups = (_a = data.floatingGroups) !== null && _a !== void 0 ? _a : [];
5859
+ for (const serializedFloatingGroup of serializedFloatingGroups) {
5860
+ const { data, position } = serializedFloatingGroup;
5861
+ const group = createGroupFromSerializedState(data);
5862
+ this.addFloatingGroup(group, {
5863
+ x: position.left,
5864
+ y: position.top,
5865
+ height: position.height,
5866
+ width: position.width,
5867
+ }, { skipRemoveGroup: true, inDragMode: false });
5868
+ }
5869
+ for (const floatingGroup of this.floatingGroups) {
5870
+ floatingGroup.overlay.setBounds();
5871
+ }
5281
5872
  if (typeof activeGroup === 'string') {
5282
5873
  const panel = this.getPanel(activeGroup);
5283
5874
  if (panel) {
5284
5875
  this.doSetGroupActive(panel);
5285
5876
  }
5286
5877
  }
5287
- this.gridview.layout(this.width, this.height);
5288
5878
  this._onDidLayoutFromJSON.fire();
5289
5879
  }
5290
5880
  clear() {
@@ -5293,7 +5883,7 @@ class DockviewComponent extends BaseGrid {
5293
5883
  const hasActivePanel = !!this.activePanel;
5294
5884
  for (const group of groups) {
5295
5885
  // remove the group will automatically remove the panels
5296
- this.removeGroup(group, true);
5886
+ this.removeGroup(group, { skipActive: true });
5297
5887
  }
5298
5888
  if (hasActiveGroup) {
5299
5889
  this.doSetGroupActive(undefined);
@@ -5315,6 +5905,9 @@ class DockviewComponent extends BaseGrid {
5315
5905
  throw new Error(`panel with id ${options.id} already exists`);
5316
5906
  }
5317
5907
  let referenceGroup;
5908
+ if (options.position && options.floating) {
5909
+ throw new Error('you can only provide one of: position, floating as arguments to .addPanel(...)');
5910
+ }
5318
5911
  if (options.position) {
5319
5912
  if (isPanelOptionsWithPanel(options.position)) {
5320
5913
  const referencePanel = typeof options.position.referencePanel === 'string'
@@ -5347,7 +5940,20 @@ class DockviewComponent extends BaseGrid {
5347
5940
  let panel;
5348
5941
  if (referenceGroup) {
5349
5942
  const target = toTarget(((_b = options.position) === null || _b === void 0 ? void 0 : _b.direction) || 'within');
5350
- if (target === 'center') {
5943
+ if (options.floating) {
5944
+ const group = this.createGroup();
5945
+ panel = this.createPanel(options, group);
5946
+ group.model.openPanel(panel);
5947
+ const o = typeof options.floating === 'object' &&
5948
+ options.floating !== null
5949
+ ? options.floating
5950
+ : {};
5951
+ this.addFloatingGroup(group, o, {
5952
+ inDragMode: false,
5953
+ skipRemoveGroup: true,
5954
+ });
5955
+ }
5956
+ else if (referenceGroup.api.isFloating || target === 'center') {
5351
5957
  panel = this.createPanel(options, referenceGroup);
5352
5958
  referenceGroup.model.openPanel(panel);
5353
5959
  }
@@ -5359,6 +5965,19 @@ class DockviewComponent extends BaseGrid {
5359
5965
  group.model.openPanel(panel);
5360
5966
  }
5361
5967
  }
5968
+ else if (options.floating) {
5969
+ const group = this.createGroup();
5970
+ panel = this.createPanel(options, group);
5971
+ group.model.openPanel(panel);
5972
+ const o = typeof options.floating === 'object' &&
5973
+ options.floating !== null
5974
+ ? options.floating
5975
+ : {};
5976
+ this.addFloatingGroup(group, o, {
5977
+ inDragMode: false,
5978
+ skipRemoveGroup: true,
5979
+ });
5980
+ }
5362
5981
  else {
5363
5982
  const group = this.createGroupAtLocation();
5364
5983
  panel = this.createPanel(options, group);
@@ -5375,7 +5994,9 @@ class DockviewComponent extends BaseGrid {
5375
5994
  throw new Error(`cannot remove panel ${panel.id}. it's missing a group.`);
5376
5995
  }
5377
5996
  group.model.removePanel(panel);
5378
- panel.dispose();
5997
+ if (!options.skipDispose) {
5998
+ panel.dispose();
5999
+ }
5379
6000
  if (group.size === 0 && options.removeEmptyGroup) {
5380
6001
  this.removeGroup(group);
5381
6002
  }
@@ -5390,7 +6011,7 @@ class DockviewComponent extends BaseGrid {
5390
6011
  }
5391
6012
  updateWatermark() {
5392
6013
  var _a, _b;
5393
- if (this.groups.length === 0) {
6014
+ if (this.groups.filter((x) => !x.api.isFloating).length === 0) {
5394
6015
  if (!this.watermark) {
5395
6016
  this.watermark = this.createWatermarkComponent();
5396
6017
  this.watermark.init({
@@ -5399,7 +6020,7 @@ class DockviewComponent extends BaseGrid {
5399
6020
  const watermarkContainer = document.createElement('div');
5400
6021
  watermarkContainer.className = 'dv-watermark-container';
5401
6022
  watermarkContainer.appendChild(this.watermark.element);
5402
- this.element.appendChild(watermarkContainer);
6023
+ this.gridview.element.appendChild(watermarkContainer);
5403
6024
  }
5404
6025
  }
5405
6026
  else if (this.watermark) {
@@ -5449,15 +6070,28 @@ class DockviewComponent extends BaseGrid {
5449
6070
  return group;
5450
6071
  }
5451
6072
  }
5452
- removeGroup(group, skipActive = false) {
6073
+ removeGroup(group, options) {
6074
+ var _a;
5453
6075
  const panels = [...group.panels]; // reassign since group panels will mutate
5454
6076
  for (const panel of panels) {
5455
6077
  this.removePanel(panel, {
5456
6078
  removeEmptyGroup: false,
5457
- skipDispose: false,
6079
+ skipDispose: (_a = options === null || options === void 0 ? void 0 : options.skipDispose) !== null && _a !== void 0 ? _a : false,
5458
6080
  });
5459
6081
  }
5460
- super.doRemoveGroup(group, { skipActive });
6082
+ this.doRemoveGroup(group, options);
6083
+ }
6084
+ doRemoveGroup(group, options) {
6085
+ const floatingGroup = this.floatingGroups.find((_) => _.group === group);
6086
+ if (floatingGroup) {
6087
+ if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
6088
+ floatingGroup.group.dispose();
6089
+ this._groups.delete(group.id);
6090
+ }
6091
+ floatingGroup.dispose();
6092
+ return floatingGroup.group;
6093
+ }
6094
+ return super.doRemoveGroup(group, options);
5461
6095
  }
5462
6096
  moveGroupOrPanel(destinationGroup, sourceGroupId, sourceItemId, destinationTarget, destinationIndex) {
5463
6097
  var _a;
@@ -5488,25 +6122,26 @@ class DockviewComponent extends BaseGrid {
5488
6122
  const targetLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
5489
6123
  if (sourceGroup && sourceGroup.size < 2) {
5490
6124
  const [targetParentLocation, to] = tail(targetLocation);
5491
- const sourceLocation = getGridLocation(sourceGroup.element);
5492
- const [sourceParentLocation, from] = tail(sourceLocation);
5493
- if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
5494
- // special case when 'swapping' two views within same grid location
5495
- // if a group has one tab - we are essentially moving the 'group'
5496
- // which is equivalent to swapping two views in this case
5497
- this.gridview.moveView(sourceParentLocation, from, to);
5498
- }
5499
- else {
5500
- // source group will become empty so delete the group
5501
- const targetGroup = this.doRemoveGroup(sourceGroup, {
5502
- skipActive: true,
5503
- skipDispose: true,
5504
- });
5505
- // after deleting the group we need to re-evaulate the ref location
5506
- const updatedReferenceLocation = getGridLocation(destinationGroup.element);
5507
- const location = getRelativeLocation(this.gridview.orientation, updatedReferenceLocation, destinationTarget);
5508
- this.doAddGroup(targetGroup, location);
6125
+ const isFloating = this.floatingGroups.find((x) => x.group === sourceGroup);
6126
+ if (!isFloating) {
6127
+ const sourceLocation = getGridLocation(sourceGroup.element);
6128
+ const [sourceParentLocation, from] = tail(sourceLocation);
6129
+ if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
6130
+ // special case when 'swapping' two views within same grid location
6131
+ // if a group has one tab - we are essentially moving the 'group'
6132
+ // which is equivalent to swapping two views in this case
6133
+ this.gridview.moveView(sourceParentLocation, from, to);
6134
+ }
5509
6135
  }
6136
+ // source group will become empty so delete the group
6137
+ const targetGroup = this.doRemoveGroup(sourceGroup, {
6138
+ skipActive: true,
6139
+ skipDispose: true,
6140
+ });
6141
+ // after deleting the group we need to re-evaulate the ref location
6142
+ const updatedReferenceLocation = getGridLocation(destinationGroup.element);
6143
+ const location = getRelativeLocation(this.gridview.orientation, updatedReferenceLocation, destinationTarget);
6144
+ this.doAddGroup(targetGroup, location);
5510
6145
  }
5511
6146
  else {
5512
6147
  const groupItem = (sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.removePanel(sourceItemId)) ||
@@ -5535,7 +6170,13 @@ class DockviewComponent extends BaseGrid {
5535
6170
  }
5536
6171
  }
5537
6172
  else {
5538
- this.gridview.removeView(getGridLocation(sourceGroup.element));
6173
+ const floatingGroup = this.floatingGroups.find((x) => x.group === sourceGroup);
6174
+ if (floatingGroup) {
6175
+ floatingGroup.dispose();
6176
+ }
6177
+ else {
6178
+ this.gridview.removeView(getGridLocation(sourceGroup.element));
6179
+ }
5539
6180
  const referenceLocation = getGridLocation(referenceGroup.element);
5540
6181
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, target);
5541
6182
  this.gridview.addView(sourceGroup, Sizing.Distribute, dropLocation);
@@ -5690,6 +6331,9 @@ class GridviewComponent extends BaseGrid {
5690
6331
  this.clear();
5691
6332
  const { grid, activePanel } = serializedGridview;
5692
6333
  const queue = [];
6334
+ // take note of the existing dimensions
6335
+ const width = this.width;
6336
+ const height = this.height;
5693
6337
  this.gridview.deserialize(grid, {
5694
6338
  fromJSON: (node) => {
5695
6339
  const { data } = node;
@@ -5715,7 +6359,7 @@ class GridviewComponent extends BaseGrid {
5715
6359
  return view;
5716
6360
  },
5717
6361
  });
5718
- this.layout(this.width, this.height, true);
6362
+ this.layout(width, height, true);
5719
6363
  queue.forEach((f) => f());
5720
6364
  if (typeof activePanel === 'string') {
5721
6365
  const panel = this.getPanel(activePanel);
@@ -6029,6 +6673,9 @@ class SplitviewComponent extends Resizable {
6029
6673
  this.clear();
6030
6674
  const { views, orientation, size, activeView } = serializedSplitview;
6031
6675
  const queue = [];
6676
+ // take note of the existing dimensions
6677
+ const width = this.width;
6678
+ const height = this.height;
6032
6679
  this.splitview = new Splitview(this.element, {
6033
6680
  orientation,
6034
6681
  proportionalLayout: this.options.proportionalLayout,
@@ -6065,7 +6712,7 @@ class SplitviewComponent extends Resizable {
6065
6712
  }),
6066
6713
  },
6067
6714
  });
6068
- this.layout(this.width, this.height);
6715
+ this.layout(width, height);
6069
6716
  queue.forEach((f) => f());
6070
6717
  if (typeof activeView === 'string') {
6071
6718
  const panel = this.getPanel(activeView);
@@ -6332,6 +6979,9 @@ class PaneviewComponent extends Resizable {
6332
6979
  this.clear();
6333
6980
  const { views, size } = serializedPaneview;
6334
6981
  const queue = [];
6982
+ // take note of the existing dimensions
6983
+ const width = this.width;
6984
+ const height = this.height;
6335
6985
  this.paneview = new Paneview(this.element, {
6336
6986
  orientation: Orientation.VERTICAL,
6337
6987
  descriptor: {
@@ -6387,7 +7037,7 @@ class PaneviewComponent extends Resizable {
6387
7037
  }),
6388
7038
  },
6389
7039
  });
6390
- this.layout(this.width, this.height);
7040
+ this.layout(width, height);
6391
7041
  queue.forEach((f) => f());
6392
7042
  this._onDidLayoutfromJSON.fire();
6393
7043
  }
@@ -6770,7 +7420,7 @@ class ReactWatermarkPart {
6770
7420
  }
6771
7421
  }
6772
7422
 
6773
- class ReactGroupControlsRendererPart {
7423
+ class ReactHeaderActionsRendererPart {
6774
7424
  get element() {
6775
7425
  return this._element;
6776
7426
  }
@@ -6807,6 +7457,7 @@ class ReactGroupControlsRendererPart {
6807
7457
  panels: this._group.model.panels,
6808
7458
  activePanel: this._group.model.activePanel,
6809
7459
  isGroupActive: this._group.api.isActive,
7460
+ group: this._group,
6810
7461
  });
6811
7462
  }
6812
7463
  update(event) {
@@ -6840,7 +7491,7 @@ class ReactGroupControlsRendererPart {
6840
7491
  function createGroupControlElement(component, store) {
6841
7492
  return component
6842
7493
  ? (groupPanel) => {
6843
- return new ReactGroupControlsRendererPart(component, store, groupPanel);
7494
+ return new ReactHeaderActionsRendererPart(component, store, groupPanel);
6844
7495
  }
6845
7496
  : undefined;
6846
7497
  }
@@ -6897,8 +7548,10 @@ const DockviewReact = React.forwardRef((props, ref) => {
6897
7548
  ? { separatorBorder: 'transparent' }
6898
7549
  : undefined,
6899
7550
  showDndOverlay: props.showDndOverlay,
6900
- createGroupControlElement: createGroupControlElement(props.groupControlComponent, { addPortal }),
7551
+ createLeftHeaderActionsElement: createGroupControlElement(props.leftHeaderActionsComponent, { addPortal }),
7552
+ createRightHeaderActionsElement: createGroupControlElement(props.rightHeaderActionsComponent, { addPortal }),
6901
7553
  singleTabMode: props.singleTabMode,
7554
+ disableFloatingGroups: props.disableFloatingGroups,
6902
7555
  });
6903
7556
  const { clientWidth, clientHeight } = domRef.current;
6904
7557
  dockview.layout(clientWidth, clientHeight);
@@ -6957,6 +7610,14 @@ const DockviewReact = React.forwardRef((props, ref) => {
6957
7610
  frameworkTabComponents: props.tabComponents,
6958
7611
  });
6959
7612
  }, [props.tabComponents]);
7613
+ React.useEffect(() => {
7614
+ if (!dockviewRef.current) {
7615
+ return;
7616
+ }
7617
+ dockviewRef.current.updateOptions({
7618
+ disableFloatingGroups: props.disableFloatingGroups,
7619
+ });
7620
+ }, [props.disableFloatingGroups]);
6960
7621
  React.useEffect(() => {
6961
7622
  if (!dockviewRef.current) {
6962
7623
  return;
@@ -6978,9 +7639,17 @@ const DockviewReact = React.forwardRef((props, ref) => {
6978
7639
  return;
6979
7640
  }
6980
7641
  dockviewRef.current.updateOptions({
6981
- createGroupControlElement: createGroupControlElement(props.groupControlComponent, { addPortal }),
7642
+ createRightHeaderActionsElement: createGroupControlElement(props.rightHeaderActionsComponent, { addPortal }),
7643
+ });
7644
+ }, [props.rightHeaderActionsComponent]);
7645
+ React.useEffect(() => {
7646
+ if (!dockviewRef.current) {
7647
+ return;
7648
+ }
7649
+ dockviewRef.current.updateOptions({
7650
+ createLeftHeaderActionsElement: createGroupControlElement(props.leftHeaderActionsComponent, { addPortal }),
6982
7651
  });
6983
- }, [props.groupControlComponent]);
7652
+ }, [props.leftHeaderActionsComponent]);
6984
7653
  return (React.createElement("div", { className: props.className, style: { height: '100%', width: '100%' }, ref: domRef }, portals));
6985
7654
  });
6986
7655
  DockviewReact.displayName = 'DockviewComponent';
@@ -6999,6 +7668,8 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
6999
7668
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
7000
7669
  PERFORMANCE OF THIS SOFTWARE.
7001
7670
  ***************************************************************************** */
7671
+ /* global Reflect, Promise, SuppressedError, Symbol */
7672
+
7002
7673
 
7003
7674
  function __rest(s, e) {
7004
7675
  var t = {};
@@ -7010,7 +7681,12 @@ function __rest(s, e) {
7010
7681
  t[p[i]] = s[p[i]];
7011
7682
  }
7012
7683
  return t;
7013
- }
7684
+ }
7685
+
7686
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
7687
+ var e = new Error(message);
7688
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
7689
+ };
7014
7690
 
7015
7691
  const CloseButton = () => (React.createElement("svg", { height: "11", width: "11", viewBox: "0 0 28 28", "aria-hidden": 'false', focusable: false, className: "dockview-svg" },
7016
7692
  React.createElement("path", { d: "M2.1 27.3L0 25.2L11.55 13.65L0 2.1L2.1 0L13.65 11.55L25.2 0L27.3 2.1L15.75 13.65L27.3 25.2L25.2 27.3L13.65 15.75L2.1 27.3Z" })));
@@ -7282,4 +7958,5 @@ const PaneviewReact = React.forwardRef((props, ref) => {
7282
7958
  });
7283
7959
  PaneviewReact.displayName = 'PaneviewComponent';
7284
7960
 
7285
- export { BaseGrid, ContentContainer, DefaultDockviewDeserialzier, DefaultTab, DockviewApi, DockviewComponent, CompositeDisposable as DockviewCompositeDisposable, DockviewDefaultTab, DockviewDropTargets, Emitter as DockviewEmitter, Event as DockviewEvent, DockviewGroupPanel, DockviewGroupPanelModel, MutableDisposable as DockviewMutableDisposable, DockviewPanel, DockviewReact, DraggablePaneviewPanel, Gridview, GridviewApi, GridviewComponent, GridviewPanel, GridviewReact, LayoutPriority, LocalSelectionTransfer, Orientation, PaneFramework, PaneTransfer, PanelTransfer, Paneview, PaneviewApi, PaneviewComponent, PaneviewPanel, PaneviewReact, ReactPart, ReactPartContext, SashState, Sizing, Splitview, SplitviewApi, SplitviewComponent, SplitviewPanel, SplitviewReact, Tab, createComponent, directionToPosition, getDirectionOrientation, getGridLocation, getLocationOrientation, getPaneData, getPanelData, getRelativeLocation, indexInParent, isGridBranchNode, isGroupOptionsWithGroup, isGroupOptionsWithPanel, isPanelOptionsWithGroup, isPanelOptionsWithPanel, isReactElement, orthogonal, positionToDirection, toTarget, usePortalsLifecycle, watchElementResize };
7961
+ export { BaseGrid, ContentContainer, DefaultDockviewDeserialzier, DefaultTab, DockviewApi, DockviewComponent, CompositeDisposable as DockviewCompositeDisposable, DockviewDefaultTab, DockviewDropTargets, Emitter as DockviewEmitter, Event as DockviewEvent, DockviewGroupPanel, DockviewGroupPanelModel, MutableDisposable as DockviewMutableDisposable, DockviewPanel, DockviewReact, DraggablePaneviewPanel, Gridview, GridviewApi, GridviewComponent, GridviewPanel, GridviewReact, LayoutPriority, LocalSelectionTransfer, Orientation, PaneFramework, PaneTransfer, PanelTransfer, Paneview, PaneviewApi, PaneviewComponent, PaneviewPanel, PaneviewReact, ReactPart, ReactPartContext, SashState, Sizing, Splitview, SplitviewApi, SplitviewComponent, SplitviewPanel, SplitviewReact, Tab, createComponent, directionToPosition, getDirectionOrientation, getGridLocation, getLocationOrientation, getPaneData, getPanelData, getRelativeLocation, indexInParent, isGridBranchNode, isGroupOptionsWithGroup, isGroupOptionsWithPanel, isPanelOptionsWithGroup, isPanelOptionsWithPanel, isReactElement, orthogonal, positionToDirection, toTarget, usePortalsLifecycle };
7962
+ //# sourceMappingURL=dockview.esm.js.map