dockview 1.8.5 → 1.9.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 (46) hide show
  1. package/README.md +15 -10
  2. package/dist/cjs/dockview/defaultTab.js.map +1 -1
  3. package/dist/cjs/dockview/dockview.d.ts +3 -1
  4. package/dist/cjs/dockview/dockview.d.ts.map +1 -1
  5. package/dist/cjs/dockview/dockview.js +2 -0
  6. package/dist/cjs/dockview/dockview.js.map +1 -1
  7. package/dist/cjs/dockview/reactWatermarkPart.js.map +1 -1
  8. package/dist/cjs/gridview/gridview.js.map +1 -1
  9. package/dist/cjs/gridview/view.js.map +1 -1
  10. package/dist/cjs/paneview/paneview.js.map +1 -1
  11. package/dist/cjs/react.js.map +1 -1
  12. package/dist/cjs/splitview/splitview.js.map +1 -1
  13. package/dist/cjs/splitview/view.js.map +1 -1
  14. package/dist/dockview.amd.js +897 -169
  15. package/dist/dockview.amd.js.map +1 -1
  16. package/dist/dockview.amd.min.js +2 -2
  17. package/dist/dockview.amd.min.js.map +1 -1
  18. package/dist/dockview.amd.min.noStyle.js +2 -2
  19. package/dist/dockview.amd.min.noStyle.js.map +1 -1
  20. package/dist/dockview.amd.noStyle.js +897 -169
  21. package/dist/dockview.amd.noStyle.js.map +1 -1
  22. package/dist/dockview.cjs.js +897 -169
  23. package/dist/dockview.cjs.js.map +1 -1
  24. package/dist/dockview.esm.js +897 -169
  25. package/dist/dockview.esm.js.map +1 -1
  26. package/dist/dockview.esm.min.js +2 -2
  27. package/dist/dockview.esm.min.js.map +1 -1
  28. package/dist/dockview.js +897 -169
  29. package/dist/dockview.js.map +1 -1
  30. package/dist/dockview.min.js +2 -2
  31. package/dist/dockview.min.js.map +1 -1
  32. package/dist/dockview.min.noStyle.js +2 -2
  33. package/dist/dockview.min.noStyle.js.map +1 -1
  34. package/dist/dockview.noStyle.js +897 -169
  35. package/dist/dockview.noStyle.js.map +1 -1
  36. package/dist/esm/dockview/defaultTab.js.map +1 -1
  37. package/dist/esm/dockview/dockview.d.ts +3 -1
  38. package/dist/esm/dockview/dockview.d.ts.map +1 -1
  39. package/dist/esm/dockview/dockview.js +2 -0
  40. package/dist/esm/dockview/dockview.js.map +1 -1
  41. package/dist/esm/dockview/reactWatermarkPart.js.map +1 -1
  42. package/dist/esm/gridview/gridview.js.map +1 -1
  43. package/dist/esm/paneview/paneview.js.map +1 -1
  44. package/dist/esm/react.js.map +1 -1
  45. package/dist/esm/splitview/splitview.js.map +1 -1
  46. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * dockview
3
- * @version 1.8.5
3
+ * @version 1.9.0
4
4
  * @link https://github.com/mathuo/dockview
5
5
  * @license MIT
6
6
  */
@@ -285,6 +285,14 @@ var Disposable;
285
285
  // noop
286
286
  },
287
287
  };
288
+ function from(func) {
289
+ return {
290
+ dispose: () => {
291
+ func();
292
+ },
293
+ };
294
+ }
295
+ Disposable.from = from;
288
296
  })(Disposable || (Disposable = {}));
