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
  */
@@ -256,6 +256,14 @@
256
256
  // noop
257
257
  },
258
258
  };
259
+ function from(func) {
260
+ return {
261
+ dispose: () => {
262
+ func();
263
+ },
264
+ };
265
+ }
266
+ Disposable.from = from;
259
267
  })(Disposable || (Disposable = {}));
260
268
  class CompositeDisposable {
261
269
  get isDisposed() {
@@ -440,6 +448,61 @@
440
448
  function quasiDefaultPrevented(event) {
441
449
  return event[QUASI_PREVENT_DEFAULT_KEY];
442
450
  }
451
+ function addStyles(document, styleSheetList) {
452
+ const styleSheets = Array.from(styleSheetList);
453
+ for (const styleSheet of styleSheets) {
454
+ if (styleSheet.href) {
455
+ const link = document.createElement('link');
456
+ link.href = styleSheet.href;
457
+ link.type = styleSheet.type;
458
+ link.rel = 'stylesheet';
459
+ document.head.appendChild(link);
460
+ }
461
+ let cssTexts = [];
462
+ try {
463
+ if (styleSheet.cssRules) {
464
+ cssTexts = Array.from(styleSheet.cssRules).map((rule) => rule.cssText);
465
+ }
466
+ }
467
+ catch (err) {
468
+ // security errors (lack of permissions), ignore
469
+ }
470
+ for (const rule of cssTexts) {
471
+ const style = document.createElement('style');
472
+ style.appendChild(document.createTextNode(rule));
473
+ document.head.appendChild(style);
474
+ }
475
+ }
476
+ }
477
+ function getDomNodePagePosition(domNode) {
478
+ const { left, top, width, height } = domNode.getBoundingClientRect();
479
+ return {
480
+ left: left + window.scrollX,
481
+ top: top + window.scrollY,
482
+ width: width,
483
+ height: height,
484
+ };
485
+ }
486
+ /**
487
+ * Check whether an element is in the DOM (including the Shadow DOM)
488
+ * @see https://terodox.tech/how-to-tell-if-an-element-is-in-the-dom-including-the-shadow-dom/
489
+ */
490
+ function isInDocument(element) {
491
+ let currentElement = element;
492
+ while (currentElement === null || currentElement === void 0 ? void 0 : currentElement.parentNode) {
493
+ if (currentElement.parentNode === document) {
494
+ return true;
495
+ }
496
+ else if (currentElement.parentNode instanceof DocumentFragment) {
497
+ // handle shadow DOMs
498
+ currentElement = currentElement.parentNode.host;
499
+ }
500
+ else {
501
+ currentElement = currentElement.parentNode;
502
+ }
503
+ }
504
+ return false;
505
+ }
443
506
 
444
507
  function tail(arr) {
445
508
  if (arr.length === 0) {
@@ -637,6 +700,9 @@
637
700
  Sizing.Invisible = Invisible;
638
701
  })(exports.Sizing || (exports.Sizing = {}));
639
702
  class Splitview {
703
+ get contentSize() {
704
+ return this._contentSize;
705
+ }
640
706
  get size() {
641
707
  return this._size;
642
708
  }
@@ -702,7 +768,7 @@
702
768
  this.sashes = [];
703
769
  this._size = 0;
704
770
  this._orthogonalSize = 0;
705
- this.contentSize = 0;
771
+ this._contentSize = 0;
706
772
  this._proportions = undefined;
707
773
  this._startSnappingEnabled = true;
708
774
  this._endSnappingEnabled = true;
@@ -821,7 +887,7 @@
821
887
  );
822
888
  });
823
889
  // Initialize content size and proportions for first layout
824
- this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
890
+ this._contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
825
891
  this.saveProportions();
826
892
  }
827
893
  }
@@ -1095,7 +1161,7 @@
1095
1161
  this.addView(view, sizing, to);
1096
1162
  }
1097
1163
  layout(size, orthogonalSize) {
1098
- const previousSize = Math.max(this.size, this.contentSize);
1164
+ const previousSize = Math.max(this.size, this._contentSize);
1099
1165
  this.size = size;
1100
1166
  this.orthogonalSize = orthogonalSize;
1101
1167
  if (!this.proportions) {
@@ -1105,9 +1171,23 @@
1105
1171
  this.resize(this.viewItems.length - 1, size - previousSize, undefined, lowPriorityIndexes, highPriorityIndexes);
1106
1172
  }
1107
1173
  else {
1174
+ let total = 0;
1175
+ for (let i = 0; i < this.viewItems.length; i++) {
1176
+ const item = this.viewItems[i];
1177
+ const proportion = this.proportions[i];
1178
+ if (typeof proportion === 'number') {
1179
+ total += proportion;
1180
+ }
1181
+ else {
1182
+ size -= item.size;
1183
+ }
1184
+ }
1108
1185
  for (let i = 0; i < this.viewItems.length; i++) {
1109
1186
  const item = this.viewItems[i];
1110
- item.size = clamp(Math.round(this.proportions[i] * size), item.minimumSize, item.maximumSize);
1187
+ const proportion = this.proportions[i];
1188
+ if (typeof proportion === 'number' && total > 0) {
1189
+ item.size = clamp(Math.round((proportion * size) / total), item.minimumSize, item.maximumSize);
1190
+ }
1111
1191
  }
1112
1192
  }
1113
1193
  this.distributeEmptySpace();
@@ -1144,12 +1224,12 @@
1144
1224
  }
1145
1225
  }
