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
  */
@@ -326,6 +326,31 @@ class MutableDisposable {
326
326
  }
327
327
  }
328
328
 
329
+ function createComponent(id, componentName, components = {}, frameworkComponents = {}, createFrameworkComponent, fallback) {
330
+ const Component = typeof componentName === 'string'
331
+ ? components[componentName]
332
+ : undefined;
333
+ const FrameworkComponent = typeof componentName === 'string'
334
+ ? frameworkComponents[componentName]
335
+ : undefined;
336
+ if (Component && FrameworkComponent) {
337
+ throw new Error(`Cannot create '${id}'. component '${componentName}' registered as both a component and frameworkComponent`);
338
+ }
339
+ if (FrameworkComponent) {
340
+ if (!createFrameworkComponent) {
341
+ throw new Error(`Cannot create '${id}' for framework component '${componentName}'. you must register a frameworkPanelWrapper to use framework components`);
342
+ }
343
+ return createFrameworkComponent.createComponent(id, componentName, FrameworkComponent);
344
+ }
345
+ if (!Component) {
346
+ if (fallback) {
347
+ return fallback();
348
+ }
349
+ throw new Error(`Cannot create '${id}', no component '${componentName}' provided`);
350
+ }
351
+ return new Component(id, componentName);
352
+ }
353
+
329
354
  function watchElementResize(element, cb) {
330
355
  const observer = new ResizeObserver((entires) => {
331
356
  /**
@@ -439,31 +464,16 @@ class FocusTracker extends CompositeDisposable {
439
464
  refreshState() {
440
465
  this._refreshStateHandler();
441
466
  }
442
- }
443
-
444
- function createComponent(id, componentName, components = {}, frameworkComponents = {}, createFrameworkComponent, fallback) {
445
- const Component = typeof componentName === 'string'
446
- ? components[componentName]
447
- : undefined;
448
- const FrameworkComponent = typeof componentName === 'string'
449
- ? frameworkComponents[componentName]
450
- : undefined;
451
- if (Component && FrameworkComponent) {
452
- throw new Error(`Cannot create '${id}'. component '${componentName}' registered as both a component and frameworkComponent`);
453
- }
454
- if (FrameworkComponent) {
455
- if (!createFrameworkComponent) {
456
- throw new Error(`Cannot create '${id}' for framework component '${componentName}'. you must register a frameworkPanelWrapper to use framework components`);
457
- }
458
- return createFrameworkComponent.createComponent(id, componentName, FrameworkComponent);
459
- }
460
- if (!Component) {
461
- if (fallback) {
462
- return fallback();
463
- }
464
- throw new Error(`Cannot create '${id}', no component '${componentName}' provided`);
465
- }
466
- return new Component(id, componentName);
467
+ }
468
+ // quasi: apparently, but not really; seemingly
469
+ const QUASI_PREVENT_DEFAULT_KEY = 'dv-quasiPreventDefault';
470
+ // mark an event directly for other listeners to check
471
+ function quasiPreventDefault(event) {
472
+ event[QUASI_PREVENT_DEFAULT_KEY] = true;
473
+ }
474
+ // check if this event has been marked
475
+ function quasiDefaultPrevented(event) {
476
+ return event[QUASI_PREVENT_DEFAULT_KEY];
467
477
  }
468
478
 
469
479
  function tail(arr) {
@@ -514,6 +524,14 @@ function firstIndex(array, fn) {
514
524
  }
515
525
  }
516
526
  return -1;
527
+ }
528
+ function remove(array, value) {
529
+ const index = array.findIndex((t) => t === value);
530
+ if (index > -1) {
531
+ array.splice(index, 1);
532
+ return true;
533
+ }
534
+ return false;
517
535
  }
518
536
 
519
537
  const clamp = (value, min, max) => {
@@ -943,7 +961,7 @@ class Splitview {
943
961
  //add sash
944
962
  const sash = document.createElement('div');
945
963
  sash.className = 'sash';
946
- const onStart = (event) => {
964
+ const onPointerStart = (event) => {
947
965
  for (const item of this.viewItems) {
948
966
  item.enabled = false;
949
967
  }
@@ -1002,11 +1020,10 @@ class Splitview {
1002
1020
  size: snappedViewItem.size,
1003
1021
  };
1004
1022
  }
1005
- //
1006
- const mousemove = (mousemoveEvent) => {
1023
+ const onPointerMove = (event) => {
1007
1024
  const current = this._orientation === exports.Orientation.HORIZONTAL
1008
- ? mousemoveEvent.clientX
1009
- : mousemoveEvent.clientY;
1025
+ ? event.clientX
1026
+ : event.clientY;
1010
1027
  const delta = current - start;
1011
1028
  this.resize(sashIndex, delta, sizes, undefined, undefined, minDelta, maxDelta, snapBefore, snapAfter);
1012
1029
  this.distributeEmptySpace();
@@ -1020,18 +1037,20 @@ class Splitview {
1020
1037
  iframe.style.pointerEvents = 'auto';
1021
1038
  }
1022
1039
  this.saveProportions();
1023
- document.removeEventListener('mousemove', mousemove);
1024
- document.removeEventListener('mouseup', end);
1040
+ document.removeEventListener('pointermove', onPointerMove);
1041
+ document.removeEventListener('pointerup', end);
1042
+ document.removeEventListener('pointercancel', end);
1025
1043
  this._onDidSashEnd.fire(undefined);
1026
1044
  };
1027
- document.addEventListener('mousemove', mousemove);
1028
- document.addEventListener('mouseup', end);
1045
+ document.addEventListener('pointermove', onPointerMove);
1046
+ document.addEventListener('pointerup', end);
1047
+ document.addEventListener('pointercancel', end);
1029
1048
  };
1030
- sash.addEventListener('mousedown', onStart);
1049
+ sash.addEventListener('pointerdown', onPointerStart);
1031
1050
  const sashItem = {
1032
1051
  container: sash,
1033
1052
  disposable: () => {
1034
- sash.removeEventListener('mousedown', onStart);
1053
+ sash.removeEventListener('pointerdown', onPointerStart);
1035
1054
  this.sashContainer.removeChild(sash);
1036
1055
  },
1037
1056
  };
@@ -1655,7 +1674,7 @@ class BranchNode extends CompositeDisposable {
1655
1674
  : true,
1656
1675
  };
1657
1676
  }),
1658
- size: this.size,
1677
+ size: this.orthogonalSize,
1659
1678
  };
1660
1679
  this.children = childDescriptors.map((c) => c.node);
1661
1680
  this.splitview = new Splitview(this.element, {
@@ -1718,7 +1737,7 @@ class BranchNode extends CompositeDisposable {
1718
1737
  layout(size, orthogonalSize) {
1719
1738
  this._size = orthogonalSize;
1720
1739
  this._orthogonalSize = size;
1721
- this.splitview.layout(this.size, this.orthogonalSize);
1740
+ this.splitview.layout(orthogonalSize, size);
1722
1741
  }
1723
1742
  addChild(node, size, index, skipLayout) {
1724
1743
  if (index < 0 || index > this.children.length) {
@@ -1943,9 +1962,9 @@ class Gridview {
1943
1962
  this._deserialize(json.root, orientation, deserializer, height);
1944
1963
  }
1945
1964
  _deserialize(root, orientation, deserializer, orthogonalSize) {
1946
- this.root = this._deserializeNode(root, orientation, deserializer, orthogonalSize, true);
1965
+ this.root = this._deserializeNode(root, orientation, deserializer, orthogonalSize);
1947
1966
  }
1948
- _deserializeNode(node, orientation, deserializer, orthogonalSize, isRoot = false) {
1967
+ _deserializeNode(node, orientation, deserializer, orthogonalSize) {
1949
1968
  let result;
1950
1969
  if (node.type === 'branch') {
1951
1970
  const serializedChildren = node.data;
@@ -1955,9 +1974,9 @@ class Gridview {
1955
1974
  visible: serializedChild.visible,
1956
1975
  };
1957
1976
  });
1958
- // HORIZONTAL => height=orthogonalsize width=size
1959
- // VERTICAL => height=size width=orthogonalsize
1960
- result = new BranchNode(orientation, this.proportionalLayout, this.styles, isRoot ? orthogonalSize : node.size, isRoot ? node.size : orthogonalSize, children);
1977
+ result = new BranchNode(orientation, this.proportionalLayout, this.styles, node.size, // <- orthogonal size - flips at each depth
1978
+ orthogonalSize, // <- size - flips at each depth
1979
+ children);
1961
1980
  }
1962
1981
  else {
1963
1982
  result = new LeafNode(deserializer.fromJSON(node), orientation, orthogonalSize, node.size);
@@ -1990,7 +2009,8 @@ class Gridview {
1990
2009
  const oldRoot = this.root;
1991
2010
  oldRoot.element.remove();
1992
2011
  this._root = new BranchNode(orthogonal(oldRoot.orientation), this.proportionalLayout, this.styles, this.root.orthogonalSize, this.root.size);
1993
- if (oldRoot.children.length === 1) {
2012
+ if (oldRoot.children.length === 0) ;
2013
+ else if (oldRoot.children.length === 1) {
1994
2014
  // can remove one level of redundant branching if there is only a single child
1995
2015
  const childReference = oldRoot.children[0];
1996
2016
  const child = oldRoot.removeChild(0); // remove to prevent disposal when disposing of unwanted root
@@ -2124,52 +2144,70 @@ class Gridview {
2124
2144
  if (!(parent instanceof BranchNode)) {
2125
2145
  throw new Error('Invalid location');
2126
2146
  }
2127
- const node = parent.children[index];
2128
- if (!(node instanceof LeafNode)) {
2147
+ const nodeToRemove = parent.children[index];
2148
+ if (!(nodeToRemove instanceof LeafNode)) {
2129
2149
  throw new Error('Invalid location');
2130
2150
  }
2131
2151
  parent.removeChild(index, sizing);
2132
- if (parent.children.length === 0) {
2133
- return node.view;
2134
- }
2135
- if (parent.children.length > 1) {
2136
- return node.view;
2137
- }
2152
+ nodeToRemove.dispose();
2153
+ if (parent.children.length !== 1) {
2154
+ return nodeToRemove.view;
2155
+ }
2156
+ // if the parent has only one child and we know the parent is a BranchNode we can make the tree
2157
+ // more efficiently spaced by replacing the parent BranchNode with the child.
2158
+ // if that child is a LeafNode then we simply replace the BranchNode with the child otherwise if the child
2159
+ // is a BranchNode too we should spread it's children into the grandparent.
2160
+ // refer to the remaining child as the sibling
2138
2161
  const sibling = parent.children[0];
2139
2162
  if (pathToParent.length === 0) {
2140
- // parent is root
2163
+ // if the parent is root
2141
2164
  if (sibling instanceof LeafNode) {
2142
- return node.view;
2165
+ // if the sibling is a leaf node no action is required
2166
+ return nodeToRemove.view;
2143
2167
  }
2144
- // we must promote sibling to be the new root
2168
+ // otherwise the sibling is a branch node. since the parent is the root and the root has only one child
2169
+ // which is a branch node we can just set this branch node to be the new root node
2170
+ // for good housekeeping we'll removing the sibling from it's existing tree
2145
2171
  parent.removeChild(0, sizing);
2172
+ // and set that sibling node to be root
2146
2173
  this.root = sibling;
2147
- return node.view;
2174
+ return nodeToRemove.view;
2148
2175
  }
2176
+ // otherwise the parent is apart of a large sub-tree
2149
2177
  const [grandParent, ..._] = [...pathToParent].reverse();
2150
2178
  const [parentIndex, ...__] = [...rest].reverse();
2151
2179
  const isSiblingVisible = parent.isChildVisible(0);
2180
+ // either way we need to remove the sibling from it's existing tree
2152
2181
  parent.removeChild(0, sizing);
2182
+ // note the sizes of all of the grandparents children
2153
2183
  const sizes = grandParent.children.map((_size, i) => grandParent.getChildSize(i));
2154
- grandParent.removeChild(parentIndex, sizing);
2184
+ // remove the parent from the grandparent since we are moving the sibling to take the parents place
2185
+ // this parent is no longer used and can be disposed of
2186
+ grandParent.removeChild(parentIndex, sizing).dispose();
2155
2187
  if (sibling instanceof BranchNode) {
2188
+ // replace the parent with the siblings children
2156
2189
  sizes.splice(parentIndex, 1, ...sibling.children.map((c) => c.size));
2190
+ // and add those siblings to the grandparent
2157
2191
  for (let i = 0; i < sibling.children.length; i++) {
2158
2192
  const child = sibling.children[i];
2159
2193
  grandParent.addChild(child, child.size, parentIndex + i);
2160
2194
  }
2161
2195
  }
2162
2196
  else {
2197
+ // otherwise create a new leaf node and add that to the grandparent
2163
2198
  const newSibling = new LeafNode(sibling.view, orthogonal(sibling.orientation), sibling.size);
2164
2199
  const siblingSizing = isSiblingVisible
2165
2200
  ? sibling.orthogonalSize
2166
2201
  : exports.Sizing.Invisible(sibling.orthogonalSize);
2167
2202
  grandParent.addChild(newSibling, siblingSizing, parentIndex);
2168
2203
  }
2204
+ // the containing node of the sibling is no longer required and can be disposed of
2205
+ sibling.dispose();
2206
+ // resize everything
2169
2207
  for (let i = 0; i < sizes.length; i++) {
2170
2208
  grandParent.resizeChild(i, sizes[i]);
2171
2209
  }
2172
- return node.view;
2210
+ return nodeToRemove.view;
2173
2211
  }
2174
2212
  layout(width, height) {
2175
2213
  const [size, orthogonalSize] = this.root.orientation === exports.Orientation.HORIZONTAL
@@ -2488,6 +2526,9 @@ class DockviewApi {
2488
2526
  addPanel(options) {
2489
2527
  return this.component.addPanel(options);
2490
2528
  }
2529
+ removePanel(panel) {
2530
+ this.component.removePanel(panel);
2531
+ }
2491
2532
  addGroup(options) {
2492
2533
  return this.component.addGroup(options);
2493
2534
  }
@@ -2506,6 +2547,9 @@ class DockviewApi {
2506
2547
  getGroup(id) {
2507
2548
  return this.component.getPanel(id);
2508
2549
  }
2550
+ addFloatingGroup(item, coord) {
2551
+ return this.component.addFloatingGroup(item, coord);
2552
+ }
2509
2553
  fromJSON(data) {
2510
2554
  this.component.fromJSON(data);
2511
2555
  }
@@ -2598,10 +2642,14 @@ class Droptarget extends CompositeDisposable {
2598
2642
  this._onDrop = new Emitter();
2599
2643
  this.onDrop = this._onDrop.event;
2600
2644
  // use a set to take advantage of #<set>.has
2601
- const acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
2645
+ this._acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
2602
2646
  this.addDisposables(this._onDrop, new DragAndDropObserver(this.element, {
2603
2647
  onDragEnter: () => undefined,
2604
2648
  onDragOver: (e) => {
2649
+ if (this._acceptedTargetZonesSet.size === 0) {
2650
+ this.removeDropTarget();
2651
+ return;
2652
+ }
2605
2653
  const width = this.element.clientWidth;
2606
2654
  const height = this.element.clientHeight;
2607
2655
  if (width === 0 || height === 0) {
@@ -2610,20 +2658,28 @@ class Droptarget extends CompositeDisposable {
2610
2658
  const rect = e.currentTarget.getBoundingClientRect();
2611
2659
  const x = e.clientX - rect.left;
2612
2660
  const y = e.clientY - rect.top;
2613
- const quadrant = this.calculateQuadrant(acceptedTargetZonesSet, x, y, width, height);
2614
- if (quadrant === null) {
2661
+ const quadrant = this.calculateQuadrant(this._acceptedTargetZonesSet, x, y, width, height);
2662
+ /**
2663
+ * If the event has already been used by another DropTarget instance
2664
+ * then don't show a second drop target, only one target should be
2665
+ * active at any one time
2666
+ */
2667
+ if (this.isAlreadyUsed(e) || quadrant === null) {
2615
2668
  // no drop target should be displayed
2616
2669
  this.removeDropTarget();
2617
2670
  return;
2618
2671
  }
2619
2672
  if (typeof this.options.canDisplayOverlay === 'boolean') {
2620
2673
  if (!this.options.canDisplayOverlay) {
2674
+ this.removeDropTarget();
2621
2675
  return;
2622
2676
  }
2623
2677
  }
2624
2678
  else if (!this.options.canDisplayOverlay(e, quadrant)) {
2679
+ this.removeDropTarget();
2625
2680
  return;
2626
2681
  }
2682
+ this.markAsUsed(e);
2627
2683
  if (!this.targetElement) {
2628
2684
  this.targetElement = document.createElement('div');
2629
2685
  this.targetElement.className = 'drop-target-dropzone';
@@ -2634,12 +2690,6 @@ class Droptarget extends CompositeDisposable {
2634
2690
  this.element.classList.add('drop-target');
2635
2691
  this.element.append(this.targetElement);
2636
2692
  }
2637
- if (this.options.acceptedTargetZones.length === 0) {
2638
- return;
2639
- }
2640
- if (!this.targetElement || !this.overlayElement) {
2641
- return;
2642
- }
2643
2693
  this.toggleClasses(quadrant, width, height);
2644
2694
  this.setState(quadrant);
2645
2695
  },
@@ -2662,10 +2712,26 @@ class Droptarget extends CompositeDisposable {
2662
2712
  },
2663
2713
  }));