289
297
  class CompositeDisposable {
290
298
  get isDisposed() {
@@ -469,6 +477,61 @@ function quasiPreventDefault(event) {
469
477
  function quasiDefaultPrevented(event) {
470
478
  return event[QUASI_PREVENT_DEFAULT_KEY];
471
479
  }
480
+ function addStyles(document, styleSheetList) {
481
+ const styleSheets = Array.from(styleSheetList);
482
+ for (const styleSheet of styleSheets) {
483
+ if (styleSheet.href) {
484
+ const link = document.createElement('link');
485
+ link.href = styleSheet.href;
486
+ link.type = styleSheet.type;
487
+ link.rel = 'stylesheet';
488
+ document.head.appendChild(link);
489
+ }
490
+ let cssTexts = [];
491
+ try {
492
+ if (styleSheet.cssRules) {
493
+ cssTexts = Array.from(styleSheet.cssRules).map((rule) => rule.cssText);
494
+ }
495
+ }
496
+ catch (err) {
497
+ // security errors (lack of permissions), ignore
498
+ }
499
+ for (const rule of cssTexts) {
500
+ const style = document.createElement('style');
501
+ style.appendChild(document.createTextNode(rule));
502
+ document.head.appendChild(style);
503
+ }
504
+ }
505
+ }
506
+ function getDomNodePagePosition(domNode) {
507
+ const { left, top, width, height } = domNode.getBoundingClientRect();
508
+ return {
509
+ left: left + window.scrollX,
510
+ top: top + window.scrollY,
511
+ width: width,
512
+ height: height,
513
+ };
514
+ }
515
+ /**
516
+ * Check whether an element is in the DOM (including the Shadow DOM)
517
+ * @see https://terodox.tech/how-to-tell-if-an-element-is-in-the-dom-including-the-shadow-dom/
518
+ */
519
+ function isInDocument(element) {
520
+ let currentElement = element;
521
+ while (currentElement === null || currentElement === void 0 ? void 0 : currentElement.parentNode) {
522
+ if (currentElement.parentNode === document) {
523
+ return true;
524
+ }
525
+ else if (currentElement.parentNode instanceof DocumentFragment) {
526
+ // handle shadow DOMs
527
+ currentElement = currentElement.parentNode.host;
528
+ }
529
+ else {
530
+ currentElement = currentElement.parentNode;
531
+ }
532
+ }
533
+ return false;
534
+ }
472
535
 
473
536
  function tail(arr) {
474
537
  if (arr.length === 0) {
@@ -666,6 +729,9 @@ exports.Sizing = void 0;
666
729
  Sizing.Invisible = Invisible;
667
730
  })(exports.Sizing || (exports.Sizing = {}));
668
731
  class Splitview {
732
+ get contentSize() {
733
+ return this._contentSize;
734
+ }
669
735
  get size() {
670
736
  return this._size;
671
737
  }
@@ -731,7 +797,7 @@ class Splitview {
731
797
  this.sashes = [];
732
798
  this._size = 0;
733
799
  this._orthogonalSize = 0;
734
- this.contentSize = 0;
800
+ this._contentSize = 0;
735
801
  this._proportions = undefined;
736
802
  this._startSnappingEnabled = true;
737
803
  this._endSnappingEnabled = true;
@@ -850,7 +916,7 @@ class Splitview {
850
916
  );
851
917
  });
852
918
  // Initialize content size and proportions for first layout
853
- this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
919
+ this._contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
854
920
  this.saveProportions();
855
921
  }
856
922
  }
@@ -1124,7 +1190,7 @@ class Splitview {
1124
1190
  this.addView(view, sizing, to);
1125
1191
  }
1126
1192
  layout(size, orthogonalSize) {
1127
- const previousSize = Math.max(this.size, this.contentSize);
1193
+ const previousSize = Math.max(this.size, this._contentSize);
1128
1194
  this.size = size;
1129
1195
  this.orthogonalSize = orthogonalSize;
1130
1196
  if (!this.proportions) {
@@ -1134,9 +1200,23 @@ class Splitview {
1134
1200
  this.resize(this.viewItems.length - 1, size - previousSize, undefined, lowPriorityIndexes, highPriorityIndexes);
1135
1201
  }
1136
1202
  else {
1203
+ let total = 0;
1204
+ for (let i = 0; i < this.viewItems.length; i++) {
1205
+ const item = this.viewItems[i];
1206
+ const proportion = this.proportions[i];
1207
+ if (typeof proportion === 'number') {
1208
+ total += proportion;
1209
+ }
1210
+ else {
1211
+ size -= item.size;
1212
+ }
1213
+ }
1137
1214
  for (let i = 0; i < this.viewItems.length; i++) {
1138
1215
  const item = this.viewItems[i];
1139
- item.size = clamp(Math.round(this.proportions[i] * size), item.minimumSize, item.maximumSize);
1216
+ const proportion = this.proportions[i];
1217
+ if (typeof proportion === 'number' && total > 0) {
1218
+ item.size = clamp(Math.round((proportion * size) / total), item.minimumSize, item.maximumSize);
1219
+ }
1140
1220
  }
1141
1221
  }
1142
1222
  this.distributeEmptySpace();
@@ -1173,12 +1253,12 @@ class Splitview {
1173
1253
  }
1174
1254
  }
1175
1255
  saveProportions() {
1176
- if (this.proportionalLayout && this.contentSize > 0) {
1177
- this._proportions = this.viewItems.map((i) => i.size / this.contentSize);
1256
+ if (this.proportionalLayout && this._contentSize > 0) {
1257
+ this._proportions = this.viewItems.map((i) => i.visible ? i.size / this._contentSize : undefined);
1178
1258
  }
1179
1259
  }
1180
1260
  layoutViews() {
1181
- this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
1261
+ this._contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
1182
1262
  let sum = 0;
1183
1263
  const x = [];
1184
1264
  this.updateSashEnablement();
@@ -1272,7 +1352,7 @@ class Splitview {
1272
1352
  }
1273
1353
  else if (snappedAfter &&
1274
1354
  collapsesDown[index] &&
1275
- (position < this.contentSize || this.endSnappingEnabled)) {
1355
+ (position < this._contentSize || this.endSnappingEnabled)) {
1276
1356
  this.updateSash(sash, exports.SashState.MAXIMUM);
1277
1357
  }
1278
1358
  else {
@@ -1561,7 +1641,6 @@ class LeafNode {
1561
1641
  setVisible(visible) {
1562
1642
  if (this.view.setVisible) {
1563
1643
  this.view.setVisible(visible);
1564
- this._onDidChange.fire({});
1565
1644
  }
1566
1645
  }
1567
1646
  layout(size, orthogonalSize) {
@@ -1593,10 +1672,14 @@ class BranchNode extends CompositeDisposable {
1593
1672
  get minimumSize() {
1594
1673
  return this.children.length === 0
1595
1674
  ? 0
1596
- : Math.max(...this.children.map((c) => c.minimumOrthogonalSize));
1675
+ : Math.max(...this.children.map((c, index) => this.splitview.isViewVisible(index)
1676
+ ? c.minimumOrthogonalSize
1677
+ : 0));
1597
1678
  }
1598
1679
  get maximumSize() {
1599
- return Math.min(...this.children.map((c) => c.maximumOrthogonalSize));
1680
+ return Math.min(...this.children.map((c, index) => this.splitview.isViewVisible(index)
1681
+ ? c.maximumOrthogonalSize
1682
+ : Number.POSITIVE_INFINITY));
1600
1683
  }
1601
1684
  get minimumOrthogonalSize() {
1602
1685
  return this.splitview.minimumSize;
@@ -1654,6 +1737,8 @@ class BranchNode extends CompositeDisposable {
1654
1737
  this.children = [];
1655
1738
  this._onDidChange = new Emitter();
1656
1739
  this.onDidChange = this._onDidChange.event;
1740
+ this._onDidVisibilityChange = new Emitter();
1741
+ this.onDidVisibilityChange = this._onDidVisibilityChange.event;
1657
1742
  this._orthogonalSize = orthogonalSize;
1658
1743
  this._size = size;
1659
1744
  this.element = document.createElement('div');
@@ -1688,7 +1773,7 @@ class BranchNode extends CompositeDisposable {
1688
1773
  styles,
1689
1774
  });
1690
1775
  }
1691
- this.addDisposables(this._onDidChange, this.splitview.onDidSashEnd(() => {
1776
+ this.addDisposables(this._onDidChange, this._onDidVisibilityChange, this.splitview.onDidSashEnd(() => {
1692
1777
  this._onDidChange.fire({});
1693
1778
  }));
1694
1779
  this.setupChildrenEvents();
@@ -1711,7 +1796,15 @@ class BranchNode extends CompositeDisposable {
1711
1796
  if (this.splitview.isViewVisible(index) === visible) {
1712
1797
  return;
1713
1798
  }
1799
+ const wereAllChildrenHidden = this.splitview.contentSize === 0;
1714
1800
  this.splitview.setViewVisible(index, visible);
1801
+ const areAllChildrenHidden = this.splitview.contentSize === 0;
1802
+ // If all children are hidden then the parent should hide the entire splitview
1803
+ // If the entire splitview is hidden then the parent should show the splitview when a child is shown
1804
+ if ((visible && wereAllChildrenHidden) ||
1805
+ (!visible && areAllChildrenHidden)) {
1806
+ this._onDidVisibilityChange.fire(visible);
1807
+ }
1715
1808
  }
1716
1809
  moveChild(from, to) {
1717
1810
  if (from === to) {
@@ -1775,13 +1868,20 @@ class BranchNode extends CompositeDisposable {
1775
1868
  }
1776
1869
  setupChildrenEvents() {
1777
1870
  this._childrenDisposable.dispose();
1778
- this._childrenDisposable = exports.DockviewEvent.any(...this.children.map((c) => c.onDidChange))((e) => {
1871
+ this._childrenDisposable = new CompositeDisposable(exports.DockviewEvent.any(...this.children.map((c) => c.onDidChange))((e) => {
1779
1872
  /**
1780
1873
  * indicate a change has occured to allows any re-rendering but don't bubble
1781
1874
  * event because that was specific to this branch
1782
1875
  */
1783
1876
  this._onDidChange.fire({ size: e.orthogonalSize });
1784
- });
1877
+ }), ...this.children.map((c, i) => {
1878
+ if (c instanceof BranchNode) {
1879
+ return c.onDidVisibilityChange((visible) => {
1880
+ this.setChildVisible(i, visible);
1881
+ });
1882
+ }
1883
+ return Disposable.NONE;
1884
+ }));
1785
1885
  }
1786
1886
  dispose() {
1787
1887
  this._childrenDisposable.dispose();
@@ -1942,7 +2042,69 @@ class Gridview {
1942
2042
  get maximumHeight() {
1943
2043
  return this.root.maximumHeight;
1944
2044
  }
2045
+ maximizedView() {
2046
+ var _a;
2047
+ return (_a = this._maximizedNode) === null || _a === void 0 ? void 0 : _a.view;
2048
+ }
2049
+ hasMaximizedView() {
2050
+ return this._maximizedNode !== undefined;
2051
+ }
2052
+ maximizeView(view) {
2053
+ const location = getGridLocation(view.element);
2054
+ const [_, node] = this.getNode(location);
2055
+ if (!(node instanceof LeafNode)) {
2056
+ return;
2057
+ }
2058
+ if (this._maximizedNode === node) {
2059
+ return;
2060
+ }
2061
+ if (this.hasMaximizedView()) {
2062
+ this.exitMaximizedView();
2063
+ }
2064
+ function hideAllViewsBut(parent, exclude) {
2065
+ for (let i = 0; i < parent.children.length; i++) {
2066
+ const child = parent.children[i];
2067
+ if (child instanceof LeafNode) {
2068
+ if (child !== exclude) {
2069
+ parent.setChildVisible(i, false);
2070
+ }
2071
+ }
2072
+ else {
2073
+ hideAllViewsBut(child, exclude);
2074
+ }
2075
+ }
2076
+ }
2077
+ hideAllViewsBut(this.root, node);
2078
+ this._maximizedNode = node;
2079
+ this._onDidMaxmizedNodeChange.fire();
2080
+ }
2081
+ exitMaximizedView() {
2082
+ if (!this._maximizedNode) {
2083
+ return;
2084
+ }
2085
+ function showViewsInReverseOrder(parent) {
2086
+ for (let index = parent.children.length - 1; index >= 0; index--) {
2087
+ const child = parent.children[index];
2088
+ if (child instanceof LeafNode) {
2089
+ parent.setChildVisible(index, true);
2090
+ }
2091
+ else {
2092
+ showViewsInReverseOrder(child);
2093
+ }
2094
+ }
2095
+ }
2096
+ showViewsInReverseOrder(this.root);
2097
+ this._maximizedNode = undefined;
2098
+ this._onDidMaxmizedNodeChange.fire();
2099
+ }
1945
2100
  serialize() {
2101
+ if (this.hasMaximizedView()) {
2102
+ /**
2103
+ * do not persist maximized view state but we must first exit any maximized views
2104
+ * before serialization to ensure the correct dimensions are persisted
2105
+ */
2106
+ this.exitMaximizedView();
2107
+ }
1946
2108
  const root = serializeBranchNode(this.getView(), this.orientation);
1947
2109
  return {
1948
2110
  root,
@@ -1954,7 +2116,9 @@ class Gridview {
1954
2116
  dispose() {
1955
2117
  this.disposable.dispose();
1956
2118
  this._onDidChange.dispose();
2119
+ this._onDidMaxmizedNodeChange.dispose();
1957
2120
  this.root.dispose();
2121
+ this._maximizedNode = undefined;
1958
2122
  this.element.remove();
1959
2123
  }
1960
2124
  clear() {
@@ -1995,6 +2159,7 @@ class Gridview {
1995
2159
  const oldRoot = this._root;
1996
2160
  if (oldRoot) {
1997
2161
  oldRoot.dispose();
2162
+ this._maximizedNode = undefined;
1998
2163
  this.element.removeChild(oldRoot.element);
1999
2164
  }
2000
2165
  this._root = root;
@@ -2081,9 +2246,12 @@ class Gridview {
2081
2246
  constructor(proportionalLayout, styles, orientation) {
2082
2247
  this.proportionalLayout = proportionalLayout;
2083
2248
  this.styles = styles;
2249
+ this._maximizedNode = undefined;
2084
2250
  this.disposable = new MutableDisposable();
2085
2251
  this._onDidChange = new Emitter();
2086
2252
  this.onDidChange = this._onDidChange.event;
2253
+ this._onDidMaxmizedNodeChange = new Emitter();
2254
+ this.onDidMaxmizedNodeChange = this._onDidMaxmizedNodeChange.event;
2087
2255
  this.element = document.createElement('div');
2088
2256
  this.element.className = 'grid-view';
2089
2257
  this.root = new BranchNode(orientation, proportionalLayout, styles, 0, 0);
@@ -2097,6 +2265,9 @@ class Gridview {
2097
2265
  return parent.isChildVisible(index);
2098
2266
  }
2099
2267
  setViewVisible(location, visible) {
2268
+ if (this.hasMaximizedView()) {
2269
+ this.exitMaximizedView();
2270
+ }
2100
2271
  const [rest, index] = tail(location);
2101
2272
  const [, parent] = this.getNode(rest);
2102
2273
  if (!(parent instanceof BranchNode)) {
@@ -2105,6 +2276,9 @@ class Gridview {
2105
2276
  parent.setChildVisible(index, visible);
2106
2277
  }
2107
2278
  moveView(parentLocation, from, to) {
2279
+ if (this.hasMaximizedView()) {
2280
+ this.exitMaximizedView();
2281
+ }
2108
2282
  const [, parent] = this.getNode(parentLocation);
2109
2283
  if (!(parent instanceof BranchNode)) {
2110
2284
  throw new Error('Invalid location');
@@ -2112,6 +2286,9 @@ class Gridview {
2112
2286
  parent.moveChild(from, to);
2113
2287
  }
2114
2288
  addView(view, size, location) {
2289
+ if (this.hasMaximizedView()) {
2290
+ this.exitMaximizedView();
2291
+ }
2115
2292
  const [rest, index] = tail(location);
2116
2293
  const [pathToParent, parent] = this.getNode(rest);
2117
2294
  if (parent instanceof BranchNode) {
@@ -2144,6 +2321,9 @@ class Gridview {
2144
2321
  return this.removeView(location, sizing);
2145
2322
  }
2146
2323
  removeView(location, sizing) {
2324
+ if (this.hasMaximizedView()) {
2325
+ this.exitMaximizedView();
2326
+ }
2147
2327
  const [rest, index] = tail(location);
2148
2328
  const [pathToParent, parent] = this.getNode(rest);
2149
2329
  if (!(parent instanceof BranchNode)) {
@@ -2881,6 +3061,24 @@ class DockviewApi {
2881
3061
  moveToPrevious(options) {
2882
3062
  this.component.moveToPrevious(options);
2883
3063
  }
3064
+ maximizeGroup(panel) {
3065
+ this.component.maximizeGroup(panel.group);
3066
+ }
3067
+ hasMaximizedGroup() {
3068
+ return this.component.hasMaximizedGroup();
3069
+ }
3070
+ exitMaxmizedGroup() {
3071
+ this.component.exitMaximizedGroup();
3072
+ }
3073
+ get onDidMaxmizedGroupChange() {
3074
+ return this.component.onDidMaxmizedGroupChange;
3075
+ }
3076
+ /**
3077
+ * Add a popout group in a new Window
3078
+ */
3079
+ addPopoutGroup(item, options) {
3080
+ this.component.addPopoutGroup(item, options);
3081
+ }
2884
3082
  }
2885
3083
 
2886
3084
  class DragAndDropObserver extends CompositeDisposable {
@@ -2891,29 +3089,44 @@ class DragAndDropObserver extends CompositeDisposable {
2891
3089
  this.target = null;
2892
3090
  this.registerListeners();
2893
3091
  }
3092
+ onDragEnter(e) {
3093
+ this.target = e.target;
3094
+ this.callbacks.onDragEnter(e);
3095
+ }
3096
+ onDragOver(e) {
3097
+ e.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome)
3098
+ if (this.callbacks.onDragOver) {
3099
+ this.callbacks.onDragOver(e);
3100
+ }
3101
+ }
3102
+ onDragLeave(e) {
3103
+ if (this.target === e.target) {
3104
+ this.target = null;
3105
+ this.callbacks.onDragLeave(e);
3106
+ }
3107
+ }
3108
+ onDragEnd(e) {
3109
+ this.target = null;
3110
+ this.callbacks.onDragEnd(e);
3111
+ }
3112
+ onDrop(e) {
3113
+ this.callbacks.onDrop(e);
3114
+ }
2894
3115
  registerListeners() {
2895
3116
  this.addDisposables(addDisposableListener(this.element, 'dragenter', (e) => {
2896
- this.target = e.target;
2897
- this.callbacks.onDragEnter(e);
3117
+ this.onDragEnter(e);
2898
3118
  }, true));
2899
3119
  this.addDisposables(addDisposableListener(this.element, 'dragover', (e) => {
2900
- e.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome)
2901
- if (this.callbacks.onDragOver) {
2902
- this.callbacks.onDragOver(e);
2903
- }
3120
+ this.onDragOver(e);
2904
3121
  }, true));
2905
3122
  this.addDisposables(addDisposableListener(this.element, 'dragleave', (e) => {
2906
- if (this.target === e.target) {
2907
- this.target = null;
2908
- this.callbacks.onDragLeave(e);
2909
- }
3123
+ this.onDragLeave(e);
2910
3124
  }));
2911
3125
  this.addDisposables(addDisposableListener(this.element, 'dragend', (e) => {
2912
- this.target = null;
2913
- this.callbacks.onDragEnd(e);
3126
+ this.onDragEnd(e);
2914
3127
  }));
2915
3128
  this.addDisposables(addDisposableListener(this.element, 'drop', (e) => {
2916
- this.callbacks.onDrop(e);
3129
+ this.onDrop(e);
2917
3130
  }));
2918
3131
  }
2919
3132
  }
@@ -2965,7 +3178,7 @@ class Droptarget extends CompositeDisposable {
2965
3178
  this.onDrop = this._onDrop.event;
2966
3179
  // use a set to take advantage of #<set>.has
2967
3180
  this._acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
2968
- this.addDisposables(this._onDrop, new DragAndDropObserver(this.element, {
3181
+ this.dnd = new DragAndDropObserver(this.element, {
2969
3182
  onDragEnter: () => undefined,
2970
3183
  onDragOver: (e) => {
2971
3184
  if (this._acceptedTargetZonesSet.size === 0) {
@@ -3032,7 +3245,8 @@ class Droptarget extends CompositeDisposable {
3032
3245
  this._onDrop.fire({ position: state, nativeEvent: e });
3033
3246
  }
3034
3247
  },
3035
- }));
3248
+ });
3249
+ this.addDisposables(this._onDrop, this.dnd);
3036
3250
  }
3037
3251
  setTargetZones(acceptedTargetZones) {
3038
3252
  this._acceptedTargetZonesSet = new Set(acceptedTargetZones);
@@ -3188,12 +3402,22 @@ function calculateQuadrantAsPixels(overlayType, x, y, width, height, threshold)
3188
3402
  return 'center';
3189
3403
  }
3190
3404
 
3405
+ exports.DockviewDropTargets = void 0;
3406
+ (function (DockviewDropTargets) {
3407
+ DockviewDropTargets[DockviewDropTargets["Tab"] = 0] = "Tab";
3408
+ DockviewDropTargets[DockviewDropTargets["Panel"] = 1] = "Panel";
3409
+ DockviewDropTargets[DockviewDropTargets["TabContainer"] = 2] = "TabContainer";
3410
+ DockviewDropTargets[DockviewDropTargets["Edge"] = 3] = "Edge";
3411
+ })(exports.DockviewDropTargets || (exports.DockviewDropTargets = {}));
3412
+
3191
3413
  class ContentContainer extends CompositeDisposable {
3192
3414
  get element() {
3193
3415
  return this._element;
3194
3416
  }
3195
- constructor() {
3417
+ constructor(accessor, group) {
3196
3418
  super();
3419
+ this.accessor = accessor;
3420
+ this.group = group;
3197
3421
  this.disposable = new MutableDisposable();
3198
3422
  this._onDidFocus = new Emitter();
3199
3423
  this.onDidFocus = this._onDidFocus.event;
@@ -3203,11 +3427,38 @@ class ContentContainer extends CompositeDisposable {
3203
3427
  this._element.className = 'content-container';
3204
3428
  this._element.tabIndex = -1;
3205
3429
  this.addDisposables(this._onDidFocus, this._onDidBlur);
3206
- // for hosted containers
3207
- // 1) register a drop target on the host
3208
- // 2) register window dragStart events to disable pointer events
3209
- // 3) register dragEnd events
3210
- // 4) register mouseMove events (if no buttons are present we take this as a dragEnd event)
3430
+ this.dropTarget = new Droptarget(this.element, {
3431
+ acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
3432
+ canDisplayOverlay: (event, position) => {
3433
+ if (this.group.locked === 'no-drop-target' ||
3434
+ (this.group.locked && position === 'center')) {
3435
+ return false;
3436
+ }
3437
+ const data = getPanelData();
3438
+ if (!data &&
3439
+ event.shiftKey &&
3440
+ this.group.location !== 'floating') {
3441
+ return false;
3442
+ }
3443
+ if (data && data.viewId === this.accessor.id) {
3444
+ if (data.groupId === this.group.id) {
3445
+ if (position === 'center') {
3446
+ // don't allow to drop on self for center position
3447
+ return false;
3448
+ }
3449
+ if (data.panelId === null) {
3450
+ // don't allow group move to drop anywhere on self
3451
+ return false;
3452
+ }
3453
+ }
3454
+ const groupHasOnePanelAndIsActiveDragElement = this.group.panels.length === 1 &&
3455
+ data.groupId === this.group.id;
3456
+ return !groupHasOnePanelAndIsActiveDragElement;
3457
+ }
3458
+ return this.group.canDisplayOverlay(event, position, exports.DockviewDropTargets.Panel);
3459
+ },
3460
+ });
3461
+ this.addDisposables(this.dropTarget);
3211
3462
  }
3212
3463
  show() {
3213
3464
  this.element.style.display = '';
@@ -3215,23 +3466,43 @@ class ContentContainer extends CompositeDisposable {
3215
3466
  hide() {
3216
3467
  this.element.style.display = 'none';
3217
3468
  }
3218
- openPanel(panel) {
3219
- var _a;
3220
- if (this.panel === panel) {
3221
- return;
3222
- }
3223
- if (this.panel) {
3224
- if ((_a = this.panel.view) === null || _a === void 0 ? void 0 : _a.content) {
3225
- this._element.removeChild(this.panel.view.content.element);
3226
- }
3227
- this.panel = undefined;
3469
+ renderPanel(panel, options = { asActive: true }) {
3470
+ const doRender = options.asActive ||
3471
+ (this.panel && this.group.isPanelActive(this.panel));
3472
+ if (this.panel &&
3473
+ this.panel.view.content.element.parentElement === this._element) {
3474
+ /**
3475
+ * If the currently attached panel is mounted directly to the content then remove it
3476
+ */
3477
+ this._element.removeChild(this.panel.view.content.element);
3228
3478
  }
3229
3479
  this.panel = panel;
3230
- const disposable = new CompositeDisposable();
3231
- if (this.panel.view) {
3232
- const _onDidFocus = this.panel.view.content.onDidFocus;
3233
- const _onDidBlur = this.panel.view.content.onDidBlur;
3234
- const focusTracker = trackFocus(this._element);
3480
+ let container;
3481
+ switch (panel.api.renderer) {
3482
+ case 'onlyWhenVisibile':
3483
+ this.accessor.overlayRenderContainer.detatch(panel);
3484
+ if (this.panel) {
3485
+ if (doRender) {
3486
+ this._element.appendChild(this.panel.view.content.element);
3487
+ }
3488
+ }
3489
+ container = this._element;
3490
+ break;
3491
+ case 'always':
3492
+ if (panel.view.content.element.parentElement === this._element) {
3493
+ this._element.removeChild(panel.view.content.element);
3494
+ }
3495
+ container = this.accessor.overlayRenderContainer.attach({
3496
+ panel,
3497
+ referenceContainer: this,
3498
+ });
3499
+ break;
3500
+ }
3501
+ if (doRender) {
3502
+ const _onDidFocus = panel.view.content.onDidFocus;
3503
+ const _onDidBlur = panel.view.content.onDidBlur;
3504
+ const focusTracker = trackFocus(container);
3505
+ const disposable = new CompositeDisposable();
3235
3506
  disposable.addDisposables(focusTracker, focusTracker.onDidFocus(() => this._onDidFocus.fire()), focusTracker.onDidBlur(() => this._onDidBlur.fire()));
3236
3507
  if (_onDidFocus) {
3237
3508
  disposable.addDisposables(_onDidFocus(() => this._onDidFocus.fire()));
@@ -3239,17 +3510,23 @@ class ContentContainer extends CompositeDisposable {
3239
3510
  if (_onDidBlur) {
3240
3511
  disposable.addDisposables(_onDidBlur(() => this._onDidBlur.fire()));
3241
3512
  }
3242
- this._element.appendChild(this.panel.view.content.element);
3513
+ this.disposable.value = disposable;
3243
3514
  }
3244
- this.disposable.value = disposable;
3515
+ }
3516
+ openPanel(panel) {
3517
+ if (this.panel === panel) {
3518
+ return;
3519
+ }
3520
+ this.renderPanel(panel);
3245
3521
  }
3246
3522
  layout(_width, _height) {
3247
3523
  // noop
3248
3524
  }
3249
3525
  closePanel() {
3250
- var _a, _b, _c;
3251
- if ((_c = (_b = (_a = this.panel) === null || _a === void 0 ? void 0 : _a.view) === null || _b === void 0 ? void 0 : _b.content) === null || _c === void 0 ? void 0 : _c.element) {
3252
- this._element.removeChild(this.panel.view.content.element);
3526
+ if (this.panel) {
3527
+ if (this.accessor.options.defaultRenderer === 'onlyWhenVisibile') {
3528
+ this._element.removeChild(this.panel.view.content.element);
3529
+ }
3253
3530
  this.panel = undefined;
3254
3531
  }
3255
3532
  }
@@ -3259,14 +3536,6 @@ class ContentContainer extends CompositeDisposable {
3259
3536
  }
3260
3537
  }
3261
3538
 
3262
- exports.DockviewDropTargets = void 0;
3263
- (function (DockviewDropTargets) {
3264
- DockviewDropTargets[DockviewDropTargets["Tab"] = 0] = "Tab";
3265
- DockviewDropTargets[DockviewDropTargets["Panel"] = 1] = "Panel";
3266
- DockviewDropTargets[DockviewDropTargets["TabContainer"] = 2] = "TabContainer";
3267
- DockviewDropTargets[DockviewDropTargets["Edge"] = 3] = "Edge";
3268
- })(exports.DockviewDropTargets || (exports.DockviewDropTargets = {}));
3269
-
3270
3539
  class DragHandler extends CompositeDisposable {
3271
3540
  constructor(el) {
3272
3541
  super();
@@ -3441,7 +3710,7 @@ class GroupDragHandler extends DragHandler {
3441
3710
  }, true));
3442
3711
  }
3443
3712
  isCancelled(_event) {
3444
- if (this.group.api.isFloating && !_event.shiftKey) {
3713
+ if (this.group.api.location === 'floating' && !_event.shiftKey) {
3445
3714
  return true;
3446
3715
  }
3447
3716
  return false;
@@ -3643,7 +3912,7 @@ class TabsContainer extends CompositeDisposable {
3643
3912
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3644
3913
  if (isFloatingGroupsEnabled &&
3645
3914
  event.shiftKey &&
3646
- !this.group.api.isFloating) {
3915
+ this.group.api.location !== 'floating') {
3647
3916
  event.preventDefault();
3648
3917
  const { top, left } = this.element.getBoundingClientRect();
3649
3918
  const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
@@ -3708,7 +3977,7 @@ class TabsContainer extends CompositeDisposable {
3708
3977
  }), tab.onChanged((event) => {
3709
3978
  var _a;
3710
3979
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3711
- const isFloatingWithOnePanel = this.group.api.isFloating && this.size === 1;
3980
+ const isFloatingWithOnePanel = this.group.api.location === 'floating' && this.size === 1;
3712
3981
  if (isFloatingGroupsEnabled &&
3713
3982
  !isFloatingWithOnePanel &&
3714
3983
  event.shiftKey) {
@@ -3791,15 +4060,37 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3791
4060
  }
3792
4061
  return isAncestor(document.activeElement, this.contentContainer.element);
3793
4062
  }
3794
- get isFloating() {
3795
- return this._isFloating;
3796
- }
3797
- set isFloating(value) {
3798
- this._isFloating = value;
3799
- this.dropTarget.setTargetZones(value ? ['center'] : ['top', 'bottom', 'left', 'right', 'center']);
3800
- toggleClass(this.container, 'dv-groupview-floating', value);
3801
- this.groupPanel.api._onDidFloatingStateChange.fire({
3802
- isFloating: this.isFloating,
4063
+ get location() {
4064
+ return this._location;
4065
+ }
4066
+ set location(value) {
4067
+ this._location = value;
4068
+ toggleClass(this.container, 'dv-groupview-floating', false);
4069
+ toggleClass(this.container, 'dv-groupview-popout', false);
4070
+ switch (value) {
4071
+ case 'grid':
4072
+ this.contentContainer.dropTarget.setTargetZones([
4073
+ 'top',
4074
+ 'bottom',
4075
+ 'left',
4076
+ 'right',
4077
+ 'center',
4078
+ ]);
4079
+ break;
4080
+ case 'floating':
4081
+ this.contentContainer.dropTarget.setTargetZones(['center']);
4082
+ this.contentContainer.dropTarget.setTargetZones(value
4083
+ ? ['center']
4084
+ : ['top', 'bottom', 'left', 'right', 'center']);
4085
+ toggleClass(this.container, 'dv-groupview-floating', true);
4086
+ break;
4087
+ case 'popout':
4088
+ this.contentContainer.dropTarget.setTargetZones(['center']);
4089
+ toggleClass(this.container, 'dv-groupview-popout', true);
4090
+ break;
4091
+ }
4092
+ this.groupPanel.api._onDidLocationChange.fire({
4093
+ location: this.location,
3803
4094
  });
3804
4095
  }
3805
4096
  constructor(container, accessor, id, options, groupPanel) {
@@ -3812,7 +4103,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3812
4103
  this.groupPanel = groupPanel;
3813
4104
  this._isGroupActive = false;
3814
4105
  this._locked = false;
3815
- this._isFloating = false;
4106
+ this._location = 'grid';
3816
4107
  this.mostRecentlyUsed = [];
3817
4108
  this._onDidChange = new Emitter();
3818
4109
  this.onDidChange = this._onDidChange.event;
@@ -3835,35 +4126,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3835
4126
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
3836
4127
  toggleClass(this.container, 'groupview', true);
3837
4128
  this.tabsContainer = new TabsContainer(this.accessor, this.groupPanel);
3838
- this.contentContainer = new ContentContainer();
3839
- this.dropTarget = new Droptarget(this.contentContainer.element, {
3840
- acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
3841
- canDisplayOverlay: (event, position) => {
3842
- if (this.locked === 'no-drop-target' ||
3843
- (this.locked && position === 'center')) {
3844
- return false;
3845
- }
3846
- const data = getPanelData();
3847
- if (!data && event.shiftKey && !this.isFloating) {
3848
- return false;
3849
- }
3850
- if (data && data.viewId === this.accessor.id) {
3851
- if (data.groupId === this.id) {
3852
- if (position === 'center') {
3853
- // don't allow to drop on self for center position
3854
- return false;
3855
- }
3856
- if (data.panelId === null) {
3857
- // don't allow group move to drop anywhere on self
3858
- return false;
3859
- }
3860
- }
3861
- const groupHasOnePanelAndIsActiveDragElement = this._panels.length === 1 && data.groupId === this.id;
3862
- return !groupHasOnePanelAndIsActiveDragElement;
3863
- }
3864
- return this.canDisplayOverlay(event, position, exports.DockviewDropTargets.Panel);
3865
- },
3866
- });
4129
+ this.contentContainer = new ContentContainer(this.accessor, this);
3867
4130
  container.append(this.tabsContainer.element, this.contentContainer.element);
3868
4131
  this.header.hidden = !!options.hideHeader;
3869
4132
  this.locked = (_a = options.locked) !== null && _a !== void 0 ? _a : false;
@@ -3877,7 +4140,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3877
4140
  this.accessor.doSetGroupActive(this.groupPanel, true);
3878
4141
  }), this.contentContainer.onDidBlur(() => {
3879
4142
  // noop
3880
- }), this.dropTarget.onDrop((event) => {
4143
+ }), this.contentContainer.dropTarget.onDrop((event) => {
3881
4144
  this.handleDropEvent(event.nativeEvent, event.position);
3882
4145
  }), this._onMove, this._onDidChange, this._onDidDrop, this._onDidAddPanel, this._onDidRemovePanel, this._onDidActivePanelChange);
3883
4146
  }
@@ -3926,6 +4189,9 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3926
4189
  this.tabsContainer.setPrefixActionsElement(this._prefixHeaderActions.element);
3927
4190
  }
3928
4191
  }
4192
+ rerender(panel) {
4193
+ this.contentContainer.renderPanel(panel, { asActive: false });
4194
+ }
3929
4195
  indexOf(panel) {
3930
4196
  return this.tabsContainer.indexOf(panel.id);
3931
4197
  }
@@ -4117,12 +4383,12 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4117
4383
  doAddPanel(panel, index = this.panels.length, skipSetActive = false) {
4118
4384
  const existingPanel = this._panels.indexOf(panel);
4119
4385
  const hasExistingPanel = existingPanel > -1;
4386
+ this.tabsContainer.show();
4387
+ this.contentContainer.show();
4120
4388
  this.tabsContainer.openPanel(panel, index);
4121
4389
  if (!skipSetActive) {
4122
4390
  this.contentContainer.openPanel(panel);
4123
4391
  }
4124
- this.tabsContainer.show();
4125
- this.contentContainer.show();
4126
4392
  if (hasExistingPanel) {
4127
4393
  // TODO - need to ensure ordering hasn't changed and if it has need to re-order this.panels
4128
4394
  return;
@@ -4238,7 +4504,6 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4238
4504
  for (const panel of this.panels) {
4239
4505
  panel.dispose();
4240
4506
  }
4241
- this.dropTarget.dispose();
4242
4507
  this.tabsContainer.dispose();
4243
4508
  this.contentContainer.dispose();
4244
4509
  }
@@ -4277,7 +4542,7 @@ class Resizable extends CompositeDisposable {
4277
4542
  if (this.disableResizing) {
4278
4543
  return;
4279
4544
  }
4280
- if (!document.body.contains(this._element)) {
4545
+ if (!isInDocument(this._element)) {
4281
4546
  /**
4282
4547
  * since the event is dispatched through requestAnimationFrame there is a small chance
4283
4548
  * the component is no longer attached to the DOM, if that is the case the dimensions
@@ -4369,6 +4634,21 @@ class BaseGrid extends Resizable {
4369
4634
  isVisible(panel) {
4370
4635
  return this.gridview.isViewVisible(getGridLocation(panel.element));
4371
4636
  }
4637
+ maximizeGroup(panel) {
4638
+ this.gridview.maximizeView(panel);
4639
+ }
4640
+ isMaximizedGroup(panel) {
4641
+ return this.gridview.maximizedView() === panel;
4642
+ }
4643
+ exitMaximizedGroup() {
4644
+ this.gridview.exitMaximizedView();
4645
+ }
4646
+ hasMaximizedGroup() {
4647
+ return this.gridview.hasMaximizedView();
4648
+ }
4649
+ get onDidMaxmizedGroupChange() {
4650
+ return this.gridview.onDidMaxmizedNodeChange;
4651
+ }
4372
4652
  doAddGroup(group, location = [0], size) {
4373
4653
  this.gridview.addView(group, size !== null && size !== void 0 ? size : exports.Sizing.Distribute, location);
4374
4654
  this._onDidAddGroup.fire(group);
@@ -5145,32 +5425,63 @@ class GridviewPanel extends BasePanelView {
5145
5425
  }
5146
5426
  }
5147
5427
 
5428
+ // TODO find a better way to initialize and avoid needing null checks
5429
+ const NOT_INITIALIZED_MESSAGE = 'DockviewGroupPanelApiImpl not initialized';
5148
5430
  class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
5149
- get isFloating() {
5431
+ get location() {
5150
5432
  if (!this._group) {
5151
- throw new Error(`DockviewGroupPanelApiImpl not initialized`);
5433
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5152
5434
  }
5153
- return this._group.model.isFloating;
5435
+ return this._group.model.location;
5154
5436
  }
5155
5437
  constructor(id, accessor) {
5156
5438
  super(id);
5157
5439
  this.accessor = accessor;
5158
- this._onDidFloatingStateChange = new Emitter();
5159
- this.onDidFloatingStateChange = this._onDidFloatingStateChange.event;
5160
- this.addDisposables(this._onDidFloatingStateChange);
5440
+ this._onDidLocationChange = new Emitter();
5441
+ this.onDidLocationChange = this._onDidLocationChange.event;
5442
+ this.addDisposables(this._onDidLocationChange);
5161
5443
  }
5162
5444
  moveTo(options) {
5163
- var _a;
5445
+ var _a, _b, _c;
5446
+ if (!this._group) {
5447
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5448
+ }
5449
+ const group = (_a = options.group) !== null && _a !== void 0 ? _a : this.accessor.addGroup({
5450
+ direction: positionToDirection((_b = options.position) !== null && _b !== void 0 ? _b : 'right'),
5451
+ });
5452
+ this.accessor.moveGroupOrPanel(group, this._group.id, undefined, options.group ? (_c = options.position) !== null && _c !== void 0 ? _c : 'center' : 'center');
5453
+ }
5454
+ maximize() {
5455
+ if (!this._group) {
5456
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5457
+ }
5458
+ if (this.location !== 'grid') {
5459
+ // only grid groups can be maximized
5460
+ return;
5461
+ }
5462
+ this.accessor.maximizeGroup(this._group);
5463
+ }
5464
+ isMaximized() {
5164
5465
  if (!this._group) {
5165
- throw new Error(`DockviewGroupPanelApiImpl not initialized`);
5466
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5467
+ }
5468
+ return this.accessor.isMaximizedGroup(this._group);
5469
+ }
5470
+ exitMaximized() {
5471
+ if (!this._group) {
5472
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5473
+ }
5474
+ if (this.isMaximized()) {
5475
+ this.accessor.exitMaximizedGroup();
5166
5476
  }
5167
- this.accessor.moveGroupOrPanel(options.group, this._group.id, undefined, (_a = options.position) !== null && _a !== void 0 ? _a : 'center');
5168
5477
  }
5169
5478
  initialize(group) {
5170
5479
  this._group = group;
5171
5480
  }
5172
5481
  }
5173
5482
 
5483
+ const MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH = 100;
5484
+ const MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT = 100;
5174
5485
  class DockviewGroupPanel extends GridviewPanel {
5175
5486
  get panels() {
5176
5487
  return this._model.panels;
@@ -5195,8 +5506,8 @@ class DockviewGroupPanel extends GridviewPanel {
5195
5506
  }
5196
5507
  constructor(accessor, id, options) {
5197
5508
  super(id, 'groupview_default', {
5198
- minimumHeight: 100,
5199
- minimumWidth: 100,
5509
+ minimumHeight: MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT,
5510
+ minimumWidth: MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH,
5200
5511
  }, new DockviewGroupPanelApiImpl(id, accessor));
5201
5512
  this.api.initialize(this); // cannot use 'this' after after 'super' call
5202
5513
  this._model = new DockviewGroupPanelModel(this.element, accessor, id, options, this);
@@ -5250,8 +5561,10 @@ class DockviewPanelApiImpl extends GridviewPanelApiImpl {
5250
5561
  return this.panel.title;
5251
5562
  }
5252
5563
  get isGroupActive() {
5253
- var _a;
5254
- return !!((_a = this.group) === null || _a === void 0 ? void 0 : _a.isActive);
5564
+ return this.group.isActive;
5565
+ }
5566
+ get renderer() {
5567
+ return this.panel.renderer;
5255
5568
  }
5256
5569
  set group(value) {
5257
5570
  const isOldGroupActive = this.isGroupActive;
@@ -5279,10 +5592,12 @@ class DockviewPanelApiImpl extends GridviewPanelApiImpl {
5279
5592
  this.onDidActiveGroupChange = this._onDidActiveGroupChange.event;
5280
5593
  this._onDidGroupChange = new Emitter();
5281
5594
  this.onDidGroupChange = this._onDidGroupChange.event;
5595
+ this._onDidRendererChange = new Emitter();
5596
+ this.onDidRendererChange = this._onDidRendererChange.event;
5282
5597
  this.disposable = new MutableDisposable();
5283
5598
  this.initialize(panel);
5284
5599
  this._group = group;
5285
- this.addDisposables(this.disposable, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange);
5600
+ this.addDisposables(this.disposable, this._onDidRendererChange, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange);
5286
5601
  }
5287
5602
  moveTo(options) {
5288
5603
  var _a;
@@ -5291,9 +5606,21 @@ class DockviewPanelApiImpl extends GridviewPanelApiImpl {
5291
5606
  setTitle(title) {
5292
5607
  this.panel.setTitle(title);
5293
5608
  }
5609
+ setRenderer(renderer) {
5610
+ this.panel.setRenderer(renderer);
5611
+ }
5294
5612
  close() {
5295
5613
  this.group.model.closePanel(this.panel);
5296
5614
  }
5615
+ maximize() {
5616
+ this.group.api.maximize();
5617
+ }
5618
+ isMaximized() {
5619
+ return this.group.api.isMaximized();
5620
+ }
5621
+ exitMaximized() {
5622
+ this.group.api.exitMaximized();
5623
+ }
5297
5624
  }
5298
5625
 
5299
5626
  class DockviewPanel extends CompositeDisposable {
@@ -5306,11 +5633,17 @@ class DockviewPanel extends CompositeDisposable {
5306
5633
  get group() {
5307
5634
  return this._group;
5308
5635
  }
5309
- constructor(id, accessor, containerApi, group, view) {
5636
+ get renderer() {
5637
+ var _a;
5638
+ return (_a = this._renderer) !== null && _a !== void 0 ? _a : this.accessor.renderer;
5639
+ }
5640
+ constructor(id, accessor, containerApi, group, view, options) {
5310
5641
  super();
5311
5642
  this.id = id;
5643
+ this.accessor = accessor;
5312
5644
  this.containerApi = containerApi;
5313
5645
  this.view = view;
5646
+ this._renderer = options.renderer;
5314
5647
  this._group = group;
5315
5648
  this.api = new DockviewPanelApiImpl(this, this._group, accessor);
5316
5649
  this.addDisposables(this.api.onActiveChange(() => {
@@ -5319,6 +5652,8 @@ class DockviewPanel extends CompositeDisposable {
5319
5652
  // forward the resize event to the group since if you want to resize a panel
5320
5653
  // you are actually just resizing the panels parent which is the group
5321
5654
  this.group.api.setSize(event);
5655
+ }), this.api.onDidRendererChange((event) => {
5656
+ this.group.model.rerender(this);
5322
5657
  }));
5323
5658
  }
5324
5659
  init(params) {
@@ -5338,6 +5673,7 @@ class DockviewPanel extends CompositeDisposable {
5338
5673
  ? this._params
5339
5674
  : undefined,
5340
5675
  title: this.title,
5676
+ renderer: this._renderer,
5341
5677
  };
5342
5678
  }
5343
5679
  setTitle(title) {
@@ -5353,6 +5689,15 @@ class DockviewPanel extends CompositeDisposable {
5353
5689
  this.api._onDidTitleChange.fire({ title });
5354
5690
  }
5355
5691
  }
5692
+ setRenderer(renderer) {
5693
+ const didChange = renderer !== this.renderer;
5694
+ if (didChange) {
5695
+ this._renderer = renderer;
5696
+ this.api._onDidRendererChange.fire({
5697
+ renderer: renderer,
5698
+ });
5699
+ }
5700
+ }
5356
5701
  update(event) {
5357
5702
  var _a;
5358
5703
  // merge the new parameters with the existing parameters
@@ -5571,8 +5916,8 @@ class DockviewPanelModel {
5571
5916
  }
5572
5917
 
5573
5918
  class DefaultDockviewDeserialzier {
5574
- constructor(layout) {
5575
- this.layout = layout;
5919
+ constructor(accessor) {
5920
+ this.accessor = accessor;
5576
5921
  }
5577
5922
  fromJSON(panelData, group) {
5578
5923
  var _a, _b;
@@ -5586,8 +5931,10 @@ class DefaultDockviewDeserialzier {
5586
5931
  const tabComponent = viewData
5587
5932
  ? (_b = viewData.tab) === null || _b === void 0 ? void 0 : _b.id
5588
5933
  : panelData.tabComponent;
5589
- const view = new DockviewPanelModel(this.layout, panelId, contentComponent, tabComponent);
5590
- const panel = new DockviewPanel(panelId, this.layout, new DockviewApi(this.layout), group, view);
5934
+ const view = new DockviewPanelModel(this.accessor, panelId, contentComponent, tabComponent);
5935
+ const panel = new DockviewPanel(panelId, this.accessor, new DockviewApi(this.accessor), group, view, {
5936
+ renderer: panelData.renderer,
5937
+ });
5591
5938
  panel.init({
5592
5939
  title: title !== null && title !== void 0 ? title : panelId,
5593
5940
  params: params !== null && params !== void 0 ? params : {},
@@ -5967,7 +6314,261 @@ class DockviewFloatingGroupPanel extends CompositeDisposable {
5967
6314
  }
5968
6315
  }
5969
6316
 
6317
+ class PopoutWindow extends CompositeDisposable {
6318
+ constructor(id, className, options) {
6319
+ super();
6320
+ this.id = id;
6321
+ this.className = className;
6322
+ this.options = options;
6323
+ this._onDidClose = new Emitter();
6324
+ this.onDidClose = this._onDidClose.event;
6325
+ this._window = null;
6326
+ this.addDisposables(this._onDidClose, {
6327
+ dispose: () => {
6328
+ this.close();
6329
+ },
6330
+ });
6331
+ }
6332
+ dimensions() {
6333
+ if (!this._window) {
6334
+ return null;
6335
+ }
6336
+ const left = this._window.value.screenX;
6337
+ const top = this._window.value.screenY;
6338
+ const width = this._window.value.innerWidth;
6339
+ const height = this._window.value.innerHeight;
6340
+ return { top, left, width, height };
6341
+ }
6342
+ close() {
6343
+ if (this._window) {
6344
+ this._window.disposable.dispose();
6345
+ this._window.value.close();
6346
+ this._window = null;
6347
+ }
6348
+ }
6349
+ open(content) {
6350
+ if (this._window) {
6351
+ throw new Error('instance of popout window is already open');
6352
+ }
6353
+ const url = `${this.options.url}`;
6354
+ const features = Object.entries({
6355
+ top: this.options.top,
6356
+ left: this.options.left,
6357
+ width: this.options.width,
6358
+ height: this.options.height,
6359
+ })
6360
+ .map(([key, value]) => `${key}=${value}`)
6361
+ .join(',');
6362
+ // https://developer.mozilla.org/en-US/docs/Web/API/Window/open
6363
+ const externalWindow = window.open(url, this.id, features);
6364
+ if (!externalWindow) {
6365
+ return;
6366
+ }
6367
+ const disposable = new CompositeDisposable();
6368
+ this._window = { value: externalWindow, disposable };
6369
+ const cleanUp = () => {
6370
+ this._onDidClose.fire();
6371
+ this._window = null;
6372
+ };
6373
+ // prevent any default content from loading
6374
+ // externalWindow.document.body.replaceWith(document.createElement('div'));
6375
+ disposable.addDisposables(addDisposableWindowListener(window, 'beforeunload', () => {
6376
+ cleanUp();
6377
+ this.close();
6378
+ }));
6379
+ externalWindow.addEventListener('load', () => {
6380
+ const externalDocument = externalWindow.document;
6381
+ externalDocument.title = document.title;
6382
+ const div = document.createElement('div');
6383
+ div.classList.add('dv-popout-window');
6384
+ div.style.position = 'absolute';
6385
+ div.style.width = '100%';
6386
+ div.style.height = '100%';
6387
+ div.style.top = '0px';
6388
+ div.style.left = '0px';
6389
+ div.classList.add(this.className);
6390
+ div.appendChild(content);
6391
+ externalDocument.body.replaceChildren(div);
6392
+ externalDocument.body.classList.add(this.className);
6393
+ addStyles(externalDocument, window.document.styleSheets);
6394
+ externalWindow.addEventListener('beforeunload', () => {
6395
+ // TODO: indicate external window is closing
6396
+ cleanUp();
6397
+ });
6398
+ });
6399
+ }
6400
+ }
6401
+
6402
+ class DockviewPopoutGroupPanel extends CompositeDisposable {
6403
+ constructor(id, group, options) {
6404
+ var _a;
6405
+ super();
6406
+ this.id = id;
6407
+ this.group = group;
6408
+ this.options = options;
6409
+ this.window = new PopoutWindow(id, (_a = options.className) !== null && _a !== void 0 ? _a : '', {
6410
+ url: this.options.popoutUrl,
6411
+ left: this.options.box.left,
6412
+ top: this.options.box.top,
6413
+ width: this.options.box.width,
6414
+ height: this.options.box.height,
6415
+ });
6416
+ group.model.location = 'popout';
6417
+ this.addDisposables(this.window, {
6418
+ dispose: () => {
6419
+ group.model.location = 'grid';
6420
+ },
6421
+ }, this.window.onDidClose(() => {
6422
+ this.dispose();
6423
+ }));
6424
+ this.window.open(group.element);
6425
+ }
6426
+ }
6427
+
5970
6428
  const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100;
6429
+ const DEFAULT_FLOATING_GROUP_POSITION = { left: 100, top: 100 };
6430
+
6431
+ function createFocusableElement() {
6432
+ const element = document.createElement('div');
6433
+ element.tabIndex = -1;
6434
+ return element;
6435
+ }
6436
+ class OverlayRenderContainer extends CompositeDisposable {
6437
+ constructor(element) {
6438
+ super();
6439
+ this.element = element;
6440
+ this.map = {};
6441
+ this.addDisposables(Disposable.from(() => {
6442
+ for (const value of Object.values(this.map)) {
6443
+ value.disposable.dispose();
6444
+ value.destroy.dispose();
6445
+ }
6446
+ }));
6447
+ }
6448
+ detatch(panel) {
6449
+ if (this.map[panel.api.id]) {
6450
+ const { disposable, destroy } = this.map[panel.api.id];
6451
+ disposable.dispose();
6452
+ destroy.dispose();
6453
+ delete this.map[panel.api.id];
6454
+ return true;
6455
+ }
6456
+ return false;
6457
+ }
6458
+ attach(options) {
6459
+ const { panel, referenceContainer } = options;
6460
+ if (!this.map[panel.api.id]) {
6461
+ const element = createFocusableElement();
6462
+ element.className = 'dv-render-overlay';
6463
+ this.map[panel.api.id] = {
6464
+ panel,
6465
+ disposable: Disposable.NONE,
6466
+ destroy: Disposable.NONE,
6467
+ element,
6468
+ };
6469
+ }
6470
+ const focusContainer = this.map[panel.api.id].element;
6471
+ if (panel.view.content.element.parentElement !== focusContainer) {
6472
+ focusContainer.appendChild(panel.view.content.element);
6473
+ }
6474
+ if (focusContainer.parentElement !== this.element) {
6475
+ this.element.appendChild(focusContainer);
6476
+ }
6477
+ const resize = () => {
6478
+ // TODO propagate position to avoid getDomNodePagePosition calls, possible performance bottleneck?
6479
+ const box = getDomNodePagePosition(referenceContainer.element);
6480
+ const box2 = getDomNodePagePosition(this.element);
6481
+ focusContainer.style.left = `${box.left - box2.left}px`;
6482
+ focusContainer.style.top = `${box.top - box2.top}px`;
6483
+ focusContainer.style.width = `${box.width}px`;
6484
+ focusContainer.style.height = `${box.height}px`;
6485
+ toggleClass(focusContainer, 'dv-render-overlay-float', panel.group.api.location === 'floating');
6486
+ };
6487
+ const visibilityChanged = () => {
6488
+ if (panel.api.isVisible) {
6489
+ resize();
6490
+ }
6491
+ focusContainer.style.display = panel.api.isVisible ? '' : 'none';
6492
+ };
6493
+ const disposable = new CompositeDisposable(
6494
+ /**
6495
+ * since container is positioned absoutely we must explicitly forward
6496
+ * the dnd events for the expect behaviours to continue to occur in terms of dnd
6497
+ *
6498
+ * the dnd observer does not need to be conditional on whether the panel is visible since
6499
+ * non-visible panels are 'display: none' and in such case the dnd observer will not fire.
6500
+ */
6501
+ new DragAndDropObserver(focusContainer, {
6502
+ onDragEnd: (e) => {
6503
+ referenceContainer.dropTarget.dnd.onDragEnd(e);
6504
+ },
6505
+ onDragEnter: (e) => {
6506
+ referenceContainer.dropTarget.dnd.onDragEnter(e);
6507
+ },
6508
+ onDragLeave: (e) => {
6509
+ referenceContainer.dropTarget.dnd.onDragLeave(e);
6510
+ },
6511
+ onDrop: (e) => {
6512
+ referenceContainer.dropTarget.dnd.onDrop(e);
6513
+ },
6514
+ onDragOver: (e) => {
6515
+ referenceContainer.dropTarget.dnd.onDragOver(e);
6516
+ },
6517
+ }), panel.api.onDidVisibilityChange((event) => {
6518
+ /**
6519
+ * Control the visibility of the content, however even when not visible (display: none)
6520
+ * the content is still maintained within the DOM hence DOM specific attributes
6521
+ * such as scroll position are maintained when next made visible.
6522
+ */
6523
+ visibilityChanged();
6524
+ }), panel.api.onDidDimensionsChange(() => {
6525
+ if (!panel.api.isVisible) {
6526
+ return;
6527
+ }
6528
+ resize();
6529
+ }));
6530
+ this.map[panel.api.id].destroy = Disposable.from(() => {
6531
+ focusContainer.removeChild(panel.view.content.element);
6532
+ this.element.removeChild(focusContainer);
6533
+ });
6534
+ queueMicrotask(() => {
6535
+ if (this.isDisposed) {
6536
+ return;
6537
+ }
6538
+ /**
6539
+ * wait until everything has finished in the current stack-frame call before
6540
+ * calling the first resize as other size-altering events may still occur before
6541
+ * the end of the stack-frame.
6542
+ */
6543
+ visibilityChanged();
6544
+ });
6545
+ // dispose of logic asoccciated with previous reference-container
6546
+ this.map[panel.api.id].disposable.dispose();
6547
+ // and reset the disposable to the active reference-container
6548
+ this.map[panel.api.id].disposable = disposable;
6549
+ return focusContainer;
6550
+ }
6551
+ }
6552
+
6553
+ function getTheme(element) {
6554
+ function toClassList(element) {
6555
+ const list = [];
6556
+ for (let i = 0; i < element.classList.length; i++) {
6557
+ list.push(element.classList.item(i));
6558
+ }
6559
+ return list;
6560
+ }
6561
+ let theme = undefined;
6562
+ let parent = element;
6563
+ while (parent !== null) {
6564
+ theme = toClassList(parent).find((cls) => cls.startsWith('dockview-theme-'));
6565
+ if (typeof theme === 'string') {
6566
+ break;
6567
+ }
6568
+ parent = parent.parentElement;
6569
+ }
6570
+ return theme;
6571
+ }
5971
6572
  class DockviewComponent extends BaseGrid {
5972
6573
  get orientation() {
5973
6574
  return this.gridview.orientation;
@@ -5988,6 +6589,10 @@ class DockviewComponent extends BaseGrid {
5988
6589
  }
5989
6590
  return activeGroup.activePanel;
5990
6591
  }
6592
+ get renderer() {
6593
+ var _a;
6594
+ return (_a = this.options.defaultRenderer) !== null && _a !== void 0 ? _a : 'onlyWhenVisibile';
6595
+ }
5991
6596
  constructor(options) {
5992
6597
  var _a;
5993
6598
  super({
@@ -6014,12 +6619,27 @@ class DockviewComponent extends BaseGrid {
6014
6619
  this.onDidLayoutFromJSON = this._onDidLayoutFromJSON.event;
6015
6620
  this._onDidActivePanelChange = new Emitter();
6016
6621
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
6017
- this.floatingGroups = [];
6622
+ this._floatingGroups = [];
6623
+ this._popoutGroups = [];
6624
+ const gready = document.createElement('div');
6625
+ gready.className = 'dv-overlay-render-container';
6626
+ this.gridview.element.appendChild(gready);
6627
+ this.overlayRenderContainer = new OverlayRenderContainer(gready);
6018
6628
  toggleClass(this.gridview.element, 'dv-dockview', true);
6019
- this.addDisposables(this._onWillDragPanel, this._onWillDragGroup, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
6629
+ toggleClass(this.element, 'dv-debug', !!options.debug);
6630
+ this.addDisposables(this.overlayRenderContainer, this._onWillDragPanel, this._onWillDragGroup, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
6020
6631
  this.updateWatermark();
6021
6632
  }), exports.DockviewEvent.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => {
6022
6633
  this._bufferOnDidLayoutChange.fire();
6634
+ }), Disposable.from(() => {
6635
+ // iterate over a copy of the array since .dispose() mutates the original array
6636
+ for (const group of [...this._floatingGroups]) {
6637
+ group.dispose();
6638
+ }
6639
+ // iterate over a copy of the array since .dispose() mutates the original array
6640
+ for (const group of [...this._popoutGroups]) {
6641
+ group.dispose();
6642
+ }
6023
6643
  }));
6024
6644
  this._options = options;
6025
6645
  if (!this.options.components) {
@@ -6089,6 +6709,55 @@ class DockviewComponent extends BaseGrid {
6089
6709
  this._api = new DockviewApi(this);
6090
6710
  this.updateWatermark();
6091
6711
  }
6712
+ addPopoutGroup(item, options) {
6713
+ var _a;
6714
+ let group;
6715
+ let box = options === null || options === void 0 ? void 0 : options.position;
6716
+ if (item instanceof DockviewPanel) {
6717
+ group = this.createGroup();
6718
+ this.removePanel(item, {
6719
+ removeEmptyGroup: true,
6720
+ skipDispose: true,
6721
+ });
6722
+ group.model.openPanel(item);
6723
+ if (!box) {
6724
+ box = this.element.getBoundingClientRect();
6725
+ }
6726
+ }
6727
+ else {
6728
+ group = item;
6729
+ if (!box) {
6730
+ box = group.element.getBoundingClientRect();
6731
+ }
6732
+ const skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' &&
6733
+ options.skipRemoveGroup;
6734
+ if (!skip) {
6735
+ this.doRemoveGroup(item, { skipDispose: true });
6736
+ }
6737
+ }
6738
+ const theme = getTheme(this.gridview.element);
6739
+ const popoutWindow = new DockviewPopoutGroupPanel(`${this.id}-${group.id}`, // globally unique within dockview
6740
+ group, {
6741
+ className: theme !== null && theme !== void 0 ? theme : '',
6742
+ popoutUrl: (_a = options === null || options === void 0 ? void 0 : options.popoutUrl) !== null && _a !== void 0 ? _a : '/popout.html',
6743
+ box: {
6744
+ left: window.screenX + box.left,
6745
+ top: window.screenY + box.top,
6746
+ width: box.width,
6747
+ height: box.height,
6748
+ },
6749
+ });
6750
+ popoutWindow.addDisposables({
6751
+ dispose: () => {
6752
+ remove(this._popoutGroups, popoutWindow);
6753
+ this.updateWatermark();
6754
+ },
6755
+ }, popoutWindow.window.onDidClose(() => {
6756
+ this.doAddGroup(group, [0]);
6757
+ }));
6758
+ this._popoutGroups.push(popoutWindow);
6759
+ this.updateWatermark();
6760
+ }
6092
6761
  addFloatingGroup(item, coord, options) {
6093
6762
  var _a, _b, _c, _d, _e, _f;
6094
6763
  let group;
@@ -6108,9 +6777,13 @@ class DockviewComponent extends BaseGrid {
6108
6777
  this.doRemoveGroup(item, { skipDispose: true });
6109
6778
  }
6110
6779
  }
6111
- group.model.isFloating = true;
6112
- const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number' ? Math.max(coord.x, 0) : 100;
6113
- const overlayTop = typeof (coord === null || coord === void 0 ? void 0 : coord.y) === 'number' ? Math.max(coord.y, 0) : 100;
6780
+ group.model.location = 'floating';
6781
+ const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number'
6782
+ ? Math.max(coord.x, 0)
6783
+ : DEFAULT_FLOATING_GROUP_POSITION.left;
6784
+ const overlayTop = typeof (coord === null || coord === void 0 ? void 0 : coord.y) === 'number'
6785
+ ? Math.max(coord.y, 0)
6786
+ : DEFAULT_FLOATING_GROUP_POSITION.top;
6114
6787
  const overlay = new Overlay({
6115
6788
  container: this.gridview.element,
6116
6789
  content: group.element,
@@ -6154,12 +6827,12 @@ class DockviewComponent extends BaseGrid {
6154
6827
  }), {
6155
6828
  dispose: () => {
6156
6829
  disposable.dispose();
6157
- group.model.isFloating = false;
6158
- remove(this.floatingGroups, floatingGroupPanel);
6830
+ group.model.location = 'grid';
6831
+ remove(this._floatingGroups, floatingGroupPanel);
6159
6832
  this.updateWatermark();
6160
6833
  },
6161
6834
  });
6162
- this.floatingGroups.push(floatingGroupPanel);
6835
+ this._floatingGroups.push(floatingGroupPanel);
6163
6836
  this.updateWatermark();
6164
6837
  }
6165
6838
  orthogonalize(position) {
@@ -6204,7 +6877,7 @@ class DockviewComponent extends BaseGrid {
6204
6877
  this.gridview.orientation = options.orientation;
6205
6878
  }
6206
6879
  if (hasFloatingGroupOptionsChanged) {
6207
- for (const group of this.floatingGroups) {
6880
+ for (const group of this._floatingGroups) {
6208
6881
  switch (this.options.floatingGroupBounds) {
6209
6882
  case 'boundedWithinViewport':
6210
6883
  group.overlay.minimumInViewportHeight = undefined;
@@ -6229,8 +6902,8 @@ class DockviewComponent extends BaseGrid {
6229
6902
  }
6230
6903
  layout(width, height, forceResize) {
6231
6904
  super.layout(width, height, forceResize);
6232
- if (this.floatingGroups) {
6233
- for (const floating of this.floatingGroups) {
6905
+ if (this._floatingGroups) {
6906
+ for (const floating of this._floatingGroups) {
6234
6907
  // ensure floting groups stay within visible boundaries
6235
6908
  floating.overlay.setBounds();
6236
6909
  }
@@ -6298,10 +6971,16 @@ class DockviewComponent extends BaseGrid {
6298
6971
  collection[panel.id] = panel.toJSON();
6299
6972
  return collection;
6300
6973
  }, {});
6301
- const floats = this.floatingGroups.map((floatingGroup) => {
6974
+ const floats = this._floatingGroups.map((group) => {
6975
+ return {
6976
+ data: group.group.toJSON(),
6977
+ position: group.overlay.toJSON(),
6978
+ };
6979
+ });
6980
+ const popoutGroups = this._popoutGroups.map((group) => {
6302
6981
  return {
6303
- data: floatingGroup.group.toJSON(),
6304
- position: floatingGroup.overlay.toJSON(),
6982
+ data: group.group.toJSON(),
6983
+ position: group.window.dimensions(),
6305
6984
  };
6306
6985
  });
6307
6986
  const result = {
@@ -6312,10 +6991,13 @@ class DockviewComponent extends BaseGrid {
6312
6991
  if (floats.length > 0) {
6313
6992
  result.floatingGroups = floats;
6314
6993
  }
6994
+ if (popoutGroups.length > 0) {
6995
+ result.popoutGroups = popoutGroups;
6996
+ }
6315
6997
  return result;
6316
6998
  }
6317
6999
  fromJSON(data) {
6318
- var _a;
7000
+ var _a, _b;
6319
7001
  this.clear();
6320
7002
  if (typeof data !== 'object' || data === null) {
6321
7003
  throw new Error('serialized layout must be a non-null object');
@@ -6382,7 +7064,16 @@ class DockviewComponent extends BaseGrid {
6382
7064
  width: position.width,
6383
7065
  }, { skipRemoveGroup: true, inDragMode: false });
6384
7066
  }
6385
- for (const floatingGroup of this.floatingGroups) {
7067
+ const serializedPopoutGroups = (_b = data.popoutGroups) !== null && _b !== void 0 ? _b : [];
7068
+ for (const serializedPopoutGroup of serializedPopoutGroups) {
7069
+ const { data, position } = serializedPopoutGroup;
7070
+ const group = createGroupFromSerializedState(data);
7071
+ this.addPopoutGroup(group, {
7072
+ skipRemoveGroup: true,
7073
+ position: position !== null && position !== void 0 ? position : undefined,
7074
+ });
7075
+ }
7076
+ for (const floatingGroup of this._floatingGroups) {
6386
7077
  floatingGroup.overlay.setBounds();
6387
7078
  }
6388
7079
  if (typeof activeGroup === 'string') {
@@ -6414,7 +7105,7 @@ class DockviewComponent extends BaseGrid {
6414
7105
  this._onDidRemoveGroup.fire(group);
6415
7106
  }
6416
7107
  // iterate over a reassigned array since original array will be modified
6417
- for (const floatingGroup of [...this.floatingGroups]) {
7108
+ for (const floatingGroup of [...this._floatingGroups]) {
6418
7109
  floatingGroup.dispose();
6419
7110
  }
6420
7111
  // fires clean-up events and clears the underlying HTML gridview.
@@ -6506,7 +7197,8 @@ class DockviewComponent extends BaseGrid {
6506
7197
  group.model.openPanel(panel);
6507
7198
  this.doSetGroupAndPanelActive(group);
6508
7199
  }
6509
- else if (referenceGroup.api.isFloating || target === 'center') {
7200
+ else if (referenceGroup.api.location === 'floating' ||
7201
+ target === 'center') {
6510
7202
  panel = this.createPanel(options, referenceGroup);
6511
7203
  referenceGroup.model.openPanel(panel);
6512
7204
  }
@@ -6550,6 +7242,7 @@ class DockviewComponent extends BaseGrid {
6550
7242
  }
6551
7243
  group.model.removePanel(panel);
6552
7244
  if (!options.skipDispose) {
7245
+ this.overlayRenderContainer.detatch(panel);
6553
7246
  panel.dispose();
6554
7247
  }
6555
7248
  if (group.size === 0 && options.removeEmptyGroup) {
@@ -6566,7 +7259,7 @@ class DockviewComponent extends BaseGrid {
6566
7259
  }
6567
7260
  updateWatermark() {
6568
7261
  var _a, _b;
6569
- if (this.groups.filter((x) => !x.api.isFloating).length === 0) {
7262
+ if (this.groups.filter((x) => x.api.location === 'grid').length === 0) {
6570
7263
  if (!this.watermark) {
6571
7264
  this.watermark = this.createWatermarkComponent();
6572
7265
  this.watermark.init({
@@ -6641,19 +7334,40 @@ class DockviewComponent extends BaseGrid {
6641
7334
  }
6642
7335
  }
6643
7336
  doRemoveGroup(group, options) {
6644
- const floatingGroup = this.floatingGroups.find((_) => _.group === group);
6645
- if (floatingGroup) {
6646
- if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
6647
- floatingGroup.group.dispose();
6648
- this._groups.delete(group.id);
6649
- this._onDidRemoveGroup.fire(group);
7337
+ if (group.api.location === 'floating') {
7338
+ const floatingGroup = this._floatingGroups.find((_) => _.group === group);
7339
+ if (floatingGroup) {
7340
+ if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
7341
+ floatingGroup.group.dispose();
7342
+ this._groups.delete(group.id);
7343
+ this._onDidRemoveGroup.fire(group);
7344
+ }
7345
+ remove(this._floatingGroups, floatingGroup);
7346
+ floatingGroup.dispose();
7347
+ if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
7348
+ const groups = Array.from(this._groups.values());
7349
+ this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7350
+ }
7351
+ return floatingGroup.group;
6650
7352
  }
6651
- floatingGroup.dispose();
6652
- if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
6653
- const groups = Array.from(this._groups.values());
6654
- this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7353
+ throw new Error('failed to find floating group');
7354
+ }
7355
+ if (group.api.location === 'popout') {
7356
+ const selectedGroup = this._popoutGroups.find((_) => _.group === group);
7357
+ if (selectedGroup) {
7358
+ if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
7359
+ selectedGroup.group.dispose();
7360
+ this._groups.delete(group.id);
7361
+ this._onDidRemoveGroup.fire(group);
7362
+ }
7363
+ selectedGroup.dispose();
7364
+ if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
7365
+ const groups = Array.from(this._groups.values());
7366
+ this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7367
+ }
7368
+ return selectedGroup.group;
6655
7369
  }
6656
- return floatingGroup.group;
7370
+ throw new Error('failed to find popout group');
6657
7371
  }
6658
7372
  return super.doRemoveGroup(group, options);
6659
7373
  }
@@ -6685,8 +7399,7 @@ class DockviewComponent extends BaseGrid {
6685
7399
  const targetLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
6686
7400
  if (sourceGroup && sourceGroup.size < 2) {
6687
7401
  const [targetParentLocation, to] = tail(targetLocation);
6688
- const isFloating = this.floatingGroups.find((x) => x.group === sourceGroup);
6689
- if (!isFloating) {
7402
+ if (sourceGroup.api.location === 'grid') {
6690
7403
  const sourceLocation = getGridLocation(sourceGroup.element);
6691
7404
  const [sourceParentLocation, from] = tail(sourceLocation);
6692
7405
  if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
@@ -6732,12 +7445,25 @@ class DockviewComponent extends BaseGrid {
6732
7445
  }
6733
7446
  }
6734
7447
  else {
6735
- const floatingGroup = this.floatingGroups.find((x) => x.group === sourceGroup);
6736
- if (floatingGroup) {
6737
- floatingGroup.dispose();
6738
- }
6739
- else {
6740
- this.gridview.removeView(getGridLocation(sourceGroup.element));
7448
+ switch (sourceGroup.api.location) {
7449
+ case 'grid':
7450
+ this.gridview.removeView(getGridLocation(sourceGroup.element));
7451
+ break;
7452
+ case 'floating': {
7453
+ const selectedFloatingGroup = this._floatingGroups.find((x) => x.group === sourceGroup);
7454
+ if (!selectedFloatingGroup) {
7455
+ throw new Error('failed to find floating group');
7456
+ }
7457
+ selectedFloatingGroup.dispose();
7458
+ break;
7459
+ }
7460
+ case 'popout': {
7461
+ const selectedPopoutGroup = this._popoutGroups.find((x) => x.group === sourceGroup);
7462
+ if (!selectedPopoutGroup) {
7463
+ throw new Error('failed to find popout group');
7464
+ }
7465
+ selectedPopoutGroup.dispose();
7466
+ }
6741
7467
  }
6742
7468
  const referenceLocation = getGridLocation(referenceGroup.element);
6743
7469
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, target);
@@ -6799,7 +7525,7 @@ class DockviewComponent extends BaseGrid {
6799
7525
  const contentComponent = options.component;
6800
7526
  const tabComponent = (_a = options.tabComponent) !== null && _a !== void 0 ? _a : this.options.defaultTabComponent;
6801
7527
  const view = new DockviewPanelModel(this, options.id, contentComponent, tabComponent);
6802
- const panel = new DockviewPanel(options.id, this, this._api, group, view);
7528
+ const panel = new DockviewPanel(options.id, this, this._api, group, view, { renderer: options.renderer });
6803
7529
  panel.init({
6804
7530
  title: (_b = options.title) !== null && _b !== void 0 ? _b : options.id,
6805
7531
  params: (_c = options === null || options === void 0 ? void 0 : options.params) !== null && _c !== void 0 ? _c : {},
@@ -8145,6 +8871,8 @@ const DockviewReact = React__namespace.forwardRef((props, ref) => {
8145
8871
  singleTabMode: props.singleTabMode,
8146
8872
  disableFloatingGroups: props.disableFloatingGroups,
8147
8873
  floatingGroupBounds: props.floatingGroupBounds,
8874
+ defaultRenderer: props.defaultRenderer,
8875
+ debug: props.debug,
8148
8876
  });
8149
8877
  const { clientWidth, clientHeight } = domRef.current;
8150
8878
  dockview.layout(clientWidth, clientHeight);