1146
1226
  saveProportions() {
1147
- if (this.proportionalLayout && this.contentSize > 0) {
1148
- this._proportions = this.viewItems.map((i) => i.size / this.contentSize);
1227
+ if (this.proportionalLayout && this._contentSize > 0) {
1228
+ this._proportions = this.viewItems.map((i) => i.visible ? i.size / this._contentSize : undefined);
1149
1229
  }
1150
1230
  }
1151
1231
  layoutViews() {
1152
- this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
1232
+ this._contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
1153
1233
  let sum = 0;
1154
1234
  const x = [];
1155
1235
  this.updateSashEnablement();
@@ -1243,7 +1323,7 @@
1243
1323
  }
1244
1324
  else if (snappedAfter &&
1245
1325
  collapsesDown[index] &&
1246
- (position < this.contentSize || this.endSnappingEnabled)) {
1326
+ (position < this._contentSize || this.endSnappingEnabled)) {
1247
1327
  this.updateSash(sash, exports.SashState.MAXIMUM);
1248
1328
  }
1249
1329
  else {
@@ -1532,7 +1612,6 @@
1532
1612
  setVisible(visible) {
1533
1613
  if (this.view.setVisible) {
1534
1614
  this.view.setVisible(visible);
1535
- this._onDidChange.fire({});
1536
1615
  }
1537
1616
  }
1538
1617
  layout(size, orthogonalSize) {
@@ -1564,10 +1643,14 @@
1564
1643
  get minimumSize() {
1565
1644
  return this.children.length === 0
1566
1645
  ? 0
1567
- : Math.max(...this.children.map((c) => c.minimumOrthogonalSize));
1646
+ : Math.max(...this.children.map((c, index) => this.splitview.isViewVisible(index)
1647
+ ? c.minimumOrthogonalSize
1648
+ : 0));
1568
1649
  }
1569
1650
  get maximumSize() {
1570
- return Math.min(...this.children.map((c) => c.maximumOrthogonalSize));
1651
+ return Math.min(...this.children.map((c, index) => this.splitview.isViewVisible(index)
1652
+ ? c.maximumOrthogonalSize
1653
+ : Number.POSITIVE_INFINITY));
1571
1654
  }
1572
1655
  get minimumOrthogonalSize() {
1573
1656
  return this.splitview.minimumSize;
@@ -1625,6 +1708,8 @@
1625
1708
  this.children = [];
1626
1709
  this._onDidChange = new Emitter();
1627
1710
  this.onDidChange = this._onDidChange.event;
1711
+ this._onDidVisibilityChange = new Emitter();
1712
+ this.onDidVisibilityChange = this._onDidVisibilityChange.event;
1628
1713
  this._orthogonalSize = orthogonalSize;
1629
1714
  this._size = size;
1630
1715
  this.element = document.createElement('div');
@@ -1659,7 +1744,7 @@
1659
1744
  styles,
1660
1745
  });
1661
1746
  }
1662
- this.addDisposables(this._onDidChange, this.splitview.onDidSashEnd(() => {
1747
+ this.addDisposables(this._onDidChange, this._onDidVisibilityChange, this.splitview.onDidSashEnd(() => {
1663
1748
  this._onDidChange.fire({});
1664
1749
  }));
1665
1750
  this.setupChildrenEvents();
@@ -1682,7 +1767,15 @@
1682
1767
  if (this.splitview.isViewVisible(index) === visible) {
1683
1768
  return;
1684
1769
  }
1770
+ const wereAllChildrenHidden = this.splitview.contentSize === 0;
1685
1771
  this.splitview.setViewVisible(index, visible);
1772
+ const areAllChildrenHidden = this.splitview.contentSize === 0;
1773
+ // If all children are hidden then the parent should hide the entire splitview
1774
+ // If the entire splitview is hidden then the parent should show the splitview when a child is shown
1775
+ if ((visible && wereAllChildrenHidden) ||
1776
+ (!visible && areAllChildrenHidden)) {
1777
+ this._onDidVisibilityChange.fire(visible);
1778
+ }
1686
1779
  }
1687
1780
  moveChild(from, to) {
1688
1781
  if (from === to) {
@@ -1746,13 +1839,20 @@
1746
1839
  }
1747
1840
  setupChildrenEvents() {
1748
1841
  this._childrenDisposable.dispose();
1749
- this._childrenDisposable = exports.DockviewEvent.any(...this.children.map((c) => c.onDidChange))((e) => {
1842
+ this._childrenDisposable = new CompositeDisposable(exports.DockviewEvent.any(...this.children.map((c) => c.onDidChange))((e) => {
1750
1843
  /**
1751
1844
  * indicate a change has occured to allows any re-rendering but don't bubble
1752
1845
  * event because that was specific to this branch
1753
1846
  */
1754
1847
  this._onDidChange.fire({ size: e.orthogonalSize });
1755
- });
1848
+ }), ...this.children.map((c, i) => {
1849
+ if (c instanceof BranchNode) {
1850
+ return c.onDidVisibilityChange((visible) => {
1851
+ this.setChildVisible(i, visible);
1852
+ });
1853
+ }
1854
+ return Disposable.NONE;
1855
+ }));
1756
1856
  }
1757
1857
  dispose() {
1758
1858
  this._childrenDisposable.dispose();
@@ -1913,7 +2013,69 @@
1913
2013
  get maximumHeight() {
1914
2014
  return this.root.maximumHeight;
1915
2015
  }
2016
+ maximizedView() {
2017
+ var _a;
2018
+ return (_a = this._maximizedNode) === null || _a === void 0 ? void 0 : _a.view;
2019
+ }
2020
+ hasMaximizedView() {
2021
+ return this._maximizedNode !== undefined;
2022
+ }
2023
+ maximizeView(view) {
2024
+ const location = getGridLocation(view.element);
2025
+ const [_, node] = this.getNode(location);
2026
+ if (!(node instanceof LeafNode)) {
2027
+ return;
2028
+ }
2029
+ if (this._maximizedNode === node) {
2030
+ return;
2031
+ }
2032
+ if (this.hasMaximizedView()) {
2033
+ this.exitMaximizedView();
2034
+ }
2035
+ function hideAllViewsBut(parent, exclude) {
2036
+ for (let i = 0; i < parent.children.length; i++) {
2037
+ const child = parent.children[i];
2038
+ if (child instanceof LeafNode) {
2039
+ if (child !== exclude) {
2040
+ parent.setChildVisible(i, false);
2041
+ }
2042
+ }
2043
+ else {
2044
+ hideAllViewsBut(child, exclude);
2045
+ }
2046
+ }
2047
+ }
2048
+ hideAllViewsBut(this.root, node);
2049
+ this._maximizedNode = node;
2050
+ this._onDidMaxmizedNodeChange.fire();
2051
+ }
2052
+ exitMaximizedView() {
2053
+ if (!this._maximizedNode) {
2054
+ return;
2055
+ }
2056
+ function showViewsInReverseOrder(parent) {
2057
+ for (let index = parent.children.length - 1; index >= 0; index--) {
2058
+ const child = parent.children[index];
2059
+ if (child instanceof LeafNode) {
2060
+ parent.setChildVisible(index, true);
2061
+ }
2062
+ else {
2063
+ showViewsInReverseOrder(child);
2064
+ }
2065
+ }
2066
+ }
2067
+ showViewsInReverseOrder(this.root);
2068
+ this._maximizedNode = undefined;
2069
+ this._onDidMaxmizedNodeChange.fire();
2070
+ }
1916
2071
  serialize() {
2072
+ if (this.hasMaximizedView()) {
2073
+ /**
2074
+ * do not persist maximized view state but we must first exit any maximized views
2075
+ * before serialization to ensure the correct dimensions are persisted
2076
+ */
2077
+ this.exitMaximizedView();
2078
+ }
1917
2079
  const root = serializeBranchNode(this.getView(), this.orientation);
1918
2080
  return {
1919
2081
  root,
@@ -1925,7 +2087,9 @@
1925
2087
  dispose() {
1926
2088
  this.disposable.dispose();
1927
2089
  this._onDidChange.dispose();
2090
+ this._onDidMaxmizedNodeChange.dispose();
1928
2091
  this.root.dispose();
2092
+ this._maximizedNode = undefined;
1929
2093
  this.element.remove();
1930
2094
  }
1931
2095
  clear() {
@@ -1966,6 +2130,7 @@
1966
2130
  const oldRoot = this._root;
1967
2131
  if (oldRoot) {
1968
2132
  oldRoot.dispose();
2133
+ this._maximizedNode = undefined;
1969
2134
  this.element.removeChild(oldRoot.element);
1970
2135
  }
1971
2136
  this._root = root;
@@ -2052,9 +2217,12 @@
2052
2217
  constructor(proportionalLayout, styles, orientation) {
2053
2218
  this.proportionalLayout = proportionalLayout;
2054
2219
  this.styles = styles;
2220
+ this._maximizedNode = undefined;
2055
2221
  this.disposable = new MutableDisposable();
2056
2222
  this._onDidChange = new Emitter();
2057
2223
  this.onDidChange = this._onDidChange.event;
2224
+ this._onDidMaxmizedNodeChange = new Emitter();
2225
+ this.onDidMaxmizedNodeChange = this._onDidMaxmizedNodeChange.event;
2058
2226
  this.element = document.createElement('div');
2059
2227
  this.element.className = 'grid-view';
2060
2228
  this.root = new BranchNode(orientation, proportionalLayout, styles, 0, 0);
@@ -2068,6 +2236,9 @@
2068
2236
  return parent.isChildVisible(index);
2069
2237
  }
2070
2238
  setViewVisible(location, visible) {
2239
+ if (this.hasMaximizedView()) {
2240
+ this.exitMaximizedView();
2241
+ }
2071
2242
  const [rest, index] = tail(location);
2072
2243
  const [, parent] = this.getNode(rest);
2073
2244
  if (!(parent instanceof BranchNode)) {
@@ -2076,6 +2247,9 @@
2076
2247
  parent.setChildVisible(index, visible);
2077
2248
  }
2078
2249
  moveView(parentLocation, from, to) {
2250
+ if (this.hasMaximizedView()) {
2251
+ this.exitMaximizedView();
2252
+ }
2079
2253
  const [, parent] = this.getNode(parentLocation);
2080
2254
  if (!(parent instanceof BranchNode)) {
2081
2255
  throw new Error('Invalid location');
@@ -2083,6 +2257,9 @@
2083
2257
  parent.moveChild(from, to);
2084
2258
  }
2085
2259
  addView(view, size, location) {
2260
+ if (this.hasMaximizedView()) {
2261
+ this.exitMaximizedView();
2262
+ }
2086
2263
  const [rest, index] = tail(location);
2087
2264
  const [pathToParent, parent] = this.getNode(rest);
2088
2265
  if (parent instanceof BranchNode) {
@@ -2115,6 +2292,9 @@
2115
2292
  return this.removeView(location, sizing);
2116
2293
  }
2117
2294
  removeView(location, sizing) {
2295
+ if (this.hasMaximizedView()) {
2296
+ this.exitMaximizedView();
2297
+ }
2118
2298
  const [rest, index] = tail(location);
2119
2299
  const [pathToParent, parent] = this.getNode(rest);
2120
2300
  if (!(parent instanceof BranchNode)) {
@@ -2852,6 +3032,24 @@
2852
3032
  moveToPrevious(options) {
2853
3033
  this.component.moveToPrevious(options);
2854
3034
  }
3035
+ maximizeGroup(panel) {
3036
+ this.component.maximizeGroup(panel.group);
3037
+ }
3038
+ hasMaximizedGroup() {
3039
+ return this.component.hasMaximizedGroup();
3040
+ }
3041
+ exitMaxmizedGroup() {
3042
+ this.component.exitMaximizedGroup();
3043
+ }
3044
+ get onDidMaxmizedGroupChange() {
3045
+ return this.component.onDidMaxmizedGroupChange;
3046
+ }
3047
+ /**
3048
+ * Add a popout group in a new Window
3049
+ */
3050
+ addPopoutGroup(item, options) {
3051
+ this.component.addPopoutGroup(item, options);
3052
+ }
2855
3053
  }
2856
3054
 
2857
3055
  class DragAndDropObserver extends CompositeDisposable {
@@ -2862,29 +3060,44 @@
2862
3060
  this.target = null;
2863
3061
  this.registerListeners();
2864
3062
  }
3063
+ onDragEnter(e) {
3064
+ this.target = e.target;
3065
+ this.callbacks.onDragEnter(e);
3066
+ }
3067
+ onDragOver(e) {
3068
+ e.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome)
3069
+ if (this.callbacks.onDragOver) {
3070
+ this.callbacks.onDragOver(e);
3071
+ }
3072
+ }
3073
+ onDragLeave(e) {
3074
+ if (this.target === e.target) {
3075
+ this.target = null;
3076
+ this.callbacks.onDragLeave(e);
3077
+ }
3078
+ }
3079
+ onDragEnd(e) {
3080
+ this.target = null;
3081
+ this.callbacks.onDragEnd(e);
3082
+ }
3083
+ onDrop(e) {
3084
+ this.callbacks.onDrop(e);
3085
+ }
2865
3086
  registerListeners() {
2866
3087
  this.addDisposables(addDisposableListener(this.element, 'dragenter', (e) => {
2867
- this.target = e.target;
2868
- this.callbacks.onDragEnter(e);
3088
+ this.onDragEnter(e);
2869
3089
  }, true));
2870
3090
  this.addDisposables(addDisposableListener(this.element, 'dragover', (e) => {
2871
- e.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome)
2872
- if (this.callbacks.onDragOver) {
2873
- this.callbacks.onDragOver(e);
2874
- }
3091
+ this.onDragOver(e);
2875
3092
  }, true));
2876
3093
  this.addDisposables(addDisposableListener(this.element, 'dragleave', (e) => {
2877
- if (this.target === e.target) {
2878
- this.target = null;
2879
- this.callbacks.onDragLeave(e);
2880
- }
3094
+ this.onDragLeave(e);
2881
3095
  }));
2882
3096
  this.addDisposables(addDisposableListener(this.element, 'dragend', (e) => {
2883
- this.target = null;
2884
- this.callbacks.onDragEnd(e);
3097
+ this.onDragEnd(e);
2885
3098
  }));
2886
3099
  this.addDisposables(addDisposableListener(this.element, 'drop', (e) => {
2887
- this.callbacks.onDrop(e);
3100
+ this.onDrop(e);
2888
3101
  }));
2889
3102
  }
2890
3103
  }
@@ -2936,7 +3149,7 @@
2936
3149
  this.onDrop = this._onDrop.event;
2937
3150
  // use a set to take advantage of #<set>.has
2938
3151
  this._acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
2939
- this.addDisposables(this._onDrop, new DragAndDropObserver(this.element, {
3152
+ this.dnd = new DragAndDropObserver(this.element, {
2940
3153
  onDragEnter: () => undefined,
2941
3154
  onDragOver: (e) => {
2942
3155
  if (this._acceptedTargetZonesSet.size === 0) {
@@ -3003,7 +3216,8 @@
3003
3216
  this._onDrop.fire({ position: state, nativeEvent: e });
3004
3217
  }
3005
3218
  },
3006
- }));
3219
+ });
3220
+ this.addDisposables(this._onDrop, this.dnd);
3007
3221
  }
3008
3222
  setTargetZones(acceptedTargetZones) {
3009
3223
  this._acceptedTargetZonesSet = new Set(acceptedTargetZones);
@@ -3159,12 +3373,22 @@
3159
3373
  return 'center';
3160
3374
  }
3161
3375
 
3376
+ exports.DockviewDropTargets = void 0;
3377
+ (function (DockviewDropTargets) {
3378
+ DockviewDropTargets[DockviewDropTargets["Tab"] = 0] = "Tab";
3379
+ DockviewDropTargets[DockviewDropTargets["Panel"] = 1] = "Panel";
3380
+ DockviewDropTargets[DockviewDropTargets["TabContainer"] = 2] = "TabContainer";
3381
+ DockviewDropTargets[DockviewDropTargets["Edge"] = 3] = "Edge";
3382
+ })(exports.DockviewDropTargets || (exports.DockviewDropTargets = {}));
3383
+
3162
3384
  class ContentContainer extends CompositeDisposable {
3163
3385
  get element() {
3164
3386
  return this._element;
3165
3387
  }
3166
- constructor() {
3388
+ constructor(accessor, group) {
3167
3389
  super();
3390
+ this.accessor = accessor;
3391
+ this.group = group;
3168
3392
  this.disposable = new MutableDisposable();
3169
3393
  this._onDidFocus = new Emitter();
3170
3394
  this.onDidFocus = this._onDidFocus.event;
@@ -3174,11 +3398,38 @@
3174
3398
  this._element.className = 'content-container';
3175
3399
  this._element.tabIndex = -1;
3176
3400
  this.addDisposables(this._onDidFocus, this._onDidBlur);
3177
- // for hosted containers
3178
- // 1) register a drop target on the host
3179
- // 2) register window dragStart events to disable pointer events
3180
- // 3) register dragEnd events
3181
- // 4) register mouseMove events (if no buttons are present we take this as a dragEnd event)
3401
+ this.dropTarget = new Droptarget(this.element, {
3402
+ acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
3403
+ canDisplayOverlay: (event, position) => {
3404
+ if (this.group.locked === 'no-drop-target' ||
3405
+ (this.group.locked && position === 'center')) {
3406
+ return false;
3407
+ }
3408
+ const data = getPanelData();
3409
+ if (!data &&
3410
+ event.shiftKey &&
3411
+ this.group.location !== 'floating') {
3412
+ return false;
3413
+ }
3414
+ if (data && data.viewId === this.accessor.id) {
3415
+ if (data.groupId === this.group.id) {
3416
+ if (position === 'center') {
3417
+ // don't allow to drop on self for center position
3418
+ return false;
3419
+ }
3420
+ if (data.panelId === null) {
3421
+ // don't allow group move to drop anywhere on self
3422
+ return false;
3423
+ }
3424
+ }
3425
+ const groupHasOnePanelAndIsActiveDragElement = this.group.panels.length === 1 &&
3426
+ data.groupId === this.group.id;
3427
+ return !groupHasOnePanelAndIsActiveDragElement;
3428
+ }
3429
+ return this.group.canDisplayOverlay(event, position, exports.DockviewDropTargets.Panel);
3430
+ },
3431
+ });
3432
+ this.addDisposables(this.dropTarget);
3182
3433
  }
3183
3434
  show() {
3184
3435
  this.element.style.display = '';
@@ -3186,23 +3437,43 @@
3186
3437
  hide() {
3187
3438
  this.element.style.display = 'none';
3188
3439
  }
3189
- openPanel(panel) {
3190
- var _a;
3191
- if (this.panel === panel) {
3192
- return;
3193
- }
3194
- if (this.panel) {
3195
- if ((_a = this.panel.view) === null || _a === void 0 ? void 0 : _a.content) {
3196
- this._element.removeChild(this.panel.view.content.element);
3197
- }
3198
- this.panel = undefined;
3440
+ renderPanel(panel, options = { asActive: true }) {
3441
+ const doRender = options.asActive ||
3442
+ (this.panel && this.group.isPanelActive(this.panel));
3443
+ if (this.panel &&
3444
+ this.panel.view.content.element.parentElement === this._element) {
3445
+ /**
3446
+ * If the currently attached panel is mounted directly to the content then remove it
3447
+ */
3448
+ this._element.removeChild(this.panel.view.content.element);
3199
3449
  }
3200
3450
  this.panel = panel;
3201
- const disposable = new CompositeDisposable();
3202
- if (this.panel.view) {
3203
- const _onDidFocus = this.panel.view.content.onDidFocus;
3204
- const _onDidBlur = this.panel.view.content.onDidBlur;
3205
- const focusTracker = trackFocus(this._element);
3451
+ let container;
3452
+ switch (panel.api.renderer) {
3453
+ case 'onlyWhenVisibile':
3454
+ this.accessor.overlayRenderContainer.detatch(panel);
3455
+ if (this.panel) {
3456
+ if (doRender) {
3457
+ this._element.appendChild(this.panel.view.content.element);
3458
+ }
3459
+ }
3460
+ container = this._element;
3461
+ break;
3462
+ case 'always':
3463
+ if (panel.view.content.element.parentElement === this._element) {
3464
+ this._element.removeChild(panel.view.content.element);
3465
+ }
3466
+ container = this.accessor.overlayRenderContainer.attach({
3467
+ panel,
3468
+ referenceContainer: this,
3469
+ });
3470
+ break;
3471
+ }
3472
+ if (doRender) {
3473
+ const _onDidFocus = panel.view.content.onDidFocus;
3474
+ const _onDidBlur = panel.view.content.onDidBlur;
3475
+ const focusTracker = trackFocus(container);
3476
+ const disposable = new CompositeDisposable();
3206
3477
  disposable.addDisposables(focusTracker, focusTracker.onDidFocus(() => this._onDidFocus.fire()), focusTracker.onDidBlur(() => this._onDidBlur.fire()));
3207
3478
  if (_onDidFocus) {
3208
3479
  disposable.addDisposables(_onDidFocus(() => this._onDidFocus.fire()));
@@ -3210,17 +3481,23 @@
3210
3481
  if (_onDidBlur) {
3211
3482
  disposable.addDisposables(_onDidBlur(() => this._onDidBlur.fire()));
3212
3483
  }
3213
- this._element.appendChild(this.panel.view.content.element);
3484
+ this.disposable.value = disposable;
3214
3485
  }
3215
- this.disposable.value = disposable;
3486
+ }
3487
+ openPanel(panel) {
3488
+ if (this.panel === panel) {
3489
+ return;
3490
+ }
3491
+ this.renderPanel(panel);
3216
3492
  }
3217
3493
  layout(_width, _height) {
3218
3494
  // noop
3219
3495
  }
3220
3496
  closePanel() {
3221
- var _a, _b, _c;
3222
- 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) {
3223
- this._element.removeChild(this.panel.view.content.element);
3497
+ if (this.panel) {
3498
+ if (this.accessor.options.defaultRenderer === 'onlyWhenVisibile') {
3499
+ this._element.removeChild(this.panel.view.content.element);
3500
+ }
3224
3501
  this.panel = undefined;
3225
3502
  }
3226
3503
  }
@@ -3230,14 +3507,6 @@
3230
3507
  }
3231
3508
  }
3232
3509
 
3233
- exports.DockviewDropTargets = void 0;
3234
- (function (DockviewDropTargets) {
3235
- DockviewDropTargets[DockviewDropTargets["Tab"] = 0] = "Tab";
3236
- DockviewDropTargets[DockviewDropTargets["Panel"] = 1] = "Panel";
3237
- DockviewDropTargets[DockviewDropTargets["TabContainer"] = 2] = "TabContainer";
3238
- DockviewDropTargets[DockviewDropTargets["Edge"] = 3] = "Edge";
3239
- })(exports.DockviewDropTargets || (exports.DockviewDropTargets = {}));
3240
-
3241
3510
  class DragHandler extends CompositeDisposable {
3242
3511
  constructor(el) {
3243
3512
  super();
@@ -3412,7 +3681,7 @@
3412
3681
  }, true));
3413
3682
  }
3414
3683
  isCancelled(_event) {
3415
- if (this.group.api.isFloating && !_event.shiftKey) {
3684
+ if (this.group.api.location === 'floating' && !_event.shiftKey) {
3416
3685
  return true;
3417
3686
  }
3418
3687
  return false;
@@ -3614,7 +3883,7 @@
3614
3883
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3615
3884
  if (isFloatingGroupsEnabled &&
3616
3885
  event.shiftKey &&
3617
- !this.group.api.isFloating) {
3886
+ this.group.api.location !== 'floating') {
3618
3887
  event.preventDefault();
3619
3888
  const { top, left } = this.element.getBoundingClientRect();
3620
3889
  const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
@@ -3679,7 +3948,7 @@
3679
3948
  }), tab.onChanged((event) => {
3680
3949
  var _a;
3681
3950
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3682
- const isFloatingWithOnePanel = this.group.api.isFloating && this.size === 1;
3951
+ const isFloatingWithOnePanel = this.group.api.location === 'floating' && this.size === 1;
3683
3952
  if (isFloatingGroupsEnabled &&
3684
3953
  !isFloatingWithOnePanel &&
3685
3954
  event.shiftKey) {
@@ -3762,15 +4031,37 @@
3762
4031
  }
3763
4032
  return isAncestor(document.activeElement, this.contentContainer.element);
3764
4033
  }
3765
- get isFloating() {
3766
- return this._isFloating;
3767
- }
3768
- set isFloating(value) {
3769
- this._isFloating = value;
3770
- this.dropTarget.setTargetZones(value ? ['center'] : ['top', 'bottom', 'left', 'right', 'center']);
3771
- toggleClass(this.container, 'dv-groupview-floating', value);
3772
- this.groupPanel.api._onDidFloatingStateChange.fire({
3773
- isFloating: this.isFloating,
4034
+ get location() {
4035
+ return this._location;
4036
+ }
4037
+ set location(value) {
4038
+ this._location = value;
4039
+ toggleClass(this.container, 'dv-groupview-floating', false);
4040
+ toggleClass(this.container, 'dv-groupview-popout', false);
4041
+ switch (value) {
4042
+ case 'grid':
4043
+ this.contentContainer.dropTarget.setTargetZones([
4044
+ 'top',
4045
+ 'bottom',
4046
+ 'left',
4047
+ 'right',
4048
+ 'center',
4049
+ ]);
4050
+ break;
4051
+ case 'floating':
4052
+ this.contentContainer.dropTarget.setTargetZones(['center']);
4053
+ this.contentContainer.dropTarget.setTargetZones(value
4054
+ ? ['center']
4055
+ : ['top', 'bottom', 'left', 'right', 'center']);
4056
+ toggleClass(this.container, 'dv-groupview-floating', true);
4057
+ break;
4058
+ case 'popout':
4059
+ this.contentContainer.dropTarget.setTargetZones(['center']);
4060
+ toggleClass(this.container, 'dv-groupview-popout', true);
4061
+ break;
4062
+ }
4063
+ this.groupPanel.api._onDidLocationChange.fire({
4064
+ location: this.location,
3774
4065
  });
3775
4066
  }
3776
4067
  constructor(container, accessor, id, options, groupPanel) {
@@ -3783,7 +4074,7 @@
3783
4074
  this.groupPanel = groupPanel;
3784
4075
  this._isGroupActive = false;
3785
4076
  this._locked = false;
3786
- this._isFloating = false;
4077
+ this._location = 'grid';
3787
4078
  this.mostRecentlyUsed = [];
3788
4079
  this._onDidChange = new Emitter();
3789
4080
  this.onDidChange = this._onDidChange.event;
@@ -3806,35 +4097,7 @@
3806
4097
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
3807
4098
  toggleClass(this.container, 'groupview', true);
3808
4099
  this.tabsContainer = new TabsContainer(this.accessor, this.groupPanel);
3809
- this.contentContainer = new ContentContainer();
3810
- this.dropTarget = new Droptarget(this.contentContainer.element, {
3811
- acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
3812
- canDisplayOverlay: (event, position) => {
3813
- if (this.locked === 'no-drop-target' ||
3814
- (this.locked && position === 'center')) {
3815
- return false;
3816
- }
3817
- const data = getPanelData();
3818
- if (!data && event.shiftKey && !this.isFloating) {
3819
- return false;
3820
- }
3821
- if (data && data.viewId === this.accessor.id) {
3822
- if (data.groupId === this.id) {
3823
- if (position === 'center') {
3824
- // don't allow to drop on self for center position
3825
- return false;
3826
- }
3827
- if (data.panelId === null) {
3828
- // don't allow group move to drop anywhere on self
3829
- return false;
3830
- }
3831
- }
3832
- const groupHasOnePanelAndIsActiveDragElement = this._panels.length === 1 && data.groupId === this.id;
3833
- return !groupHasOnePanelAndIsActiveDragElement;
3834
- }
3835
- return this.canDisplayOverlay(event, position, exports.DockviewDropTargets.Panel);
3836
- },
3837
- });
4100
+ this.contentContainer = new ContentContainer(this.accessor, this);
3838
4101
  container.append(this.tabsContainer.element, this.contentContainer.element);
3839
4102
  this.header.hidden = !!options.hideHeader;
3840
4103
  this.locked = (_a = options.locked) !== null && _a !== void 0 ? _a : false;
@@ -3848,7 +4111,7 @@
3848
4111
  this.accessor.doSetGroupActive(this.groupPanel, true);
3849
4112
  }), this.contentContainer.onDidBlur(() => {
3850
4113
  // noop
3851
- }), this.dropTarget.onDrop((event) => {
4114
+ }), this.contentContainer.dropTarget.onDrop((event) => {
3852
4115
  this.handleDropEvent(event.nativeEvent, event.position);
3853
4116
  }), this._onMove, this._onDidChange, this._onDidDrop, this._onDidAddPanel, this._onDidRemovePanel, this._onDidActivePanelChange);
3854
4117
  }
@@ -3897,6 +4160,9 @@
3897
4160
  this.tabsContainer.setPrefixActionsElement(this._prefixHeaderActions.element);
3898
4161
  }
3899
4162
  }
4163
+ rerender(panel) {
4164
+ this.contentContainer.renderPanel(panel, { asActive: false });
4165
+ }
3900
4166
  indexOf(panel) {
3901
4167
  return this.tabsContainer.indexOf(panel.id);
3902
4168
  }
@@ -4088,12 +4354,12 @@
4088
4354
  doAddPanel(panel, index = this.panels.length, skipSetActive = false) {
4089
4355
  const existingPanel = this._panels.indexOf(panel);
4090
4356
  const hasExistingPanel = existingPanel > -1;
4357
+ this.tabsContainer.show();
4358
+ this.contentContainer.show();
4091
4359
  this.tabsContainer.openPanel(panel, index);
4092
4360
  if (!skipSetActive) {
4093
4361
  this.contentContainer.openPanel(panel);
4094
4362
  }
4095
- this.tabsContainer.show();
4096
- this.contentContainer.show();
4097
4363
  if (hasExistingPanel) {
4098
4364
  // TODO - need to ensure ordering hasn't changed and if it has need to re-order this.panels
4099
4365
  return;
@@ -4209,7 +4475,6 @@
4209
4475
  for (const panel of this.panels) {
4210
4476
  panel.dispose();
4211
4477
  }
4212
- this.dropTarget.dispose();
4213
4478
  this.tabsContainer.dispose();
4214
4479
  this.contentContainer.dispose();
4215
4480
  }
@@ -4248,7 +4513,7 @@
4248
4513
  if (this.disableResizing) {
4249
4514
  return;
4250
4515
  }
4251
- if (!document.body.contains(this._element)) {
4516
+ if (!isInDocument(this._element)) {
4252
4517
  /**
4253
4518
  * since the event is dispatched through requestAnimationFrame there is a small chance
4254
4519
  * the component is no longer attached to the DOM, if that is the case the dimensions
@@ -4340,6 +4605,21 @@
4340
4605
  isVisible(panel) {
4341
4606
  return this.gridview.isViewVisible(getGridLocation(panel.element));
4342
4607
  }
4608
+ maximizeGroup(panel) {
4609
+ this.gridview.maximizeView(panel);
4610
+ }
4611
+ isMaximizedGroup(panel) {
4612
+ return this.gridview.maximizedView() === panel;
4613
+ }
4614
+ exitMaximizedGroup() {
4615
+ this.gridview.exitMaximizedView();
4616
+ }
4617
+ hasMaximizedGroup() {
4618
+ return this.gridview.hasMaximizedView();
4619
+ }
4620
+ get onDidMaxmizedGroupChange() {
4621
+ return this.gridview.onDidMaxmizedNodeChange;
4622
+ }
4343
4623
  doAddGroup(group, location = [0], size) {
4344
4624
  this.gridview.addView(group, size !== null && size !== void 0 ? size : exports.Sizing.Distribute, location);
4345
4625
  this._onDidAddGroup.fire(group);
@@ -5116,32 +5396,63 @@
5116
5396
  }
5117
5397
  }
5118
5398
 
5399
+ // TODO find a better way to initialize and avoid needing null checks
5400
+ const NOT_INITIALIZED_MESSAGE = 'DockviewGroupPanelApiImpl not initialized';
5119
5401
  class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
5120
- get isFloating() {
5402
+ get location() {
5121
5403
  if (!this._group) {
5122
- throw new Error(`DockviewGroupPanelApiImpl not initialized`);
5404
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5123
5405
  }
5124
- return this._group.model.isFloating;
5406
+ return this._group.model.location;
5125
5407
  }
5126
5408
  constructor(id, accessor) {
5127
5409
  super(id);
5128
5410
  this.accessor = accessor;
5129
- this._onDidFloatingStateChange = new Emitter();
5130
- this.onDidFloatingStateChange = this._onDidFloatingStateChange.event;
5131
- this.addDisposables(this._onDidFloatingStateChange);
5411
+ this._onDidLocationChange = new Emitter();
5412
+ this.onDidLocationChange = this._onDidLocationChange.event;
5413
+ this.addDisposables(this._onDidLocationChange);
5132
5414
  }
5133
5415
  moveTo(options) {
5134
- var _a;
5416
+ var _a, _b, _c;
5417
+ if (!this._group) {
5418
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5419
+ }
5420
+ const group = (_a = options.group) !== null && _a !== void 0 ? _a : this.accessor.addGroup({
5421
+ direction: positionToDirection((_b = options.position) !== null && _b !== void 0 ? _b : 'right'),
5422
+ });
5423
+ this.accessor.moveGroupOrPanel(group, this._group.id, undefined, options.group ? (_c = options.position) !== null && _c !== void 0 ? _c : 'center' : 'center');
5424
+ }
5425
+ maximize() {
5426
+ if (!this._group) {
5427
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5428
+ }
5429
+ if (this.location !== 'grid') {
5430
+ // only grid groups can be maximized
5431
+ return;
5432
+ }
5433
+ this.accessor.maximizeGroup(this._group);
5434
+ }
5435
+ isMaximized() {
5135
5436
  if (!this._group) {
5136
- throw new Error(`DockviewGroupPanelApiImpl not initialized`);
5437
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5438
+ }
5439
+ return this.accessor.isMaximizedGroup(this._group);
5440
+ }
5441
+ exitMaximized() {
5442
+ if (!this._group) {
5443
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5444
+ }
5445
+ if (this.isMaximized()) {
5446
+ this.accessor.exitMaximizedGroup();
5137
5447
  }
5138
- this.accessor.moveGroupOrPanel(options.group, this._group.id, undefined, (_a = options.position) !== null && _a !== void 0 ? _a : 'center');
5139
5448
  }
5140
5449
  initialize(group) {
5141
5450
  this._group = group;
5142
5451
  }
5143
5452
  }
5144
5453
 
5454
+ const MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH = 100;
5455
+ const MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT = 100;
5145
5456
  class DockviewGroupPanel extends GridviewPanel {
5146
5457
  get panels() {
5147
5458
  return this._model.panels;
@@ -5166,8 +5477,8 @@
5166
5477
  }
5167
5478
  constructor(accessor, id, options) {
5168
5479
  super(id, 'groupview_default', {
5169
- minimumHeight: 100,
5170
- minimumWidth: 100,
5480
+ minimumHeight: MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT,
5481
+ minimumWidth: MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH,
5171
5482
  }, new DockviewGroupPanelApiImpl(id, accessor));
5172
5483
  this.api.initialize(this); // cannot use 'this' after after 'super' call
5173
5484
  this._model = new DockviewGroupPanelModel(this.element, accessor, id, options, this);
@@ -5221,8 +5532,10 @@
5221
5532
  return this.panel.title;
5222
5533
  }
5223
5534
  get isGroupActive() {
5224
- var _a;
5225
- return !!((_a = this.group) === null || _a === void 0 ? void 0 : _a.isActive);
5535
+ return this.group.isActive;
5536
+ }
5537
+ get renderer() {
5538
+ return this.panel.renderer;
5226
5539
  }
5227
5540
  set group(value) {
5228
5541
  const isOldGroupActive = this.isGroupActive;
@@ -5250,10 +5563,12 @@
5250
5563
  this.onDidActiveGroupChange = this._onDidActiveGroupChange.event;
5251
5564
  this._onDidGroupChange = new Emitter();
5252
5565
  this.onDidGroupChange = this._onDidGroupChange.event;
5566
+ this._onDidRendererChange = new Emitter();
5567
+ this.onDidRendererChange = this._onDidRendererChange.event;
5253
5568
  this.disposable = new MutableDisposable();
5254
5569
  this.initialize(panel);
5255
5570
  this._group = group;
5256
- this.addDisposables(this.disposable, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange);
5571
+ this.addDisposables(this.disposable, this._onDidRendererChange, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange);
5257
5572
  }
5258
5573
  moveTo(options) {
5259
5574
  var _a;
@@ -5262,9 +5577,21 @@
5262
5577
  setTitle(title) {
5263
5578
  this.panel.setTitle(title);
5264
5579
  }
5580
+ setRenderer(renderer) {
5581
+ this.panel.setRenderer(renderer);
5582
+ }
5265
5583
  close() {
5266
5584
  this.group.model.closePanel(this.panel);
5267
5585
  }
5586
+ maximize() {
5587
+ this.group.api.maximize();
5588
+ }
5589
+ isMaximized() {
5590
+ return this.group.api.isMaximized();
5591
+ }
5592
+ exitMaximized() {
5593
+ this.group.api.exitMaximized();
5594
+ }
5268
5595
  }
5269
5596
 
5270
5597
  class DockviewPanel extends CompositeDisposable {
@@ -5277,11 +5604,17 @@
5277
5604
  get group() {
5278
5605
  return this._group;
5279
5606
  }
5280
- constructor(id, accessor, containerApi, group, view) {
5607
+ get renderer() {
5608
+ var _a;
5609
+ return (_a = this._renderer) !== null && _a !== void 0 ? _a : this.accessor.renderer;
5610
+ }
5611
+ constructor(id, accessor, containerApi, group, view, options) {
5281
5612
  super();
5282
5613
  this.id = id;
5614
+ this.accessor = accessor;
5283
5615
  this.containerApi = containerApi;
5284
5616
  this.view = view;
5617
+ this._renderer = options.renderer;
5285
5618
  this._group = group;
5286
5619
  this.api = new DockviewPanelApiImpl(this, this._group, accessor);
5287
5620
  this.addDisposables(this.api.onActiveChange(() => {
@@ -5290,6 +5623,8 @@
5290
5623
  // forward the resize event to the group since if you want to resize a panel
5291
5624
  // you are actually just resizing the panels parent which is the group
5292
5625
  this.group.api.setSize(event);
5626
+ }), this.api.onDidRendererChange((event) => {
5627
+ this.group.model.rerender(this);
5293
5628
  }));
5294
5629
  }
5295
5630
  init(params) {
@@ -5309,6 +5644,7 @@
5309
5644
  ? this._params
5310
5645
  : undefined,
5311
5646
  title: this.title,
5647
+ renderer: this._renderer,
5312
5648
  };
5313
5649
  }
5314
5650
  setTitle(title) {
@@ -5324,6 +5660,15 @@
5324
5660
  this.api._onDidTitleChange.fire({ title });
5325
5661
  }
5326
5662
  }
5663
+ setRenderer(renderer) {
5664
+ const didChange = renderer !== this.renderer;
5665
+ if (didChange) {
5666
+ this._renderer = renderer;
5667
+ this.api._onDidRendererChange.fire({
5668
+ renderer: renderer,
5669
+ });
5670
+ }
5671
+ }
5327
5672
  update(event) {
5328
5673
  var _a;
5329
5674
  // merge the new parameters with the existing parameters
@@ -5542,8 +5887,8 @@
5542
5887
  }
5543
5888
 
5544
5889
  class DefaultDockviewDeserialzier {
5545
- constructor(layout) {
5546
- this.layout = layout;
5890
+ constructor(accessor) {
5891
+ this.accessor = accessor;
5547
5892
  }
5548
5893
  fromJSON(panelData, group) {
5549
5894
  var _a, _b;
@@ -5557,8 +5902,10 @@
5557
5902
  const tabComponent = viewData
5558
5903
  ? (_b = viewData.tab) === null || _b === void 0 ? void 0 : _b.id
5559
5904
  : panelData.tabComponent;
5560
- const view = new DockviewPanelModel(this.layout, panelId, contentComponent, tabComponent);
5561
- const panel = new DockviewPanel(panelId, this.layout, new DockviewApi(this.layout), group, view);
5905
+ const view = new DockviewPanelModel(this.accessor, panelId, contentComponent, tabComponent);
5906
+ const panel = new DockviewPanel(panelId, this.accessor, new DockviewApi(this.accessor), group, view, {
5907
+ renderer: panelData.renderer,
5908
+ });
5562
5909
  panel.init({
5563
5910
  title: title !== null && title !== void 0 ? title : panelId,
5564
5911
  params: params !== null && params !== void 0 ? params : {},
@@ -5938,7 +6285,261 @@
5938
6285
  }
5939
6286
  }
5940
6287
 
6288
+ class PopoutWindow extends CompositeDisposable {
6289
+ constructor(id, className, options) {
6290
+ super();
6291
+ this.id = id;
6292
+ this.className = className;
6293
+ this.options = options;
6294
+ this._onDidClose = new Emitter();
6295
+ this.onDidClose = this._onDidClose.event;
6296
+ this._window = null;
6297
+ this.addDisposables(this._onDidClose, {
6298
+ dispose: () => {
6299
+ this.close();
6300
+ },
6301
+ });
6302
+ }
6303
+ dimensions() {
6304
+ if (!this._window) {
6305
+ return null;
6306
+ }
6307
+ const left = this._window.value.screenX;
6308
+ const top = this._window.value.screenY;
6309
+ const width = this._window.value.innerWidth;
6310
+ const height = this._window.value.innerHeight;
6311
+ return { top, left, width, height };
6312
+ }
6313
+ close() {
6314
+ if (this._window) {
6315
+ this._window.disposable.dispose();
6316
+ this._window.value.close();
6317
+ this._window = null;
6318
+ }
6319
+ }
6320
+ open(content) {
6321
+ if (this._window) {
6322
+ throw new Error('instance of popout window is already open');
6323
+ }
6324
+ const url = `${this.options.url}`;
6325
+ const features = Object.entries({
6326
+ top: this.options.top,
6327
+ left: this.options.left,
6328
+ width: this.options.width,
6329
+ height: this.options.height,
6330
+ })
6331
+ .map(([key, value]) => `${key}=${value}`)
6332
+ .join(',');
6333
+ // https://developer.mozilla.org/en-US/docs/Web/API/Window/open
6334
+ const externalWindow = window.open(url, this.id, features);
6335
+ if (!externalWindow) {
6336
+ return;
6337
+ }
6338
+ const disposable = new CompositeDisposable();
6339
+ this._window = { value: externalWindow, disposable };
6340
+ const cleanUp = () => {
6341
+ this._onDidClose.fire();
6342
+ this._window = null;
6343
+ };
6344
+ // prevent any default content from loading
6345
+ // externalWindow.document.body.replaceWith(document.createElement('div'));
6346
+ disposable.addDisposables(addDisposableWindowListener(window, 'beforeunload', () => {
6347
+ cleanUp();
6348
+ this.close();
6349
+ }));
6350
+ externalWindow.addEventListener('load', () => {
6351
+ const externalDocument = externalWindow.document;
6352
+ externalDocument.title = document.title;
6353
+ const div = document.createElement('div');
6354
+ div.classList.add('dv-popout-window');
6355
+ div.style.position = 'absolute';
6356
+ div.style.width = '100%';
6357
+ div.style.height = '100%';
6358
+ div.style.top = '0px';
6359
+ div.style.left = '0px';
6360
+ div.classList.add(this.className);
6361
+ div.appendChild(content);
6362
+ externalDocument.body.replaceChildren(div);
6363
+ externalDocument.body.classList.add(this.className);
6364
+ addStyles(externalDocument, window.document.styleSheets);
6365
+ externalWindow.addEventListener('beforeunload', () => {
6366
+ // TODO: indicate external window is closing
6367
+ cleanUp();
6368
+ });
6369
+ });
6370
+ }
6371
+ }
6372
+
6373
+ class DockviewPopoutGroupPanel extends CompositeDisposable {
6374
+ constructor(id, group, options) {
6375
+ var _a;
6376
+ super();
6377
+ this.id = id;
6378
+ this.group = group;
6379
+ this.options = options;
6380
+ this.window = new PopoutWindow(id, (_a = options.className) !== null && _a !== void 0 ? _a : '', {
6381
+ url: this.options.popoutUrl,
6382
+ left: this.options.box.left,
6383
+ top: this.options.box.top,
6384
+ width: this.options.box.width,
6385
+ height: this.options.box.height,
6386
+ });
6387
+ group.model.location = 'popout';
6388
+ this.addDisposables(this.window, {
6389
+ dispose: () => {
6390
+ group.model.location = 'grid';
6391
+ },
6392
+ }, this.window.onDidClose(() => {
6393
+ this.dispose();
6394
+ }));
6395
+ this.window.open(group.element);
6396
+ }
6397
+ }
6398
+
5941
6399
  const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100;
6400
+ const DEFAULT_FLOATING_GROUP_POSITION = { left: 100, top: 100 };
6401
+
6402
+ function createFocusableElement() {
6403
+ const element = document.createElement('div');
6404
+ element.tabIndex = -1;
6405
+ return element;
6406
+ }
6407
+ class OverlayRenderContainer extends CompositeDisposable {
6408
+ constructor(element) {
6409
+ super();
6410
+ this.element = element;
6411
+ this.map = {};
6412
+ this.addDisposables(Disposable.from(() => {
6413
+ for (const value of Object.values(this.map)) {
6414
+ value.disposable.dispose();
6415
+ value.destroy.dispose();
6416
+ }
6417
+ }));
6418
+ }
6419
+ detatch(panel) {
6420
+ if (this.map[panel.api.id]) {
6421
+ const { disposable, destroy } = this.map[panel.api.id];
6422
+ disposable.dispose();
6423
+ destroy.dispose();
6424
+ delete this.map[panel.api.id];
6425
+ return true;
6426
+ }
6427
+ return false;
6428
+ }
6429
+ attach(options) {
6430
+ const { panel, referenceContainer } = options;
6431
+ if (!this.map[panel.api.id]) {
6432
+ const element = createFocusableElement();
6433
+ element.className = 'dv-render-overlay';
6434
+ this.map[panel.api.id] = {
6435
+ panel,
6436
+ disposable: Disposable.NONE,
6437
+ destroy: Disposable.NONE,
6438
+ element,
6439
+ };
6440
+ }
6441
+ const focusContainer = this.map[panel.api.id].element;
6442
+ if (panel.view.content.element.parentElement !== focusContainer) {
6443
+ focusContainer.appendChild(panel.view.content.element);
6444
+ }
6445
+ if (focusContainer.parentElement !== this.element) {
6446
+ this.element.appendChild(focusContainer);
6447
+ }
6448
+ const resize = () => {
6449
+ // TODO propagate position to avoid getDomNodePagePosition calls, possible performance bottleneck?
6450
+ const box = getDomNodePagePosition(referenceContainer.element);
6451
+ const box2 = getDomNodePagePosition(this.element);
6452
+ focusContainer.style.left = `${box.left - box2.left}px`;
6453
+ focusContainer.style.top = `${box.top - box2.top}px`;
6454
+ focusContainer.style.width = `${box.width}px`;
6455
+ focusContainer.style.height = `${box.height}px`;
6456
+ toggleClass(focusContainer, 'dv-render-overlay-float', panel.group.api.location === 'floating');
6457
+ };
6458
+ const visibilityChanged = () => {
6459
+ if (panel.api.isVisible) {
6460
+ resize();
6461
+ }
6462
+ focusContainer.style.display = panel.api.isVisible ? '' : 'none';
6463
+ };
6464
+ const disposable = new CompositeDisposable(
6465
+ /**
6466
+ * since container is positioned absoutely we must explicitly forward
6467
+ * the dnd events for the expect behaviours to continue to occur in terms of dnd
6468
+ *
6469
+ * the dnd observer does not need to be conditional on whether the panel is visible since
6470
+ * non-visible panels are 'display: none' and in such case the dnd observer will not fire.
6471
+ */
6472
+ new DragAndDropObserver(focusContainer, {
6473
+ onDragEnd: (e) => {
6474
+ referenceContainer.dropTarget.dnd.onDragEnd(e);
6475
+ },
6476
+ onDragEnter: (e) => {
6477
+ referenceContainer.dropTarget.dnd.onDragEnter(e);
6478
+ },
6479
+ onDragLeave: (e) => {
6480
+ referenceContainer.dropTarget.dnd.onDragLeave(e);
6481
+ },
6482
+ onDrop: (e) => {
6483
+ referenceContainer.dropTarget.dnd.onDrop(e);
6484
+ },
6485
+ onDragOver: (e) => {
6486
+ referenceContainer.dropTarget.dnd.onDragOver(e);
6487
+ },
6488
+ }), panel.api.onDidVisibilityChange((event) => {
6489
+ /**
6490
+ * Control the visibility of the content, however even when not visible (display: none)
6491
+ * the content is still maintained within the DOM hence DOM specific attributes
6492
+ * such as scroll position are maintained when next made visible.
6493
+ */
6494
+ visibilityChanged();
6495
+ }), panel.api.onDidDimensionsChange(() => {
6496
+ if (!panel.api.isVisible) {
6497
+ return;
6498
+ }
6499
+ resize();
6500
+ }));
6501
+ this.map[panel.api.id].destroy = Disposable.from(() => {
6502
+ focusContainer.removeChild(panel.view.content.element);
6503
+ this.element.removeChild(focusContainer);
6504
+ });
6505
+ queueMicrotask(() => {
6506
+ if (this.isDisposed) {
6507
+ return;
6508
+ }
6509
+ /**
6510
+ * wait until everything has finished in the current stack-frame call before
6511
+ * calling the first resize as other size-altering events may still occur before
6512
+ * the end of the stack-frame.
6513
+ */
6514
+ visibilityChanged();
6515
+ });
6516
+ // dispose of logic asoccciated with previous reference-container
6517
+ this.map[panel.api.id].disposable.dispose();
6518
+ // and reset the disposable to the active reference-container
6519
+ this.map[panel.api.id].disposable = disposable;
6520
+ return focusContainer;
6521
+ }
6522
+ }
6523
+
6524
+ function getTheme(element) {
6525
+ function toClassList(element) {
6526
+ const list = [];
6527
+ for (let i = 0; i < element.classList.length; i++) {
6528
+ list.push(element.classList.item(i));
6529
+ }
6530
+ return list;
6531
+ }
6532
+ let theme = undefined;
6533
+ let parent = element;
6534
+ while (parent !== null) {
6535
+ theme = toClassList(parent).find((cls) => cls.startsWith('dockview-theme-'));
6536
+ if (typeof theme === 'string') {
6537
+ break;
6538
+ }
6539
+ parent = parent.parentElement;
6540
+ }
6541
+ return theme;
6542
+ }
5942
6543
  class DockviewComponent extends BaseGrid {
5943
6544
  get orientation() {
5944
6545
  return this.gridview.orientation;
@@ -5959,6 +6560,10 @@
5959
6560
  }
5960
6561
  return activeGroup.activePanel;
5961
6562
  }
6563
+ get renderer() {
6564
+ var _a;
6565
+ return (_a = this.options.defaultRenderer) !== null && _a !== void 0 ? _a : 'onlyWhenVisibile';
6566
+ }
5962
6567
  constructor(options) {
5963
6568
  var _a;
5964
6569
  super({
@@ -5985,12 +6590,27 @@
5985
6590
  this.onDidLayoutFromJSON = this._onDidLayoutFromJSON.event;
5986
6591
  this._onDidActivePanelChange = new Emitter();
5987
6592
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
5988
- this.floatingGroups = [];
6593
+ this._floatingGroups = [];
6594
+ this._popoutGroups = [];
6595
+ const gready = document.createElement('div');
6596
+ gready.className = 'dv-overlay-render-container';
6597
+ this.gridview.element.appendChild(gready);
6598
+ this.overlayRenderContainer = new OverlayRenderContainer(gready);
5989
6599
  toggleClass(this.gridview.element, 'dv-dockview', true);
5990
- this.addDisposables(this._onWillDragPanel, this._onWillDragGroup, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
6600
+ toggleClass(this.element, 'dv-debug', !!options.debug);
6601
+ 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)(() => {
5991
6602
  this.updateWatermark();
5992
6603
  }), exports.DockviewEvent.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => {
5993
6604
  this._bufferOnDidLayoutChange.fire();
6605
+ }), Disposable.from(() => {
6606
+ // iterate over a copy of the array since .dispose() mutates the original array
6607
+ for (const group of [...this._floatingGroups]) {
6608
+ group.dispose();
6609
+ }
6610
+ // iterate over a copy of the array since .dispose() mutates the original array
6611
+ for (const group of [...this._popoutGroups]) {
6612
+ group.dispose();
6613
+ }
5994
6614
  }));
5995
6615
  this._options = options;
5996
6616
  if (!this.options.components) {
@@ -6060,6 +6680,55 @@
6060
6680
  this._api = new DockviewApi(this);
6061
6681
  this.updateWatermark();
6062
6682
  }
6683
+ addPopoutGroup(item, options) {
6684
+ var _a;
6685
+ let group;
6686
+ let box = options === null || options === void 0 ? void 0 : options.position;
6687
+ if (item instanceof DockviewPanel) {
6688
+ group = this.createGroup();
6689
+ this.removePanel(item, {
6690
+ removeEmptyGroup: true,
6691
+ skipDispose: true,
6692
+ });
6693
+ group.model.openPanel(item);
6694
+ if (!box) {
6695
+ box = this.element.getBoundingClientRect();
6696
+ }
6697
+ }
6698
+ else {
6699
+ group = item;
6700
+ if (!box) {
6701
+ box = group.element.getBoundingClientRect();
6702
+ }
6703
+ const skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' &&
6704
+ options.skipRemoveGroup;
6705
+ if (!skip) {
6706
+ this.doRemoveGroup(item, { skipDispose: true });
6707
+ }
6708
+ }
6709
+ const theme = getTheme(this.gridview.element);
6710
+ const popoutWindow = new DockviewPopoutGroupPanel(`${this.id}-${group.id}`, // globally unique within dockview
6711
+ group, {
6712
+ className: theme !== null && theme !== void 0 ? theme : '',
6713
+ popoutUrl: (_a = options === null || options === void 0 ? void 0 : options.popoutUrl) !== null && _a !== void 0 ? _a : '/popout.html',
6714
+ box: {
6715
+ left: window.screenX + box.left,
6716
+ top: window.screenY + box.top,
6717
+ width: box.width,
6718
+ height: box.height,
6719
+ },
6720
+ });
6721
+ popoutWindow.addDisposables({
6722
+ dispose: () => {
6723
+ remove(this._popoutGroups, popoutWindow);
6724
+ this.updateWatermark();
6725
+ },
6726
+ }, popoutWindow.window.onDidClose(() => {
6727
+ this.doAddGroup(group, [0]);
6728
+ }));
6729
+ this._popoutGroups.push(popoutWindow);
6730
+ this.updateWatermark();
6731
+ }
6063
6732
  addFloatingGroup(item, coord, options) {
6064
6733
  var _a, _b, _c, _d, _e, _f;
6065
6734
  let group;
@@ -6079,9 +6748,13 @@
6079
6748
  this.doRemoveGroup(item, { skipDispose: true });
6080
6749
  }
6081
6750
  }
6082
- group.model.isFloating = true;
6083
- const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number' ? Math.max(coord.x, 0) : 100;
6084
- const overlayTop = typeof (coord === null || coord === void 0 ? void 0 : coord.y) === 'number' ? Math.max(coord.y, 0) : 100;
6751
+ group.model.location = 'floating';
6752
+ const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number'
6753
+ ? Math.max(coord.x, 0)
6754
+ : DEFAULT_FLOATING_GROUP_POSITION.left;
6755
+ const overlayTop = typeof (coord === null || coord === void 0 ? void 0 : coord.y) === 'number'
6756
+ ? Math.max(coord.y, 0)
6757
+ : DEFAULT_FLOATING_GROUP_POSITION.top;
6085
6758
  const overlay = new Overlay({
6086
6759
  container: this.gridview.element,
6087
6760
  content: group.element,
@@ -6125,12 +6798,12 @@
6125
6798
  }), {
6126
6799
  dispose: () => {
6127
6800
  disposable.dispose();
6128
- group.model.isFloating = false;
6129
- remove(this.floatingGroups, floatingGroupPanel);
6801
+ group.model.location = 'grid';
6802
+ remove(this._floatingGroups, floatingGroupPanel);
6130
6803
  this.updateWatermark();
6131
6804
  },
6132
6805
  });
6133
- this.floatingGroups.push(floatingGroupPanel);
6806
+ this._floatingGroups.push(floatingGroupPanel);
6134
6807
  this.updateWatermark();
6135
6808
  }
6136
6809
  orthogonalize(position) {
@@ -6175,7 +6848,7 @@
6175
6848
  this.gridview.orientation = options.orientation;
6176
6849
  }
6177
6850
  if (hasFloatingGroupOptionsChanged) {
6178
- for (const group of this.floatingGroups) {
6851
+ for (const group of this._floatingGroups) {
6179
6852
  switch (this.options.floatingGroupBounds) {
6180
6853
  case 'boundedWithinViewport':
6181
6854
  group.overlay.minimumInViewportHeight = undefined;
@@ -6200,8 +6873,8 @@
6200
6873
  }
6201
6874
  layout(width, height, forceResize) {
6202
6875
  super.layout(width, height, forceResize);
6203
- if (this.floatingGroups) {
6204
- for (const floating of this.floatingGroups) {
6876
+ if (this._floatingGroups) {
6877
+ for (const floating of this._floatingGroups) {
6205
6878
  // ensure floting groups stay within visible boundaries
6206
6879
  floating.overlay.setBounds();
6207
6880
  }
@@ -6269,10 +6942,16 @@
6269
6942
  collection[panel.id] = panel.toJSON();
6270
6943
  return collection;
6271
6944
  }, {});
6272
- const floats = this.floatingGroups.map((floatingGroup) => {
6945
+ const floats = this._floatingGroups.map((group) => {
6946
+ return {
6947
+ data: group.group.toJSON(),
6948
+ position: group.overlay.toJSON(),
6949
+ };
6950
+ });
6951
+ const popoutGroups = this._popoutGroups.map((group) => {
6273
6952
  return {
6274
- data: floatingGroup.group.toJSON(),
6275
- position: floatingGroup.overlay.toJSON(),
6953
+ data: group.group.toJSON(),
6954
+ position: group.window.dimensions(),
6276
6955
  };
6277
6956
  });
6278
6957
  const result = {
@@ -6283,10 +6962,13 @@
6283
6962
  if (floats.length > 0) {
6284
6963
  result.floatingGroups = floats;
6285
6964
  }
6965
+ if (popoutGroups.length > 0) {
6966
+ result.popoutGroups = popoutGroups;
6967
+ }
6286
6968
  return result;
6287
6969
  }
6288
6970
  fromJSON(data) {
6289
- var _a;
6971
+ var _a, _b;
6290
6972
  this.clear();
6291
6973
  if (typeof data !== 'object' || data === null) {
6292
6974
  throw new Error('serialized layout must be a non-null object');
@@ -6353,7 +7035,16 @@
6353
7035
  width: position.width,
6354
7036
  }, { skipRemoveGroup: true, inDragMode: false });
6355
7037
  }
6356
- for (const floatingGroup of this.floatingGroups) {
7038
+ const serializedPopoutGroups = (_b = data.popoutGroups) !== null && _b !== void 0 ? _b : [];
7039
+ for (const serializedPopoutGroup of serializedPopoutGroups) {
7040
+ const { data, position } = serializedPopoutGroup;
7041
+ const group = createGroupFromSerializedState(data);
7042
+ this.addPopoutGroup(group, {
7043
+ skipRemoveGroup: true,
7044
+ position: position !== null && position !== void 0 ? position : undefined,
7045
+ });
7046
+ }
7047
+ for (const floatingGroup of this._floatingGroups) {
6357
7048
  floatingGroup.overlay.setBounds();
6358
7049
  }
6359
7050
  if (typeof activeGroup === 'string') {
@@ -6385,7 +7076,7 @@
6385
7076
  this._onDidRemoveGroup.fire(group);
6386
7077
  }
6387
7078
  // iterate over a reassigned array since original array will be modified
6388
- for (const floatingGroup of [...this.floatingGroups]) {
7079
+ for (const floatingGroup of [...this._floatingGroups]) {
6389
7080
  floatingGroup.dispose();
6390
7081
  }
6391
7082
  // fires clean-up events and clears the underlying HTML gridview.
@@ -6477,7 +7168,8 @@
6477
7168
  group.model.openPanel(panel);
6478
7169
  this.doSetGroupAndPanelActive(group);
6479
7170
  }
6480
- else if (referenceGroup.api.isFloating || target === 'center') {
7171
+ else if (referenceGroup.api.location === 'floating' ||
7172
+ target === 'center') {
6481
7173
  panel = this.createPanel(options, referenceGroup);
6482
7174
  referenceGroup.model.openPanel(panel);
6483
7175
  }
@@ -6521,6 +7213,7 @@
6521
7213
  }
6522
7214
  group.model.removePanel(panel);
6523
7215
  if (!options.skipDispose) {
7216
+ this.overlayRenderContainer.detatch(panel);
6524
7217
  panel.dispose();
6525
7218
  }
6526
7219
  if (group.size === 0 && options.removeEmptyGroup) {
@@ -6537,7 +7230,7 @@
6537
7230
  }
6538
7231
  updateWatermark() {
6539
7232
  var _a, _b;
6540
- if (this.groups.filter((x) => !x.api.isFloating).length === 0) {
7233
+ if (this.groups.filter((x) => x.api.location === 'grid').length === 0) {
6541
7234
  if (!this.watermark) {
6542
7235
  this.watermark = this.createWatermarkComponent();
6543
7236
  this.watermark.init({
@@ -6612,19 +7305,40 @@
6612
7305
  }
6613
7306
  }
6614
7307
  doRemoveGroup(group, options) {
6615
- const floatingGroup = this.floatingGroups.find((_) => _.group === group);
6616
- if (floatingGroup) {
6617
- if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
6618
- floatingGroup.group.dispose();
6619
- this._groups.delete(group.id);
6620
- this._onDidRemoveGroup.fire(group);
7308
+ if (group.api.location === 'floating') {
7309
+ const floatingGroup = this._floatingGroups.find((_) => _.group === group);
7310
+ if (floatingGroup) {
7311
+ if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
7312
+ floatingGroup.group.dispose();
7313
+ this._groups.delete(group.id);
7314
+ this._onDidRemoveGroup.fire(group);
7315
+ }
7316
+ remove(this._floatingGroups, floatingGroup);
7317
+ floatingGroup.dispose();
7318
+ if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
7319
+ const groups = Array.from(this._groups.values());
7320
+ this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7321
+ }
7322
+ return floatingGroup.group;
6621
7323
  }
6622
- floatingGroup.dispose();
6623
- if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
6624
- const groups = Array.from(this._groups.values());
6625
- this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7324
+ throw new Error('failed to find floating group');
7325
+ }
7326
+ if (group.api.location === 'popout') {
7327
+ const selectedGroup = this._popoutGroups.find((_) => _.group === group);
7328
+ if (selectedGroup) {
7329
+ if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
7330
+ selectedGroup.group.dispose();
7331
+ this._groups.delete(group.id);
7332
+ this._onDidRemoveGroup.fire(group);
7333
+ }
7334
+ selectedGroup.dispose();
7335
+ if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
7336
+ const groups = Array.from(this._groups.values());
7337
+ this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7338
+ }
7339
+ return selectedGroup.group;
6626
7340
  }
6627
- return floatingGroup.group;
7341
+ throw new Error('failed to find popout group');
6628
7342
  }
6629
7343
  return super.doRemoveGroup(group, options);
6630
7344
  }
@@ -6656,8 +7370,7 @@
6656
7370
  const targetLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
6657
7371
  if (sourceGroup && sourceGroup.size < 2) {
6658
7372
  const [targetParentLocation, to] = tail(targetLocation);
6659
- const isFloating = this.floatingGroups.find((x) => x.group === sourceGroup);
6660
- if (!isFloating) {
7373
+ if (sourceGroup.api.location === 'grid') {
6661
7374
  const sourceLocation = getGridLocation(sourceGroup.element);
6662
7375
  const [sourceParentLocation, from] = tail(sourceLocation);
6663
7376
  if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
@@ -6703,12 +7416,25 @@
6703
7416
  }
6704
7417
  }
6705
7418
  else {
6706
- const floatingGroup = this.floatingGroups.find((x) => x.group === sourceGroup);
6707
- if (floatingGroup) {
6708
- floatingGroup.dispose();
6709
- }
6710
- else {
6711
- this.gridview.removeView(getGridLocation(sourceGroup.element));
7419
+ switch (sourceGroup.api.location) {
7420
+ case 'grid':
7421
+ this.gridview.removeView(getGridLocation(sourceGroup.element));
7422
+ break;
7423
+ case 'floating': {
7424
+ const selectedFloatingGroup = this._floatingGroups.find((x) => x.group === sourceGroup);
7425
+ if (!selectedFloatingGroup) {
7426
+ throw new Error('failed to find floating group');
7427
+ }
7428
+ selectedFloatingGroup.dispose();
7429
+ break;
7430
+ }
7431
+ case 'popout': {
7432
+ const selectedPopoutGroup = this._popoutGroups.find((x) => x.group === sourceGroup);
7433
+ if (!selectedPopoutGroup) {
7434
+ throw new Error('failed to find popout group');
7435
+ }
7436
+ selectedPopoutGroup.dispose();
7437
+ }
6712
7438
  }
6713
7439
  const referenceLocation = getGridLocation(referenceGroup.element);
6714
7440
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, target);
@@ -6770,7 +7496,7 @@
6770
7496
  const contentComponent = options.component;
6771
7497
  const tabComponent = (_a = options.tabComponent) !== null && _a !== void 0 ? _a : this.options.defaultTabComponent;
6772
7498
  const view = new DockviewPanelModel(this, options.id, contentComponent, tabComponent);
6773
- const panel = new DockviewPanel(options.id, this, this._api, group, view);
7499
+ const panel = new DockviewPanel(options.id, this, this._api, group, view, { renderer: options.renderer });
6774
7500
  panel.init({
6775
7501
  title: (_b = options.title) !== null && _b !== void 0 ? _b : options.id,
6776
7502
  params: (_c = options === null || options === void 0 ? void 0 : options.params) !== null && _c !== void 0 ? _c : {},
@@ -8116,6 +8842,8 @@
8116
8842
  singleTabMode: props.singleTabMode,
8117
8843
  disableFloatingGroups: props.disableFloatingGroups,
8118
8844
  floatingGroupBounds: props.floatingGroupBounds,
8845
+ defaultRenderer: props.defaultRenderer,
8846
+ debug: props.debug,
8119
8847
  });
8120
8848
  const { clientWidth, clientHeight } = domRef.current;
8121
8849
  dockview.layout(clientWidth, clientHeight);