2664
2714
  }
2715
+ setTargetZones(acceptedTargetZones) {
2716
+ this._acceptedTargetZonesSet = new Set(acceptedTargetZones);
2717
+ }
2665
2718
  dispose() {
2666
2719
  this.removeDropTarget();
2667
2720
  super.dispose();
2668
2721
  }
2722
+ /**
2723
+ * Add a property to the event object for other potential listeners to check
2724
+ */
2725
+ markAsUsed(event) {
2726
+ event[Droptarget.USED_EVENT_ID] = true;
2727
+ }
2728
+ /**
2729
+ * Check is the event has already been used by another instance od DropTarget
2730
+ */
2731
+ isAlreadyUsed(event) {
2732
+ const value = event[Droptarget.USED_EVENT_ID];
2733
+ return typeof value === 'boolean' && value;
2734
+ }
2669
2735
  toggleClasses(quadrant, width, height) {
2670
2736
  var _a, _b, _c, _d;
2671
2737
  if (!this.overlayElement) {
@@ -2760,6 +2826,7 @@ class Droptarget extends CompositeDisposable {
2760
2826
  }
2761
2827
  }
2762
2828
  }
2829
+ Droptarget.USED_EVENT_ID = '__dockview_droptarget_event_is_used__';
2763
2830
  function calculateQuadrantAsPercentage(overlayType, x, y, width, height, threshold) {
2764
2831
  const xp = (100 * x) / width;
2765
2832
  const yp = (100 * y) / height;
@@ -2889,8 +2956,15 @@ class DragHandler extends CompositeDisposable {
2889
2956
  this.addDisposables(this._onDragStart, this.dataDisposable, this.pointerEventsDisposable);
2890
2957
  this.configure();
2891
2958
  }
2959
+ isCancelled(_event) {
2960
+ return false;
2961
+ }
2892
2962
  configure() {
2893
2963
  this.addDisposables(this._onDragStart, addDisposableListener(this.el, 'dragstart', (event) => {
2964
+ if (this.isCancelled(event)) {
2965
+ event.preventDefault();
2966
+ return;
2967
+ }
2894
2968
  const iframes = [
2895
2969
  ...getElementsByTagName('iframe'),
2896
2970
  ...getElementsByTagName('webview'),
@@ -2964,13 +3038,6 @@ class Tab extends CompositeDisposable {
2964
3038
  if (event.defaultPrevented) {
2965
3039
  return;
2966
3040
  }
2967
- /**
2968
- * TODO: alternative to stopPropagation
2969
- *
2970
- * I need to stop the event propagation here since otherwise it'll be intercepted by event handlers
2971
- * on the tabs-container. I cannot use event.preventDefault() since I need the on DragStart event to occur
2972
- */
2973
- event.stopPropagation();
2974
3041
  this._onChanged.fire(event);
2975
3042
  }));
2976
3043
  this.droptarget = new Droptarget(this._element, {
@@ -3028,6 +3095,22 @@ class GroupDragHandler extends DragHandler {
3028
3095
  this.accessorId = accessorId;
3029
3096
  this.group = group;
3030
3097
  this.panelTransfer = LocalSelectionTransfer.getInstance();
3098
+ this.addDisposables(addDisposableListener(element, 'mousedown', (e) => {
3099
+ if (e.shiftKey) {
3100
+ /**
3101
+ * You cannot call e.preventDefault() because that will prevent drag events from firing
3102
+ * but we also need to stop any group overlay drag events from occuring
3103
+ * Use a custom event marker that can be checked by the overlay drag events
3104
+ */
3105
+ quasiPreventDefault(e);
3106
+ }
3107
+ }, true));
3108
+ }
3109
+ isCancelled(_event) {
3110
+ if (this.group.api.isFloating && !_event.shiftKey) {
3111
+ return true;
3112
+ }
3113
+ return false;
3031
3114
  }
3032
3115
  getData(dataTransfer) {
3033
3116
  this.panelTransfer.setData([new PanelTransfer(this.accessorId, this.group.id, null)], PanelTransfer.prototype);
@@ -3118,17 +3201,30 @@ class TabsContainer extends CompositeDisposable {
3118
3201
  hide() {
3119
3202
  this._element.style.display = 'none';
3120
3203
  }
3121
- setActionElement(element) {
3122
- if (this.actions === element) {
3204
+ setRightActionsElement(element) {
3205
+ if (this.rightActions === element) {
3206
+ return;
3207
+ }
3208
+ if (this.rightActions) {
3209
+ this.rightActions.remove();
3210
+ this.rightActions = undefined;
3211
+ }
3212
+ if (element) {
3213
+ this.rightActionsContainer.appendChild(element);
3214
+ this.rightActions = element;
3215
+ }
3216
+ }
3217
+ setLeftActionsElement(element) {
3218
+ if (this.leftActions === element) {
3123
3219
  return;
3124
3220
  }
3125
- if (this.actions) {
3126
- this.actions.remove();
3127
- this.actions = undefined;
3221
+ if (this.leftActions) {
3222
+ this.leftActions.remove();
3223
+ this.leftActions = undefined;
3128
3224
  }
3129
3225
  if (element) {
3130
- this.actionContainer.appendChild(element);
3131
- this.actions = element;
3226
+ this.leftActionsContainer.appendChild(element);
3227
+ this.leftActions = element;
3132
3228
  }
3133
3229
  }
3134
3230
  get element() {
@@ -3163,19 +3259,35 @@ class TabsContainer extends CompositeDisposable {
3163
3259
  toggleClass(this._element, 'dv-single-tab', this.size === 1);
3164
3260
  }
3165
3261
  }));
3166
- this.actionContainer = document.createElement('div');
3167
- this.actionContainer.className = 'action-container';
3262
+ this.rightActionsContainer = document.createElement('div');
3263
+ this.rightActionsContainer.className = 'right-actions-container';
3264
+ this.leftActionsContainer = document.createElement('div');
3265
+ this.leftActionsContainer.className = 'left-actions-container';
3168
3266
  this.tabContainer = document.createElement('div');
3169
3267
  this.tabContainer.className = 'tabs-container';
3170
3268
  this.voidContainer = new VoidContainer(this.accessor, this.group);
3171
3269
  this._element.appendChild(this.tabContainer);
3270
+ this._element.appendChild(this.leftActionsContainer);
3172
3271
  this._element.appendChild(this.voidContainer.element);
3173
- this._element.appendChild(this.actionContainer);
3272
+ this._element.appendChild(this.rightActionsContainer);
3174
3273
  this.addDisposables(this.voidContainer, this.voidContainer.onDrop((event) => {
3175
3274
  this._onDrop.fire({
3176
3275
  event: event.nativeEvent,
3177
3276
  index: this.tabs.length,
3178
3277
  });
3278
+ }), addDisposableListener(this.voidContainer.element, 'mousedown', (event) => {
3279
+ const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3280
+ if (isFloatingGroupsEnabled &&
3281
+ event.shiftKey &&
3282
+ !this.group.api.isFloating) {
3283
+ event.preventDefault();
3284
+ const { top, left } = this.element.getBoundingClientRect();
3285
+ const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
3286
+ this.accessor.addFloatingGroup(this.group, {
3287
+ x: left - rootLeft + 20,
3288
+ y: top - rootTop + 20,
3289
+ }, { inDragMode: true });
3290
+ }
3179
3291
  }), addDisposableListener(this.tabContainer, 'mousedown', (event) => {
3180
3292
  if (event.defaultPrevented) {
3181
3293
  return;
@@ -3229,6 +3341,21 @@ class TabsContainer extends CompositeDisposable {
3229
3341
  tabToAdd.setContent(panel.view.tab);
3230
3342
  const disposable = CompositeDisposable.from(tabToAdd.onChanged((event) => {
3231
3343
  var _a;
3344
+ const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3345
+ const isFloatingWithOnePanel = this.group.api.isFloating && this.size === 1;
3346
+ if (isFloatingGroupsEnabled &&
3347
+ !isFloatingWithOnePanel &&
3348
+ event.shiftKey) {
3349
+ event.preventDefault();
3350
+ const panel = this.accessor.getGroupPanel(tabToAdd.panelId);
3351
+ const { top, left } = tabToAdd.element.getBoundingClientRect();
3352
+ const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
3353
+ this.accessor.addFloatingGroup(panel, {
3354
+ x: left - rootLeft,
3355
+ y: top - rootTop,
3356
+ }, { inDragMode: true });
3357
+ return;
3358
+ }
3232
3359
  const alreadyFocused = panel.id === ((_a = this.group.model.activePanel) === null || _a === void 0 ? void 0 : _a.id) &&
3233
3360
  this.group.model.isContentFocused;
3234
3361
  const isLeftClick = event.button === 0;
@@ -3298,6 +3425,17 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3298
3425
  }
3299
3426
  return isAncestor(document.activeElement, this.contentContainer.element);
3300
3427
  }
3428
+ get isFloating() {
3429
+ return this._isFloating;
3430
+ }
3431
+ set isFloating(value) {
3432
+ this._isFloating = value;
3433
+ this.dropTarget.setTargetZones(value ? ['center'] : ['top', 'bottom', 'left', 'right', 'center']);
3434
+ toggleClass(this.container, 'dv-groupview-floating', value);
3435
+ this.groupPanel.api._onDidFloatingStateChange.fire({
3436
+ isFloating: this.isFloating,
3437
+ });
3438
+ }
3301
3439
  constructor(container, accessor, id, options, groupPanel) {
3302
3440
  super();
3303
3441
  this.container = container;
@@ -3307,6 +3445,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3307
3445
  this.groupPanel = groupPanel;
3308
3446
  this._isGroupActive = false;
3309
3447
  this._locked = false;
3448
+ this._isFloating = false;
3310
3449
  this.mostRecentlyUsed = [];
3311
3450
  this._onDidChange = new Emitter();
3312
3451
  this.onDidChange = this._onDidChange.event;
@@ -3323,7 +3462,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3323
3462
  this.onDidRemovePanel = this._onDidRemovePanel.event;
3324
3463
  this._onDidActivePanelChange = new Emitter();
3325
3464
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
3326
- this.container.classList.add('groupview');
3465
+ toggleClass(this.container, 'groupview', true);
3327
3466
  this.tabsContainer = new TabsContainer(this.accessor, this.groupPanel);
3328
3467
  this.contentContainer = new ContentContainer();
3329
3468
  this.dropTarget = new Droptarget(this.contentContainer.element, {
@@ -3333,6 +3472,9 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3333
3472
  return false;
3334
3473
  }
3335
3474
  const data = getPanelData();
3475
+ if (!data && event.shiftKey && !this.isFloating) {
3476
+ return false;
3477
+ }
3336
3478
  if (data && data.viewId === this.accessor.id) {
3337
3479
  if (data.groupId === this.id) {
3338
3480
  if (position === 'center') {
@@ -3377,14 +3519,25 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3377
3519
  // correctly initialized
3378
3520
  this.setActive(this.isActive, true, true);
3379
3521
  this.updateContainer();
3380
- if (this.accessor.options.createGroupControlElement) {
3381
- this._control = this.accessor.options.createGroupControlElement(this.groupPanel);
3382
- this.addDisposables(this._control);
3383
- this._control.init({
3522
+ if (this.accessor.options.createRightHeaderActionsElement) {
3523
+ this._rightHeaderActions =
3524
+ this.accessor.options.createRightHeaderActionsElement(this.groupPanel);
3525
+ this.addDisposables(this._rightHeaderActions);
3526
+ this._rightHeaderActions.init({
3527
+ containerApi: new DockviewApi(this.accessor),
3528
+ api: this.groupPanel.api,
3529
+ });
3530
+ this.tabsContainer.setRightActionsElement(this._rightHeaderActions.element);
3531
+ }
3532
+ if (this.accessor.options.createLeftHeaderActionsElement) {
3533
+ this._leftHeaderActions =
3534
+ this.accessor.options.createLeftHeaderActionsElement(this.groupPanel);
3535
+ this.addDisposables(this._leftHeaderActions);
3536
+ this._leftHeaderActions.init({
3384
3537
  containerApi: new DockviewApi(this.accessor),
3385
3538
  api: this.groupPanel.api,
3386
3539
  });
3387
- this.tabsContainer.setActionElement(this._control.element);
3540
+ this.tabsContainer.setLeftActionsElement(this._leftHeaderActions.element);
3388
3541
  }
3389
3542
  }
3390
3543
  indexOf(panel) {
@@ -3517,7 +3670,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3517
3670
  return this._activePanel === panel;
3518
3671
  }
3519
3672
  updateActions(element) {
3520
- this.tabsContainer.setActionElement(element);
3673
+ this.tabsContainer.setRightActionsElement(element);
3521
3674
  }
3522
3675
  setActive(isGroupActive, skipFocus = false, force = false) {
3523
3676
  var _a, _b, _c, _d;
@@ -3689,9 +3842,10 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3689
3842
  }
3690
3843
  }
3691
3844
  dispose() {
3692
- var _a, _b;
3845
+ var _a, _b, _c;
3693
3846
  super.dispose();
3694
- (_b = (_a = this.watermark) === null || _a === void 0 ? void 0 : _a.dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
3847
+ (_a = this.watermark) === null || _a === void 0 ? void 0 : _a.element.remove();
3848
+ (_c = (_b = this.watermark) === null || _b === void 0 ? void 0 : _b.dispose) === null || _c === void 0 ? void 0 : _c.call(_b);
3695
3849
  for (const panel of this.panels) {
3696
3850
  panel.dispose();
3697
3851
  }
@@ -4485,8 +4639,8 @@ class GridviewPanel extends BasePanelView {
4485
4639
  get isActive() {
4486
4640
  return this.api.isActive;
4487
4641
  }
4488
- constructor(id, component, options) {
4489
- super(id, component, new GridviewPanelApiImpl(id));
4642
+ constructor(id, component, options, api) {
4643
+ super(id, component, api !== null && api !== void 0 ? api : new GridviewPanelApiImpl(id));
4490
4644
  this._evaluatedMinimumWidth = 0;
4491
4645
  this._evaluatedMaximumWidth = Number.MAX_SAFE_INTEGER;
4492
4646
  this._evaluatedMinimumHeight = 0;
@@ -4584,6 +4738,32 @@ class GridviewPanel extends BasePanelView {
4584
4738
  }
4585
4739
  }
4586
4740
 
4741
+ class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
4742
+ get isFloating() {
4743
+ if (!this._group) {
4744
+ throw new Error(`DockviewGroupPanelApiImpl not initialized`);
4745
+ }
4746
+ return this._group.model.isFloating;
4747
+ }
4748
+ constructor(id, accessor) {
4749
+ super(id);
4750
+ this.accessor = accessor;
4751
+ this._onDidFloatingStateChange = new Emitter();
4752
+ this.onDidFloatingStateChange = this._onDidFloatingStateChange.event;
4753
+ this.addDisposables(this._onDidFloatingStateChange);
4754
+ }
4755
+ moveTo(options) {
4756
+ var _a;
4757
+ if (!this._group) {
4758
+ throw new Error(`DockviewGroupPanelApiImpl not initialized`);
4759
+ }
4760
+ this.accessor.moveGroupOrPanel(options.group, this._group.id, undefined, (_a = options.position) !== null && _a !== void 0 ? _a : 'center');
4761
+ }
4762
+ initialize(group) {
4763
+ this._group = group;
4764
+ }
4765
+ }
4766
+
4587
4767
  class DockviewGroupPanel extends GridviewPanel {
4588
4768
  get panels() {
4589
4769
  return this._model.panels;
@@ -4610,7 +4790,8 @@ class DockviewGroupPanel extends GridviewPanel {
4610
4790
  super(id, 'groupview_default', {
4611
4791
  minimumHeight: 100,
4612
4792
  minimumWidth: 100,
4613
- });
4793
+ }, new DockviewGroupPanelApiImpl(id, accessor));
4794
+ this.api.initialize(this); // cannot use 'this' after after 'super' call
4614
4795
  this._model = new DockviewGroupPanelModel(this.element, accessor, id, options, this);
4615
4796
  }
4616
4797
  initialize() {
@@ -4628,7 +4809,6 @@ class DockviewGroupPanel extends GridviewPanel {
4628
4809
  return this._model;
4629
4810
  }
4630
4811
  toJSON() {
4631
- // TODO fix typing
4632
4812
  return this.model.toJSON();
4633
4813
  }
4634
4814
  }
@@ -4682,9 +4862,10 @@ class DockviewPanelApiImpl extends GridviewPanelApiImpl {
4682
4862
  get group() {
4683
4863
  return this._group;
4684
4864
  }
4685
- constructor(panel, group) {
4865
+ constructor(panel, group, accessor) {
4686
4866
  super(panel.id);
4687
4867
  this.panel = panel;
4868
+ this.accessor = accessor;
4688
4869
  this._onDidTitleChange = new Emitter();
4689
4870
  this.onDidTitleChange = this._onDidTitleChange.event;
4690
4871
  this._onDidActiveGroupChange = new Emitter();
@@ -4696,6 +4877,10 @@ class DockviewPanelApiImpl extends GridviewPanelApiImpl {
4696
4877
  this._group = group;
4697
4878
  this.addDisposables(this.disposable, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange);
4698
4879
  }
4880
+ moveTo(options) {
4881
+ var _a;
4882
+ this.accessor.moveGroupOrPanel(options.group, this._group.id, this.panel.id, (_a = options.position) !== null && _a !== void 0 ? _a : 'center', options.index);
4883
+ }
4699
4884
  setTitle(title) {
4700
4885
  this.panel.setTitle(title);
4701
4886
  }
@@ -4720,7 +4905,7 @@ class DockviewPanel extends CompositeDisposable {
4720
4905
  this.containerApi = containerApi;
4721
4906
  this.view = view;
4722
4907
  this._group = group;
4723
- this.api = new DockviewPanelApiImpl(this, this._group);
4908
+ this.api = new DockviewPanelApiImpl(this, this._group, accessor);
4724
4909
  this.addDisposables(this.api.onActiveChange(() => {
4725
4910
  accessor.setActivePanel(this);
4726
4911
  }), this.api.onDidSizeChange((event) => {
@@ -5061,6 +5246,296 @@ class Watermark extends CompositeDisposable {
5061
5246
  }
5062
5247
  }
5063
5248
 
5249
+ const bringElementToFront = (() => {
5250
+ let previous = null;
5251
+ function pushToTop(element) {
5252
+ if (previous !== element && previous !== null) {
5253
+ toggleClass(previous, 'dv-bring-to-front', false);
5254
+ }
5255
+ toggleClass(element, 'dv-bring-to-front', true);
5256
+ previous = element;
5257
+ }
5258
+ return pushToTop;
5259
+ })();
5260
+ class Overlay extends CompositeDisposable {
5261
+ constructor(options) {
5262
+ super();
5263
+ this.options = options;
5264
+ this._element = document.createElement('div');
5265
+ this._onDidChange = new Emitter();
5266
+ this.onDidChange = this._onDidChange.event;
5267
+ this._onDidChangeEnd = new Emitter();
5268
+ this.onDidChangeEnd = this._onDidChangeEnd.event;
5269
+ this.addDisposables(this._onDidChange, this._onDidChangeEnd);
5270
+ this._element.className = 'dv-resize-container';
5271
+ this.setupResize('top');
5272
+ this.setupResize('bottom');
5273
+ this.setupResize('left');
5274
+ this.setupResize('right');
5275
+ this.setupResize('topleft');
5276
+ this.setupResize('topright');
5277
+ this.setupResize('bottomleft');
5278
+ this.setupResize('bottomright');
5279
+ this._element.appendChild(this.options.content);
5280
+ this.options.container.appendChild(this._element);
5281
+ // if input bad resize within acceptable boundaries
5282
+ this.setBounds({
5283
+ height: this.options.height,
5284
+ width: this.options.width,
5285
+ top: this.options.top,
5286
+ left: this.options.left,
5287
+ });
5288
+ }
5289
+ setBounds(bounds = {}) {
5290
+ if (typeof bounds.height === 'number') {
5291
+ this._element.style.height = `${bounds.height}px`;
5292
+ }
5293
+ if (typeof bounds.width === 'number') {
5294
+ this._element.style.width = `${bounds.width}px`;
5295
+ }
5296
+ if (typeof bounds.top === 'number') {
5297
+ this._element.style.top = `${bounds.top}px`;
5298
+ }
5299
+ if (typeof bounds.left === 'number') {
5300
+ this._element.style.left = `${bounds.left}px`;
5301
+ }
5302
+ const containerRect = this.options.container.getBoundingClientRect();
5303
+ const overlayRect = this._element.getBoundingClientRect();
5304
+ // region: ensure bounds within allowable limits
5305
+ // a minimum width of minimumViewportWidth must be inside the viewport
5306
+ const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5307
+ // a minimum height of minimumViewportHeight must be inside the viewport
5308
+ const yOffset = Math.max(0, overlayRect.height - this.options.minimumInViewportHeight);
5309
+ const left = clamp(overlayRect.left - containerRect.left, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5310
+ const top = clamp(overlayRect.top - containerRect.top, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5311
+ this._element.style.left = `${left}px`;
5312
+ this._element.style.top = `${top}px`;
5313
+ this._onDidChange.fire();
5314
+ }
5315
+ toJSON() {
5316
+ const container = this.options.container.getBoundingClientRect();
5317
+ const element = this._element.getBoundingClientRect();
5318
+ return {
5319
+ top: element.top - container.top,
5320
+ left: element.left - container.left,
5321
+ width: element.width,
5322
+ height: element.height,
5323
+ };
5324
+ }
5325
+ setupDrag(dragTarget, options = { inDragMode: false }) {
5326
+ const move = new MutableDisposable();
5327
+ const track = () => {
5328
+ let offset = null;
5329
+ const iframes = [
5330
+ ...getElementsByTagName('iframe'),
5331
+ ...getElementsByTagName('webview'),
5332
+ ];
5333
+ for (const iframe of iframes) {
5334
+ iframe.style.pointerEvents = 'none';
5335
+ }
5336
+ move.value = new CompositeDisposable({
5337
+ dispose: () => {
5338
+ for (const iframe of iframes) {
5339
+ iframe.style.pointerEvents = 'auto';
5340
+ }
5341
+ },
5342
+ }, addDisposableWindowListener(window, 'mousemove', (e) => {
5343
+ const containerRect = this.options.container.getBoundingClientRect();
5344
+ const x = e.clientX - containerRect.left;
5345
+ const y = e.clientY - containerRect.top;
5346
+ toggleClass(this._element, 'dv-resize-container-dragging', true);
5347
+ const overlayRect = this._element.getBoundingClientRect();
5348
+ if (offset === null) {
5349
+ offset = {
5350
+ x: e.clientX - overlayRect.left,
5351
+ y: e.clientY - overlayRect.top,
5352
+ };
5353
+ }
5354
+ const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5355
+ const yOffset = Math.max(0, overlayRect.height -
5356
+ this.options.minimumInViewportHeight);
5357
+ const left = clamp(x - offset.x, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5358
+ const top = clamp(y - offset.y, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5359
+ this.setBounds({ top, left });
5360
+ }), addDisposableWindowListener(window, 'mouseup', () => {
5361
+ toggleClass(this._element, 'dv-resize-container-dragging', false);
5362
+ move.dispose();
5363
+ this._onDidChangeEnd.fire();
5364
+ }));
5365
+ };
5366
+ this.addDisposables(move, addDisposableListener(dragTarget, 'mousedown', (event) => {
5367
+ if (event.defaultPrevented) {
5368
+ event.preventDefault();
5369
+ return;
5370
+ }
5371
+ // if somebody has marked this event then treat as a defaultPrevented
5372
+ // without actually calling event.preventDefault()
5373
+ if (quasiDefaultPrevented(event)) {
5374
+ return;
5375
+ }
5376
+ track();
5377
+ }), addDisposableListener(this.options.content, 'mousedown', (event) => {
5378
+ if (event.defaultPrevented) {
5379
+ return;
5380
+ }
5381
+ // if somebody has marked this event then treat as a defaultPrevented
5382
+ // without actually calling event.preventDefault()
5383
+ if (quasiDefaultPrevented(event)) {
5384
+ return;
5385
+ }
5386
+ if (event.shiftKey) {
5387
+ track();
5388
+ }
5389
+ }), addDisposableListener(this.options.content, 'mousedown', () => {
5390
+ bringElementToFront(this._element);
5391
+ }, true));
5392
+ bringElementToFront(this._element);
5393
+ if (options.inDragMode) {
5394
+ track();
5395
+ }
5396
+ }
5397
+ setupResize(direction) {
5398
+ const resizeHandleElement = document.createElement('div');
5399
+ resizeHandleElement.className = `dv-resize-handle-${direction}`;
5400
+ this._element.appendChild(resizeHandleElement);
5401
+ const move = new MutableDisposable();
5402
+ this.addDisposables(move, addDisposableListener(resizeHandleElement, 'mousedown', (e) => {
5403
+ e.preventDefault();
5404
+ let startPosition = null;
5405
+ const iframes = [
5406
+ ...getElementsByTagName('iframe'),
5407
+ ...getElementsByTagName('webview'),
5408
+ ];
5409
+ for (const iframe of iframes) {
5410
+ iframe.style.pointerEvents = 'none';
5411
+ }
5412
+ move.value = new CompositeDisposable(addDisposableWindowListener(window, 'mousemove', (e) => {
5413
+ const containerRect = this.options.container.getBoundingClientRect();
5414
+ const overlayRect = this._element.getBoundingClientRect();
5415
+ const y = e.clientY - containerRect.top;
5416
+ const x = e.clientX - containerRect.left;
5417
+ if (startPosition === null) {
5418
+ // record the initial dimensions since as all subsequence moves are relative to this
5419
+ startPosition = {
5420
+ originalY: y,
5421
+ originalHeight: overlayRect.height,
5422
+ originalX: x,
5423
+ originalWidth: overlayRect.width,
5424
+ };
5425
+ }
5426
+ let top = undefined;
5427
+ let height = undefined;
5428
+ let left = undefined;
5429
+ let width = undefined;
5430
+ const minimumInViewportHeight = this.options.minimumInViewportHeight;
5431
+ const minimumInViewportWidth = this.options.minimumInViewportWidth;
5432
+ function moveTop() {
5433
+ top = clamp(y, -Number.MAX_VALUE, startPosition.originalY +
5434
+ startPosition.originalHeight >
5435
+ containerRect.height
5436
+ ? containerRect.height -
5437
+ minimumInViewportHeight
5438
+ : Math.max(0, startPosition.originalY +
5439
+ startPosition.originalHeight -
5440
+ Overlay.MINIMUM_HEIGHT));
5441
+ height =
5442
+ startPosition.originalY +
5443
+ startPosition.originalHeight -
5444
+ top;
5445
+ }
5446
+ function moveBottom() {
5447
+ top =
5448
+ startPosition.originalY -
5449
+ startPosition.originalHeight;
5450
+ height = clamp(y - top, top < 0
5451
+ ? -top + minimumInViewportHeight
5452
+ : Overlay.MINIMUM_HEIGHT, Number.MAX_VALUE);
5453
+ }
5454
+ function moveLeft() {
5455
+ left = clamp(x, -Number.MAX_VALUE, startPosition.originalX +
5456
+ startPosition.originalWidth >
5457
+ containerRect.width
5458
+ ? containerRect.width -
5459
+ minimumInViewportWidth
5460
+ : Math.max(0, startPosition.originalX +
5461
+ startPosition.originalWidth -
5462
+ Overlay.MINIMUM_WIDTH));
5463
+ width =
5464
+ startPosition.originalX +
5465
+ startPosition.originalWidth -
5466
+ left;
5467
+ }
5468
+ function moveRight() {
5469
+ left =
5470
+ startPosition.originalX -
5471
+ startPosition.originalWidth;
5472
+ width = clamp(x - left, left < 0
5473
+ ? -left + minimumInViewportWidth
5474
+ : Overlay.MINIMUM_WIDTH, Number.MAX_VALUE);
5475
+ }
5476
+ switch (direction) {
5477
+ case 'top':
5478
+ moveTop();
5479
+ break;
5480
+ case 'bottom':
5481
+ moveBottom();
5482
+ break;
5483
+ case 'left':
5484
+ moveLeft();
5485
+ break;
5486
+ case 'right':
5487
+ moveRight();
5488
+ break;
5489
+ case 'topleft':
5490
+ moveTop();
5491
+ moveLeft();
5492
+ break;
5493
+ case 'topright':
5494
+ moveTop();
5495
+ moveRight();
5496
+ break;
5497
+ case 'bottomleft':
5498
+ moveBottom();
5499
+ moveLeft();
5500
+ break;
5501
+ case 'bottomright':
5502
+ moveBottom();
5503
+ moveRight();
5504
+ break;
5505
+ }
5506
+ this.setBounds({ height, width, top, left });
5507
+ }), {
5508
+ dispose: () => {
5509
+ for (const iframe of iframes) {
5510
+ iframe.style.pointerEvents = 'auto';
5511
+ }
5512
+ },
5513
+ }, addDisposableWindowListener(window, 'mouseup', () => {
5514
+ move.dispose();
5515
+ this._onDidChangeEnd.fire();
5516
+ }));
5517
+ }));
5518
+ }
5519
+ dispose() {
5520
+ this._element.remove();
5521
+ super.dispose();
5522
+ }
5523
+ }
5524
+ Overlay.MINIMUM_HEIGHT = 20;
5525
+ Overlay.MINIMUM_WIDTH = 20;
5526
+
5527
+ class DockviewFloatingGroupPanel extends CompositeDisposable {
5528
+ constructor(group, overlay) {
5529
+ super();
5530
+ this.group = group;
5531
+ this.overlay = overlay;
5532
+ this.addDisposables(overlay);
5533
+ }
5534
+ position(bounds) {
5535
+ this.overlay.setBounds(bounds);
5536
+ }
5537
+ }
5538
+
5064
5539
  class DockviewComponent extends BaseGrid {
5065
5540
  get orientation() {
5066
5541
  return this.gridview.orientation;
@@ -5101,7 +5576,8 @@ class DockviewComponent extends BaseGrid {
5101
5576
  this.onDidLayoutFromJSON = this._onDidLayoutFromJSON.event;
5102
5577
  this._onDidActivePanelChange = new Emitter();
5103
5578
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
5104
- this.element.classList.add('dv-dockview');
5579
+ this.floatingGroups = [];
5580
+ toggleClass(this.gridview.element, 'dv-dockview', true);
5105
5581
  this.addDisposables(this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
5106
5582
  this.updateWatermark();
5107
5583
  }), exports.DockviewEvent.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => {
@@ -5131,6 +5607,11 @@ class DockviewComponent extends BaseGrid {
5131
5607
  if (data.viewId !== this.id) {
5132
5608
  return false;
5133
5609
  }
5610
+ if (position === 'center') {
5611
+ // center drop target is only allowed if there are no panels in the grid
5612
+ // floating panels are allowed
5613
+ return this.gridview.length === 0;
5614
+ }
5134
5615
  return true;
5135
5616
  }
5136
5617
  if (this.options.showDndOverlay) {
@@ -5143,7 +5624,7 @@ class DockviewComponent extends BaseGrid {
5143
5624
  }
5144
5625
  return false;
5145
5626
  },
5146
- acceptedTargetZones: ['top', 'bottom', 'left', 'right'],
5627
+ acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
5147
5628
  overlayModel: {
5148
5629
  activationSize: { type: 'pixels', value: 10 },
5149
5630
  size: { type: 'pixels', value: 20 },
@@ -5161,6 +5642,75 @@ class DockviewComponent extends BaseGrid {
5161
5642
  this._api = new DockviewApi(this);
5162
5643
  this.updateWatermark();
5163
5644
  }
5645
+ addFloatingGroup(item, coord, options) {
5646
+ var _a, _b;
5647
+ let group;
5648
+ if (item instanceof DockviewPanel) {
5649
+ group = this.createGroup();
5650
+ this.removePanel(item, {
5651
+ removeEmptyGroup: true,
5652
+ skipDispose: true,
5653
+ });
5654
+ group.model.openPanel(item);
5655
+ }
5656
+ else {
5657
+ group = item;
5658
+ const skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' &&
5659
+ options.skipRemoveGroup;
5660
+ if (!skip) {
5661
+ this.doRemoveGroup(item, { skipDispose: true });
5662
+ }
5663
+ }
5664
+ group.model.isFloating = true;
5665
+ const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number' ? Math.max(coord.x, 0) : 100;
5666
+ const overlayTop = typeof (coord === null || coord === void 0 ? void 0 : coord.y) === 'number' ? Math.max(coord.y, 0) : 100;
5667
+ const overlay = new Overlay({
5668
+ container: this.gridview.element,
5669
+ content: group.element,
5670
+ height: (_a = coord === null || coord === void 0 ? void 0 : coord.height) !== null && _a !== void 0 ? _a : 300,
5671
+ width: (_b = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _b !== void 0 ? _b : 300,
5672
+ left: overlayLeft,
5673
+ top: overlayTop,
5674
+ minimumInViewportWidth: 100,
5675
+ minimumInViewportHeight: 100,
5676
+ });
5677
+ const el = group.element.querySelector('.void-container');
5678
+ if (!el) {
5679
+ throw new Error('failed to find drag handle');
5680
+ }
5681
+ overlay.setupDrag(el, {
5682
+ inDragMode: typeof (options === null || options === void 0 ? void 0 : options.inDragMode) === 'boolean'
5683
+ ? options.inDragMode
5684
+ : false,
5685
+ });
5686
+ const floatingGroupPanel = new DockviewFloatingGroupPanel(group, overlay);
5687
+ const disposable = watchElementResize(group.element, (entry) => {
5688
+ const { width, height } = entry.contentRect;
5689
+ group.layout(width, height); // let the group know it's size is changing so it can fire events to the panel
5690
+ });
5691
+ floatingGroupPanel.addDisposables(overlay.onDidChange(() => {
5692
+ // this is either a resize or a move
5693
+ // to inform the panels .layout(...) the group with it's current size
5694
+ // don't care about resize since the above watcher handles that
5695
+ group.layout(group.height, group.width);
5696
+ }), overlay.onDidChangeEnd(() => {
5697
+ this._bufferOnDidLayoutChange.fire();
5698
+ }), group.onDidChange((event) => {
5699
+ overlay.setBounds({
5700
+ height: event === null || event === void 0 ? void 0 : event.height,
5701
+ width: event === null || event === void 0 ? void 0 : event.width,
5702
+ });
5703
+ }), {
5704
+ dispose: () => {
5705
+ disposable.dispose();
5706
+ group.model.isFloating = false;
5707
+ remove(this.floatingGroups, floatingGroupPanel);
5708
+ this.updateWatermark();
5709
+ },
5710
+ });
5711
+ this.floatingGroups.push(floatingGroupPanel);
5712
+ this.updateWatermark();
5713
+ }
5164
5714
  orthogonalize(position) {
5165
5715
  switch (position) {
5166
5716
  case 'top':
@@ -5183,6 +5733,7 @@ class DockviewComponent extends BaseGrid {
5183
5733
  switch (position) {
5184
5734
  case 'top':
5185
5735
  case 'left':
5736
+ case 'center':
5186
5737
  return this.createGroupAtLocation([0]); // insert into first position
5187
5738
  case 'bottom':
5188
5739
  case 'right':
@@ -5200,6 +5751,15 @@ class DockviewComponent extends BaseGrid {
5200
5751
  }
5201
5752
  this.layout(this.gridview.width, this.gridview.height, true);
5202
5753
  }
5754
+ layout(width, height, forceResize) {
5755
+ super.layout(width, height, forceResize);
5756
+ if (this.floatingGroups) {
5757
+ for (const floating of this.floatingGroups) {
5758
+ // ensure floting groups stay within visible boundaries
5759
+ floating.overlay.setBounds();
5760
+ }
5761
+ }
5762
+ }
5203
5763
  focus() {
5204
5764
  var _a;
5205
5765
  (_a = this.activeGroup) === null || _a === void 0 ? void 0 : _a.focus();
@@ -5262,51 +5822,81 @@ class DockviewComponent extends BaseGrid {
5262
5822
  collection[panel.id] = panel.toJSON();
5263
5823
  return collection;
5264
5824
  }, {});
5265
- return {
5825
+ const floats = this.floatingGroups.map((floatingGroup) => {
5826
+ return {
5827
+ data: floatingGroup.group.toJSON(),
5828
+ position: floatingGroup.overlay.toJSON(),
5829
+ };
5830
+ });
5831
+ const result = {
5266
5832
  grid: data,
5267
5833
  panels,
5268
5834
  activeGroup: (_a = this.activeGroup) === null || _a === void 0 ? void 0 : _a.id,
5269
5835
  };
5836
+ if (floats.length > 0) {
5837
+ result.floatingGroups = floats;
5838
+ }
5839
+ return result;
5270
5840
  }
5271
5841
  fromJSON(data) {
5842
+ var _a;
5272
5843
  this.clear();
5273
5844
  const { grid, panels, activeGroup } = data;
5274
5845
  if (grid.root.type !== 'branch' || !Array.isArray(grid.root.data)) {
5275
5846
  throw new Error('root must be of type branch');
5276
5847
  }
5848
+ // take note of the existing dimensions
5849
+ const width = this.width;
5850
+ const height = this.height;
5851
+ const createGroupFromSerializedState = (data) => {
5852
+ const { id, locked, hideHeader, views, activeView } = data;
5853
+ const group = this.createGroup({
5854
+ id,
5855
+ locked: !!locked,
5856
+ hideHeader: !!hideHeader,
5857
+ });
5858
+ this._onDidAddGroup.fire(group);
5859
+ for (const child of views) {
5860
+ const panel = this._deserializer.fromJSON(panels[child], group);
5861
+ const isActive = typeof activeView === 'string' && activeView === panel.id;
5862
+ group.model.openPanel(panel, {
5863
+ skipSetPanelActive: !isActive,
5864
+ skipSetGroupActive: true,
5865
+ });
5866
+ }
5867
+ if (!group.activePanel && group.panels.length > 0) {
5868
+ group.model.openPanel(group.panels[group.panels.length - 1], {
5869
+ skipSetGroupActive: true,
5870
+ });
5871
+ }
5872
+ return group;
5873
+ };
5277
5874
  this.gridview.deserialize(grid, {
5278
5875
  fromJSON: (node) => {
5279
- const { id, locked, hideHeader, views, activeView } = node.data;
5280
- const group = this.createGroup({
5281
- id,
5282
- locked: !!locked,
5283
- hideHeader: !!hideHeader,
5284
- });
5285
- this._onDidAddGroup.fire(group);
5286
- for (const child of views) {
5287
- const panel = this._deserializer.fromJSON(panels[child], group);
5288
- const isActive = typeof activeView === 'string' &&
5289
- activeView === panel.id;
5290
- group.model.openPanel(panel, {
5291
- skipSetPanelActive: !isActive,
5292
- skipSetGroupActive: true,
5293
- });
5294
- }
5295
- if (!group.activePanel && group.panels.length > 0) {
5296
- group.model.openPanel(group.panels[group.panels.length - 1], {
5297
- skipSetGroupActive: true,
5298
- });
5299
- }
5300
- return group;
5876
+ return createGroupFromSerializedState(node.data);
5301
5877
  },
5302
5878
  });
5879
+ this.layout(width, height, true);
5880
+ const serializedFloatingGroups = (_a = data.floatingGroups) !== null && _a !== void 0 ? _a : [];
5881
+ for (const serializedFloatingGroup of serializedFloatingGroups) {
5882
+ const { data, position } = serializedFloatingGroup;
5883
+ const group = createGroupFromSerializedState(data);
5884
+ this.addFloatingGroup(group, {
5885
+ x: position.left,
5886
+ y: position.top,
5887
+ height: position.height,
5888
+ width: position.width,
5889
+ }, { skipRemoveGroup: true, inDragMode: false });
5890
+ }
5891
+ for (const floatingGroup of this.floatingGroups) {
5892
+ floatingGroup.overlay.setBounds();
5893
+ }
5303
5894
  if (typeof activeGroup === 'string') {
5304
5895
  const panel = this.getPanel(activeGroup);
5305
5896
  if (panel) {
5306
5897
  this.doSetGroupActive(panel);
5307
5898
  }
5308
5899
  }
5309
- this.gridview.layout(this.width, this.height);
5310
5900
  this._onDidLayoutFromJSON.fire();
5311
5901
  }
5312
5902
  clear() {
@@ -5315,7 +5905,7 @@ class DockviewComponent extends BaseGrid {
5315
5905
  const hasActivePanel = !!this.activePanel;
5316
5906
  for (const group of groups) {
5317
5907
  // remove the group will automatically remove the panels
5318
- this.removeGroup(group, true);
5908
+ this.removeGroup(group, { skipActive: true });
5319
5909
  }
5320
5910
  if (hasActiveGroup) {
5321
5911
  this.doSetGroupActive(undefined);
@@ -5337,6 +5927,9 @@ class DockviewComponent extends BaseGrid {
5337
5927
  throw new Error(`panel with id ${options.id} already exists`);
5338
5928
  }
5339
5929
  let referenceGroup;
5930
+ if (options.position && options.floating) {
5931
+ throw new Error('you can only provide one of: position, floating as arguments to .addPanel(...)');
5932
+ }
5340
5933
  if (options.position) {
5341
5934
  if (isPanelOptionsWithPanel(options.position)) {
5342
5935
  const referencePanel = typeof options.position.referencePanel === 'string'
@@ -5369,7 +5962,20 @@ class DockviewComponent extends BaseGrid {
5369
5962
  let panel;
5370
5963
  if (referenceGroup) {
5371
5964
  const target = toTarget(((_b = options.position) === null || _b === void 0 ? void 0 : _b.direction) || 'within');
5372
- if (target === 'center') {
5965
+ if (options.floating) {
5966
+ const group = this.createGroup();
5967
+ panel = this.createPanel(options, group);
5968
+ group.model.openPanel(panel);
5969
+ const o = typeof options.floating === 'object' &&
5970
+ options.floating !== null
5971
+ ? options.floating
5972
+ : {};
5973
+ this.addFloatingGroup(group, o, {
5974
+ inDragMode: false,
5975
+ skipRemoveGroup: true,
5976
+ });
5977
+ }
5978
+ else if (referenceGroup.api.isFloating || target === 'center') {
5373
5979
  panel = this.createPanel(options, referenceGroup);
5374
5980
  referenceGroup.model.openPanel(panel);
5375
5981
  }
@@ -5381,6 +5987,19 @@ class DockviewComponent extends BaseGrid {
5381
5987
  group.model.openPanel(panel);
5382
5988
  }
5383
5989
  }
5990
+ else if (options.floating) {
5991
+ const group = this.createGroup();
5992
+ panel = this.createPanel(options, group);
5993
+ group.model.openPanel(panel);
5994
+ const o = typeof options.floating === 'object' &&
5995
+ options.floating !== null
5996
+ ? options.floating
5997
+ : {};
5998
+ this.addFloatingGroup(group, o, {
5999
+ inDragMode: false,
6000
+ skipRemoveGroup: true,
6001
+ });
6002
+ }
5384
6003
  else {
5385
6004
  const group = this.createGroupAtLocation();
5386
6005
  panel = this.createPanel(options, group);
@@ -5397,7 +6016,9 @@ class DockviewComponent extends BaseGrid {
5397
6016
  throw new Error(`cannot remove panel ${panel.id}. it's missing a group.`);
5398
6017
  }
5399
6018
  group.model.removePanel(panel);
5400
- panel.dispose();
6019
+ if (!options.skipDispose) {
6020
+ panel.dispose();
6021
+ }
5401
6022
  if (group.size === 0 && options.removeEmptyGroup) {
5402
6023
  this.removeGroup(group);
5403
6024
  }
@@ -5412,7 +6033,7 @@ class DockviewComponent extends BaseGrid {
5412
6033
  }
5413
6034
  updateWatermark() {
5414
6035
  var _a, _b;
5415
- if (this.groups.length === 0) {
6036
+ if (this.groups.filter((x) => !x.api.isFloating).length === 0) {
5416
6037
  if (!this.watermark) {
5417
6038
  this.watermark = this.createWatermarkComponent();
5418
6039
  this.watermark.init({
@@ -5421,7 +6042,7 @@ class DockviewComponent extends BaseGrid {
5421
6042
  const watermarkContainer = document.createElement('div');
5422
6043
  watermarkContainer.className = 'dv-watermark-container';
5423
6044
  watermarkContainer.appendChild(this.watermark.element);
5424
- this.element.appendChild(watermarkContainer);
6045
+ this.gridview.element.appendChild(watermarkContainer);
5425
6046
  }
5426
6047
  }
5427
6048
  else if (this.watermark) {
@@ -5471,15 +6092,28 @@ class DockviewComponent extends BaseGrid {
5471
6092
  return group;
5472
6093
  }
5473
6094
  }
5474
- removeGroup(group, skipActive = false) {
6095
+ removeGroup(group, options) {
6096
+ var _a;
5475
6097
  const panels = [...group.panels]; // reassign since group panels will mutate
5476
6098
  for (const panel of panels) {
5477
6099
  this.removePanel(panel, {
5478
6100
  removeEmptyGroup: false,
5479
- skipDispose: false,
6101
+ skipDispose: (_a = options === null || options === void 0 ? void 0 : options.skipDispose) !== null && _a !== void 0 ? _a : false,
5480
6102
  });
5481
6103
  }
5482
- super.doRemoveGroup(group, { skipActive });
6104
+ this.doRemoveGroup(group, options);
6105
+ }
6106
+ doRemoveGroup(group, options) {
6107
+ const floatingGroup = this.floatingGroups.find((_) => _.group === group);
6108
+ if (floatingGroup) {
6109
+ if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
6110
+ floatingGroup.group.dispose();
6111
+ this._groups.delete(group.id);
6112
+ }
6113
+ floatingGroup.dispose();
6114
+ return floatingGroup.group;
6115
+ }
6116
+ return super.doRemoveGroup(group, options);
5483
6117
  }
5484
6118
  moveGroupOrPanel(destinationGroup, sourceGroupId, sourceItemId, destinationTarget, destinationIndex) {
5485
6119
  var _a;
@@ -5510,25 +6144,26 @@ class DockviewComponent extends BaseGrid {
5510
6144
  const targetLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
5511
6145
  if (sourceGroup && sourceGroup.size < 2) {
5512
6146
  const [targetParentLocation, to] = tail(targetLocation);
5513
- const sourceLocation = getGridLocation(sourceGroup.element);
5514
- const [sourceParentLocation, from] = tail(sourceLocation);
5515
- if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
5516
- // special case when 'swapping' two views within same grid location
5517
- // if a group has one tab - we are essentially moving the 'group'
5518
- // which is equivalent to swapping two views in this case
5519
- this.gridview.moveView(sourceParentLocation, from, to);
5520
- }
5521
- else {
5522
- // source group will become empty so delete the group
5523
- const targetGroup = this.doRemoveGroup(sourceGroup, {
5524
- skipActive: true,
5525
- skipDispose: true,
5526
- });
5527
- // after deleting the group we need to re-evaulate the ref location
5528
- const updatedReferenceLocation = getGridLocation(destinationGroup.element);
5529
- const location = getRelativeLocation(this.gridview.orientation, updatedReferenceLocation, destinationTarget);
5530
- this.doAddGroup(targetGroup, location);
6147
+ const isFloating = this.floatingGroups.find((x) => x.group === sourceGroup);
6148
+ if (!isFloating) {
6149
+ const sourceLocation = getGridLocation(sourceGroup.element);
6150
+ const [sourceParentLocation, from] = tail(sourceLocation);
6151
+ if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
6152
+ // special case when 'swapping' two views within same grid location
6153
+ // if a group has one tab - we are essentially moving the 'group'
6154
+ // which is equivalent to swapping two views in this case
6155
+ this.gridview.moveView(sourceParentLocation, from, to);
6156
+ }
5531
6157
  }
6158
+ // source group will become empty so delete the group
6159
+ const targetGroup = this.doRemoveGroup(sourceGroup, {
6160
+ skipActive: true,
6161
+ skipDispose: true,
6162
+ });
6163
+ // after deleting the group we need to re-evaulate the ref location
6164
+ const updatedReferenceLocation = getGridLocation(destinationGroup.element);
6165
+ const location = getRelativeLocation(this.gridview.orientation, updatedReferenceLocation, destinationTarget);
6166
+ this.doAddGroup(targetGroup, location);
5532
6167
  }
5533
6168
  else {
5534
6169
  const groupItem = (sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.removePanel(sourceItemId)) ||
@@ -5557,7 +6192,13 @@ class DockviewComponent extends BaseGrid {
5557
6192
  }
5558
6193
  }
5559
6194
  else {
5560
- this.gridview.removeView(getGridLocation(sourceGroup.element));
6195
+ const floatingGroup = this.floatingGroups.find((x) => x.group === sourceGroup);
6196
+ if (floatingGroup) {
6197
+ floatingGroup.dispose();
6198
+ }
6199
+ else {
6200
+ this.gridview.removeView(getGridLocation(sourceGroup.element));
6201
+ }
5561
6202
  const referenceLocation = getGridLocation(referenceGroup.element);
5562
6203
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, target);
5563
6204
  this.gridview.addView(sourceGroup, exports.Sizing.Distribute, dropLocation);
@@ -5712,6 +6353,9 @@ class GridviewComponent extends BaseGrid {
5712
6353
  this.clear();
5713
6354
  const { grid, activePanel } = serializedGridview;
5714
6355
  const queue = [];
6356
+ // take note of the existing dimensions
6357
+ const width = this.width;
6358
+ const height = this.height;
5715
6359
  this.gridview.deserialize(grid, {
5716
6360
  fromJSON: (node) => {
5717
6361
  const { data } = node;
@@ -5737,7 +6381,7 @@ class GridviewComponent extends BaseGrid {
5737
6381
  return view;
5738
6382
  },
5739
6383
  });
5740
- this.layout(this.width, this.height, true);
6384
+ this.layout(width, height, true);
5741
6385
  queue.forEach((f) => f());
5742
6386
  if (typeof activePanel === 'string') {
5743
6387
  const panel = this.getPanel(activePanel);
@@ -6051,6 +6695,9 @@ class SplitviewComponent extends Resizable {
6051
6695
  this.clear();
6052
6696
  const { views, orientation, size, activeView } = serializedSplitview;
6053
6697
  const queue = [];
6698
+ // take note of the existing dimensions
6699
+ const width = this.width;
6700
+ const height = this.height;
6054
6701
  this.splitview = new Splitview(this.element, {
6055
6702
  orientation,
6056
6703
  proportionalLayout: this.options.proportionalLayout,
@@ -6087,7 +6734,7 @@ class SplitviewComponent extends Resizable {
6087
6734
  }),
6088
6735
  },
6089
6736
  });
6090
- this.layout(this.width, this.height);
6737
+ this.layout(width, height);
6091
6738
  queue.forEach((f) => f());
6092
6739
  if (typeof activeView === 'string') {
6093
6740
  const panel = this.getPanel(activeView);
@@ -6354,6 +7001,9 @@ class PaneviewComponent extends Resizable {
6354
7001
  this.clear();
6355
7002
  const { views, size } = serializedPaneview;
6356
7003
  const queue = [];
7004
+ // take note of the existing dimensions
7005
+ const width = this.width;
7006
+ const height = this.height;
6357
7007
  this.paneview = new Paneview(this.element, {
6358
7008
  orientation: exports.Orientation.VERTICAL,
6359
7009
  descriptor: {
@@ -6409,7 +7059,7 @@ class PaneviewComponent extends Resizable {
6409
7059
  }),
6410
7060
  },
6411
7061
  });
6412
- this.layout(this.width, this.height);
7062
+ this.layout(width, height);
6413
7063
  queue.forEach((f) => f());
6414
7064
  this._onDidLayoutfromJSON.fire();
6415
7065
  }
@@ -6792,7 +7442,7 @@ class ReactWatermarkPart {
6792
7442
  }
6793
7443
  }
6794
7444
 
6795
- class ReactGroupControlsRendererPart {
7445
+ class ReactHeaderActionsRendererPart {
6796
7446
  get element() {
6797
7447
  return this._element;
6798
7448
  }
@@ -6829,6 +7479,7 @@ class ReactGroupControlsRendererPart {
6829
7479
  panels: this._group.model.panels,
6830
7480
  activePanel: this._group.model.activePanel,
6831
7481
  isGroupActive: this._group.api.isActive,
7482
+ group: this._group,
6832
7483
  });
6833
7484
  }
6834
7485
  update(event) {
@@ -6862,7 +7513,7 @@ class ReactGroupControlsRendererPart {
6862
7513
  function createGroupControlElement(component, store) {
6863
7514
  return component
6864
7515
  ? (groupPanel) => {
6865
- return new ReactGroupControlsRendererPart(component, store, groupPanel);
7516
+ return new ReactHeaderActionsRendererPart(component, store, groupPanel);
6866
7517
  }
6867
7518
  : undefined;
6868
7519
  }
@@ -6919,8 +7570,10 @@ const DockviewReact = React__namespace.forwardRef((props, ref) => {
6919
7570
  ? { separatorBorder: 'transparent' }
6920
7571
  : undefined,
6921
7572
  showDndOverlay: props.showDndOverlay,
6922
- createGroupControlElement: createGroupControlElement(props.groupControlComponent, { addPortal }),
7573
+ createLeftHeaderActionsElement: createGroupControlElement(props.leftHeaderActionsComponent, { addPortal }),
7574
+ createRightHeaderActionsElement: createGroupControlElement(props.rightHeaderActionsComponent, { addPortal }),
6923
7575
  singleTabMode: props.singleTabMode,
7576
+ disableFloatingGroups: props.disableFloatingGroups,
6924
7577
  });
6925
7578
  const { clientWidth, clientHeight } = domRef.current;
6926
7579
  dockview.layout(clientWidth, clientHeight);
@@ -6979,6 +7632,14 @@ const DockviewReact = React__namespace.forwardRef((props, ref) => {
6979
7632
  frameworkTabComponents: props.tabComponents,
6980
7633
  });
6981
7634
  }, [props.tabComponents]);
7635
+ React__namespace.useEffect(() => {
7636
+ if (!dockviewRef.current) {
7637
+ return;
7638
+ }
7639
+ dockviewRef.current.updateOptions({
7640
+ disableFloatingGroups: props.disableFloatingGroups,
7641
+ });
7642
+ }, [props.disableFloatingGroups]);
6982
7643
  React__namespace.useEffect(() => {
6983
7644
  if (!dockviewRef.current) {
6984
7645
  return;
@@ -7000,9 +7661,17 @@ const DockviewReact = React__namespace.forwardRef((props, ref) => {
7000
7661
  return;
7001
7662
  }
7002
7663
  dockviewRef.current.updateOptions({
7003
- createGroupControlElement: createGroupControlElement(props.groupControlComponent, { addPortal }),
7664
+ createRightHeaderActionsElement: createGroupControlElement(props.rightHeaderActionsComponent, { addPortal }),
7665
+ });
7666
+ }, [props.rightHeaderActionsComponent]);
7667
+ React__namespace.useEffect(() => {
7668
+ if (!dockviewRef.current) {
7669
+ return;
7670
+ }
7671
+ dockviewRef.current.updateOptions({
7672
+ createLeftHeaderActionsElement: createGroupControlElement(props.leftHeaderActionsComponent, { addPortal }),
7004
7673
  });
7005
- }, [props.groupControlComponent]);
7674
+ }, [props.leftHeaderActionsComponent]);
7006
7675
  return (React__namespace.createElement("div", { className: props.className, style: { height: '100%', width: '100%' }, ref: domRef }, portals));
7007
7676
  });
7008
7677
  DockviewReact.displayName = 'DockviewComponent';
@@ -7021,6 +7690,8 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
7021
7690
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
7022
7691
  PERFORMANCE OF THIS SOFTWARE.
7023
7692
  ***************************************************************************** */
7693
+ /* global Reflect, Promise, SuppressedError, Symbol */
7694
+
7024
7695
 
7025
7696
  function __rest(s, e) {
7026
7697
  var t = {};
@@ -7032,7 +7703,12 @@ function __rest(s, e) {
7032
7703
  t[p[i]] = s[p[i]];
7033
7704
  }
7034
7705
  return t;
7035
- }
7706
+ }
7707
+
7708
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
7709
+ var e = new Error(message);
7710
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
7711
+ };
7036
7712
 
7037
7713
  const CloseButton = () => (React__namespace.createElement("svg", { height: "11", width: "11", viewBox: "0 0 28 28", "aria-hidden": 'false', focusable: false, className: "dockview-svg" },
7038
7714
  React__namespace.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" })));
@@ -7360,4 +8036,4 @@ exports.orthogonal = orthogonal;
7360
8036
  exports.positionToDirection = positionToDirection;
7361
8037
  exports.toTarget = toTarget;
7362
8038
  exports.usePortalsLifecycle = usePortalsLifecycle;
7363
- exports.watchElementResize = watchElementResize;
8039
+ //# sourceMappingURL=dockview.cjs.js.map