dockview 1.8.5 → 1.9.1

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 +4 -1
  4. package/dist/cjs/dockview/dockview.d.ts.map +1 -1
  5. package/dist/cjs/dockview/dockview.js +11 -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 +976 -228
  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 +976 -228
  21. package/dist/dockview.amd.noStyle.js.map +1 -1
  22. package/dist/dockview.cjs.js +976 -228
  23. package/dist/dockview.cjs.js.map +1 -1
  24. package/dist/dockview.esm.js +976 -228
  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 +976 -228
  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 +976 -228
  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 +4 -1
  38. package/dist/esm/dockview/dockview.d.ts.map +1 -1
  39. package/dist/esm/dockview/dockview.js +11 -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.1
4
4
  * @link https://github.com/mathuo/dockview
5
5
  * @license MIT
6
6
  */
@@ -282,6 +282,14 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
282
282
  // noop
283
283
  },
284
284
  };
285
+ function from(func) {
286
+ return {
287
+ dispose: () => {
288
+ func();
289
+ },
290
+ };
291
+ }
292
+ Disposable.from = from;
285
293
  })(Disposable || (Disposable = {}));
286
294
  class CompositeDisposable {
287
295
  get isDisposed() {
@@ -466,6 +474,61 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
466
474
  function quasiDefaultPrevented(event) {
467
475
  return event[QUASI_PREVENT_DEFAULT_KEY];
468
476
  }
477
+ function addStyles(document, styleSheetList) {
478
+ const styleSheets = Array.from(styleSheetList);
479
+ for (const styleSheet of styleSheets) {
480
+ if (styleSheet.href) {
481
+ const link = document.createElement('link');
482
+ link.href = styleSheet.href;
483
+ link.type = styleSheet.type;
484
+ link.rel = 'stylesheet';
485
+ document.head.appendChild(link);
486
+ }
487
+ let cssTexts = [];
488
+ try {
489
+ if (styleSheet.cssRules) {
490
+ cssTexts = Array.from(styleSheet.cssRules).map((rule) => rule.cssText);
491
+ }
492
+ }
493
+ catch (err) {
494
+ // security errors (lack of permissions), ignore
495
+ }
496
+ for (const rule of cssTexts) {
497
+ const style = document.createElement('style');
498
+ style.appendChild(document.createTextNode(rule));
499
+ document.head.appendChild(style);
500
+ }
501
+ }
502
+ }
503
+ function getDomNodePagePosition(domNode) {
504
+ const { left, top, width, height } = domNode.getBoundingClientRect();
505
+ return {
506
+ left: left + window.scrollX,
507
+ top: top + window.scrollY,
508
+ width: width,
509
+ height: height,
510
+ };
511
+ }
512
+ /**
513
+ * Check whether an element is in the DOM (including the Shadow DOM)
514
+ * @see https://terodox.tech/how-to-tell-if-an-element-is-in-the-dom-including-the-shadow-dom/
515
+ */
516
+ function isInDocument(element) {
517
+ let currentElement = element;
518
+ while (currentElement === null || currentElement === void 0 ? void 0 : currentElement.parentNode) {
519
+ if (currentElement.parentNode === document) {
520
+ return true;
521
+ }
522
+ else if (currentElement.parentNode instanceof DocumentFragment) {
523
+ // handle shadow DOMs
524
+ currentElement = currentElement.parentNode.host;
525
+ }
526
+ else {
527
+ currentElement = currentElement.parentNode;
528
+ }
529
+ }
530
+ return false;
531
+ }
469
532
 
470
533
  function tail(arr) {
471
534
  if (arr.length === 0) {
@@ -663,6 +726,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
663
726
  Sizing.Invisible = Invisible;
664
727
  })(exports.Sizing || (exports.Sizing = {}));
665
728
  class Splitview {
729
+ get contentSize() {
730
+ return this._contentSize;
731
+ }
666
732
  get size() {
667
733
  return this._size;
668
734
  }
@@ -728,7 +794,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
728
794
  this.sashes = [];
729
795
  this._size = 0;
730
796
  this._orthogonalSize = 0;
731
- this.contentSize = 0;
797
+ this._contentSize = 0;
732
798
  this._proportions = undefined;
733
799
  this._startSnappingEnabled = true;
734
800
  this._endSnappingEnabled = true;
@@ -847,7 +913,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
847
913
  );
848
914
  });
849
915
  // Initialize content size and proportions for first layout
850
- this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
916
+ this._contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
851
917
  this.saveProportions();
852
918
  }
853
919
  }
@@ -1121,7 +1187,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
1121
1187
  this.addView(view, sizing, to);
1122
1188
  }
1123
1189
  layout(size, orthogonalSize) {
1124
- const previousSize = Math.max(this.size, this.contentSize);
1190
+ const previousSize = Math.max(this.size, this._contentSize);
1125
1191
  this.size = size;
1126
1192
  this.orthogonalSize = orthogonalSize;
1127
1193
  if (!this.proportions) {
@@ -1131,9 +1197,23 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
1131
1197
  this.resize(this.viewItems.length - 1, size - previousSize, undefined, lowPriorityIndexes, highPriorityIndexes);
1132
1198
  }
1133
1199
  else {
1200
+ let total = 0;
1134
1201
  for (let i = 0; i < this.viewItems.length; i++) {
1135
1202
  const item = this.viewItems[i];
1136
- item.size = clamp(Math.round(this.proportions[i] * size), item.minimumSize, item.maximumSize);
1203
+ const proportion = this.proportions[i];
1204
+ if (typeof proportion === 'number') {
1205
+ total += proportion;
1206
+ }
1207
+ else {
1208
+ size -= item.size;
1209
+ }
1210
+ }
1211
+ for (let i = 0; i < this.viewItems.length; i++) {
1212
+ const item = this.viewItems[i];
1213
+ const proportion = this.proportions[i];
1214
+ if (typeof proportion === 'number' && total > 0) {
1215
+ item.size = clamp(Math.round((proportion * size) / total), item.minimumSize, item.maximumSize);
1216
+ }
1137
1217
  }
1138
1218
  }
1139
1219
  this.distributeEmptySpace();
@@ -1170,12 +1250,12 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
1170
1250
  }
1171
1251
  }
1172
1252
  saveProportions() {
1173
- if (this.proportionalLayout && this.contentSize > 0) {
1174
- this._proportions = this.viewItems.map((i) => i.size / this.contentSize);
1253
+ if (this.proportionalLayout && this._contentSize > 0) {
1254
+ this._proportions = this.viewItems.map((i) => i.visible ? i.size / this._contentSize : undefined);
1175
1255
  }
1176
1256
  }
1177
1257
  layoutViews() {
1178
- this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
1258
+ this._contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
1179
1259
  let sum = 0;
1180
1260
  const x = [];
1181
1261
  this.updateSashEnablement();
@@ -1269,7 +1349,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
1269
1349
  }
1270
1350
  else if (snappedAfter &&
1271
1351
  collapsesDown[index] &&
1272
- (position < this.contentSize || this.endSnappingEnabled)) {
1352
+ (position < this._contentSize || this.endSnappingEnabled)) {
1273
1353
  this.updateSash(sash, exports.SashState.MAXIMUM);
1274
1354
  }
1275
1355
  else {
@@ -1558,7 +1638,6 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
1558
1638
  setVisible(visible) {
1559
1639
  if (this.view.setVisible) {
1560
1640
  this.view.setVisible(visible);
1561
- this._onDidChange.fire({});
1562
1641
  }
1563
1642
  }
1564
1643
  layout(size, orthogonalSize) {
@@ -1590,10 +1669,14 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
1590
1669
  get minimumSize() {
1591
1670
  return this.children.length === 0
1592
1671
  ? 0
1593
- : Math.max(...this.children.map((c) => c.minimumOrthogonalSize));
1672
+ : Math.max(...this.children.map((c, index) => this.splitview.isViewVisible(index)
1673
+ ? c.minimumOrthogonalSize
1674
+ : 0));
1594
1675
  }
1595
1676
  get maximumSize() {
1596
- return Math.min(...this.children.map((c) => c.maximumOrthogonalSize));
1677
+ return Math.min(...this.children.map((c, index) => this.splitview.isViewVisible(index)
1678
+ ? c.maximumOrthogonalSize
1679
+ : Number.POSITIVE_INFINITY));
1597
1680
  }
1598
1681
  get minimumOrthogonalSize() {
1599
1682
  return this.splitview.minimumSize;
@@ -1651,6 +1734,8 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
1651
1734
  this.children = [];
1652
1735
  this._onDidChange = new Emitter();
1653
1736
  this.onDidChange = this._onDidChange.event;
1737
+ this._onDidVisibilityChange = new Emitter();
1738
+ this.onDidVisibilityChange = this._onDidVisibilityChange.event;
1654
1739
  this._orthogonalSize = orthogonalSize;
1655
1740
  this._size = size;
1656
1741
  this.element = document.createElement('div');
@@ -1685,7 +1770,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
1685
1770
  styles,
1686
1771
  });
1687
1772
  }
1688
- this.addDisposables(this._onDidChange, this.splitview.onDidSashEnd(() => {
1773
+ this.addDisposables(this._onDidChange, this._onDidVisibilityChange, this.splitview.onDidSashEnd(() => {
1689
1774
  this._onDidChange.fire({});
1690
1775
  }));
1691
1776
  this.setupChildrenEvents();
@@ -1708,7 +1793,15 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
1708
1793
  if (this.splitview.isViewVisible(index) === visible) {
1709
1794
  return;
1710
1795
  }
1796
+ const wereAllChildrenHidden = this.splitview.contentSize === 0;
1711
1797
  this.splitview.setViewVisible(index, visible);
1798
+ const areAllChildrenHidden = this.splitview.contentSize === 0;
1799
+ // If all children are hidden then the parent should hide the entire splitview
1800
+ // If the entire splitview is hidden then the parent should show the splitview when a child is shown
1801
+ if ((visible && wereAllChildrenHidden) ||
1802
+ (!visible && areAllChildrenHidden)) {
1803
+ this._onDidVisibilityChange.fire(visible);
1804
+ }
1712
1805
  }
1713
1806
  moveChild(from, to) {
1714
1807
  if (from === to) {
@@ -1772,13 +1865,20 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
1772
1865
  }
1773
1866
  setupChildrenEvents() {
1774
1867
  this._childrenDisposable.dispose();
1775
- this._childrenDisposable = exports.DockviewEvent.any(...this.children.map((c) => c.onDidChange))((e) => {
1868
+ this._childrenDisposable = new CompositeDisposable(exports.DockviewEvent.any(...this.children.map((c) => c.onDidChange))((e) => {
1776
1869
  /**
1777
1870
  * indicate a change has occured to allows any re-rendering but don't bubble
1778
1871
  * event because that was specific to this branch
1779
1872
  */
1780
1873
  this._onDidChange.fire({ size: e.orthogonalSize });
1781
- });
1874
+ }), ...this.children.map((c, i) => {
1875
+ if (c instanceof BranchNode) {
1876
+ return c.onDidVisibilityChange((visible) => {
1877
+ this.setChildVisible(i, visible);
1878
+ });
1879
+ }
1880
+ return Disposable.NONE;
1881
+ }));
1782
1882
  }
1783
1883
  dispose() {
1784
1884
  this._childrenDisposable.dispose();
@@ -1939,7 +2039,69 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
1939
2039
  get maximumHeight() {
1940
2040
  return this.root.maximumHeight;
1941
2041
  }
2042
+ maximizedView() {
2043
+ var _a;
2044
+ return (_a = this._maximizedNode) === null || _a === void 0 ? void 0 : _a.view;
2045
+ }
2046
+ hasMaximizedView() {
2047
+ return this._maximizedNode !== undefined;
2048
+ }
2049
+ maximizeView(view) {
2050
+ const location = getGridLocation(view.element);
2051
+ const [_, node] = this.getNode(location);
2052
+ if (!(node instanceof LeafNode)) {
2053
+ return;
2054
+ }
2055
+ if (this._maximizedNode === node) {
2056
+ return;
2057
+ }
2058
+ if (this.hasMaximizedView()) {
2059
+ this.exitMaximizedView();
2060
+ }
2061
+ function hideAllViewsBut(parent, exclude) {
2062
+ for (let i = 0; i < parent.children.length; i++) {
2063
+ const child = parent.children[i];
2064
+ if (child instanceof LeafNode) {
2065
+ if (child !== exclude) {
2066
+ parent.setChildVisible(i, false);
2067
+ }
2068
+ }
2069
+ else {
2070
+ hideAllViewsBut(child, exclude);
2071
+ }
2072
+ }
2073
+ }
2074
+ hideAllViewsBut(this.root, node);
2075
+ this._maximizedNode = node;
2076
+ this._onDidMaxmizedNodeChange.fire();
2077
+ }
2078
+ exitMaximizedView() {
2079
+ if (!this._maximizedNode) {
2080
+ return;
2081
+ }
2082
+ function showViewsInReverseOrder(parent) {
2083
+ for (let index = parent.children.length - 1; index >= 0; index--) {
2084
+ const child = parent.children[index];
2085
+ if (child instanceof LeafNode) {
2086
+ parent.setChildVisible(index, true);
2087
+ }
2088
+ else {
2089
+ showViewsInReverseOrder(child);
2090
+ }
2091
+ }
2092
+ }
2093
+ showViewsInReverseOrder(this.root);
2094
+ this._maximizedNode = undefined;
2095
+ this._onDidMaxmizedNodeChange.fire();
2096
+ }
1942
2097
  serialize() {
2098
+ if (this.hasMaximizedView()) {
2099
+ /**
2100
+ * do not persist maximized view state but we must first exit any maximized views
2101
+ * before serialization to ensure the correct dimensions are persisted
2102
+ */
2103
+ this.exitMaximizedView();
2104
+ }
1943
2105
  const root = serializeBranchNode(this.getView(), this.orientation);
1944
2106
  return {
1945
2107
  root,
@@ -1951,7 +2113,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
1951
2113
  dispose() {
1952
2114
  this.disposable.dispose();
1953
2115
  this._onDidChange.dispose();
2116
+ this._onDidMaxmizedNodeChange.dispose();
1954
2117
  this.root.dispose();
2118
+ this._maximizedNode = undefined;
1955
2119
  this.element.remove();
1956
2120
  }
1957
2121
  clear() {
@@ -1992,6 +2156,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
1992
2156
  const oldRoot = this._root;
1993
2157
  if (oldRoot) {
1994
2158
  oldRoot.dispose();
2159
+ this._maximizedNode = undefined;
1995
2160
  this.element.removeChild(oldRoot.element);
1996
2161
  }
1997
2162
  this._root = root;
@@ -2078,9 +2243,12 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
2078
2243
  constructor(proportionalLayout, styles, orientation) {
2079
2244
  this.proportionalLayout = proportionalLayout;
2080
2245
  this.styles = styles;
2246
+ this._maximizedNode = undefined;
2081
2247
  this.disposable = new MutableDisposable();
2082
2248
  this._onDidChange = new Emitter();
2083
2249
  this.onDidChange = this._onDidChange.event;
2250
+ this._onDidMaxmizedNodeChange = new Emitter();
2251
+ this.onDidMaxmizedNodeChange = this._onDidMaxmizedNodeChange.event;
2084
2252
  this.element = document.createElement('div');
2085
2253
  this.element.className = 'grid-view';
2086
2254
  this.root = new BranchNode(orientation, proportionalLayout, styles, 0, 0);
@@ -2094,6 +2262,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
2094
2262
  return parent.isChildVisible(index);
2095
2263
  }
2096
2264
  setViewVisible(location, visible) {
2265
+ if (this.hasMaximizedView()) {
2266
+ this.exitMaximizedView();
2267
+ }
2097
2268
  const [rest, index] = tail(location);
2098
2269
  const [, parent] = this.getNode(rest);
2099
2270
  if (!(parent instanceof BranchNode)) {
@@ -2102,6 +2273,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
2102
2273
  parent.setChildVisible(index, visible);
2103
2274
  }
2104
2275
  moveView(parentLocation, from, to) {
2276
+ if (this.hasMaximizedView()) {
2277
+ this.exitMaximizedView();
2278
+ }
2105
2279
  const [, parent] = this.getNode(parentLocation);
2106
2280
  if (!(parent instanceof BranchNode)) {
2107
2281
  throw new Error('Invalid location');
@@ -2109,6 +2283,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
2109
2283
  parent.moveChild(from, to);
2110
2284
  }
2111
2285
  addView(view, size, location) {
2286
+ if (this.hasMaximizedView()) {
2287
+ this.exitMaximizedView();
2288
+ }
2112
2289
  const [rest, index] = tail(location);
2113
2290
  const [pathToParent, parent] = this.getNode(rest);
2114
2291
  if (parent instanceof BranchNode) {
@@ -2141,6 +2318,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
2141
2318
  return this.removeView(location, sizing);
2142
2319
  }
2143
2320
  removeView(location, sizing) {
2321
+ if (this.hasMaximizedView()) {
2322
+ this.exitMaximizedView();
2323
+ }
2144
2324
  const [rest, index] = tail(location);
2145
2325
  const [pathToParent, parent] = this.getNode(rest);
2146
2326
  if (!(parent instanceof BranchNode)) {
@@ -2878,6 +3058,24 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
2878
3058
  moveToPrevious(options) {
2879
3059
  this.component.moveToPrevious(options);
2880
3060
  }
3061
+ maximizeGroup(panel) {
3062
+ this.component.maximizeGroup(panel.group);
3063
+ }
3064
+ hasMaximizedGroup() {
3065
+ return this.component.hasMaximizedGroup();
3066
+ }
3067
+ exitMaxmizedGroup() {
3068
+ this.component.exitMaximizedGroup();
3069
+ }
3070
+ get onDidMaxmizedGroupChange() {
3071
+ return this.component.onDidMaxmizedGroupChange;
3072
+ }
3073
+ /**
3074
+ * Add a popout group in a new Window
3075
+ */
3076
+ addPopoutGroup(item, options) {
3077
+ this.component.addPopoutGroup(item, options);
3078
+ }
2881
3079
  }
2882
3080
 
2883
3081
  class DragAndDropObserver extends CompositeDisposable {
@@ -2888,36 +3086,48 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
2888
3086
  this.target = null;
2889
3087
  this.registerListeners();
2890
3088
  }
3089
+ onDragEnter(e) {
3090
+ this.target = e.target;
3091
+ this.callbacks.onDragEnter(e);
3092
+ }
3093
+ onDragOver(e) {
3094
+ e.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome)
3095
+ if (this.callbacks.onDragOver) {
3096
+ this.callbacks.onDragOver(e);
3097
+ }
3098
+ }
3099
+ onDragLeave(e) {
3100
+ if (this.target === e.target) {
3101
+ this.target = null;
3102
+ this.callbacks.onDragLeave(e);
3103
+ }
3104
+ }
3105
+ onDragEnd(e) {
3106
+ this.target = null;
3107
+ this.callbacks.onDragEnd(e);
3108
+ }
3109
+ onDrop(e) {
3110
+ this.callbacks.onDrop(e);
3111
+ }
2891
3112
  registerListeners() {
2892
3113
  this.addDisposables(addDisposableListener(this.element, 'dragenter', (e) => {
2893
- this.target = e.target;
2894
- this.callbacks.onDragEnter(e);
3114
+ this.onDragEnter(e);
2895
3115
  }, true));
2896
3116
  this.addDisposables(addDisposableListener(this.element, 'dragover', (e) => {
2897
- e.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome)
2898
- if (this.callbacks.onDragOver) {
2899
- this.callbacks.onDragOver(e);
2900
- }
3117
+ this.onDragOver(e);
2901
3118
  }, true));
2902
3119
  this.addDisposables(addDisposableListener(this.element, 'dragleave', (e) => {
2903
- if (this.target === e.target) {
2904
- this.target = null;
2905
- this.callbacks.onDragLeave(e);
2906
- }
3120
+ this.onDragLeave(e);
2907
3121
  }));
2908
3122
  this.addDisposables(addDisposableListener(this.element, 'dragend', (e) => {
2909
- this.target = null;
2910
- this.callbacks.onDragEnd(e);
3123
+ this.onDragEnd(e);
2911
3124
  }));
2912
3125
  this.addDisposables(addDisposableListener(this.element, 'drop', (e) => {
2913
- this.callbacks.onDrop(e);
3126
+ this.onDrop(e);
2914
3127
  }));
2915
3128
  }
2916
3129
  }
2917
3130
 
2918
- function numberOrFallback(maybeNumber, fallback) {
2919
- return typeof maybeNumber === 'number' ? maybeNumber : fallback;
2920
- }
2921
3131
  function directionToPosition(direction) {
2922
3132
  switch (direction) {
2923
3133
  case 'above':
@@ -2950,6 +3160,16 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
2950
3160
  throw new Error(`invalid position '${position}'`);
2951
3161
  }
2952
3162
  }
3163
+ const DEFAULT_ACTIVATION_SIZE = {
3164
+ value: 20,
3165
+ type: 'percentage',
3166
+ };
3167
+ const DEFAULT_SIZE = {
3168
+ value: 50,
3169
+ type: 'percentage',
3170
+ };
3171
+ const SMALL_WIDTH_BOUNDARY = 100;
3172
+ const SMALL_HEIGHT_BOUNDARY = 100;
2953
3173
  class Droptarget extends CompositeDisposable {
2954
3174
  get state() {
2955
3175
  return this._state;
@@ -2962,7 +3182,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
2962
3182
  this.onDrop = this._onDrop.event;
2963
3183
  // use a set to take advantage of #<set>.has
2964
3184
  this._acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
2965
- this.addDisposables(this._onDrop, new DragAndDropObserver(this.element, {
3185
+ this.dnd = new DragAndDropObserver(this.element, {
2966
3186
  onDragEnter: () => undefined,
2967
3187
  onDragOver: (e) => {
2968
3188
  if (this._acceptedTargetZonesSet.size === 0) {
@@ -3010,7 +3230,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3010
3230
  this.element.append(this.targetElement);
3011
3231
  }
3012
3232
  this.toggleClasses(quadrant, width, height);
3013
- this.setState(quadrant);
3233
+ this._state = quadrant;
3014
3234
  },
3015
3235
  onDragLeave: () => {
3016
3236
  this.removeDropTarget();
@@ -3029,11 +3249,15 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3029
3249
  this._onDrop.fire({ position: state, nativeEvent: e });
3030
3250
  }
3031
3251
  },
3032
- }));
3252
+ });
3253
+ this.addDisposables(this._onDrop, this.dnd);
3033
3254
  }
3034
3255
  setTargetZones(acceptedTargetZones) {
3035
3256
  this._acceptedTargetZonesSet = new Set(acceptedTargetZones);
3036
3257
  }
3258
+ setOverlayModel(model) {
3259
+ this.options.overlayModel = model;
3260
+ }
3037
3261
  dispose() {
3038
3262
  this.removeDropTarget();
3039
3263
  super.dispose();
@@ -3045,19 +3269,19 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3045
3269
  event[Droptarget.USED_EVENT_ID] = true;
3046
3270
  }
3047
3271
  /**
3048
- * Check is the event has already been used by another instance od DropTarget
3272
+ * Check is the event has already been used by another instance of DropTarget
3049
3273
  */
3050
3274
  isAlreadyUsed(event) {
3051
3275
  const value = event[Droptarget.USED_EVENT_ID];
3052
3276
  return typeof value === 'boolean' && value;
3053
3277
  }
3054
3278
  toggleClasses(quadrant, width, height) {
3055
- var _a, _b, _c, _d;
3279
+ var _a, _b;
3056
3280
  if (!this.overlayElement) {
3057
3281
  return;
3058
3282
  }
3059
- const isSmallX = width < 100;
3060
- const isSmallY = height < 100;
3283
+ const isSmallX = width < SMALL_WIDTH_BOUNDARY;
3284
+ const isSmallY = height < SMALL_HEIGHT_BOUNDARY;
3061
3285
  const isLeft = quadrant === 'left';
3062
3286
  const isRight = quadrant === 'right';
3063
3287
  const isTop = quadrant === 'top';
@@ -3066,20 +3290,17 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3066
3290
  const leftClass = !isSmallX && isLeft;
3067
3291
  const topClass = !isSmallY && isTop;
3068
3292
  const bottomClass = !isSmallY && isBottom;
3069
- let size = 0.5;
3070
- if (((_b = (_a = this.options.overlayModel) === null || _a === void 0 ? void 0 : _a.size) === null || _b === void 0 ? void 0 : _b.type) === 'percentage') {
3071
- size = clamp(this.options.overlayModel.size.value, 0, 100) / 100;
3293
+ let size = 1;
3294
+ const sizeOptions = (_b = (_a = this.options.overlayModel) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : DEFAULT_SIZE;
3295
+ if (sizeOptions.type === 'percentage') {
3296
+ size = clamp(sizeOptions.value, 0, 100) / 100;
3072
3297
  }
3073
- if (((_d = (_c = this.options.overlayModel) === null || _c === void 0 ? void 0 : _c.size) === null || _d === void 0 ? void 0 : _d.type) === 'pixels') {
3298
+ else {
3074
3299
  if (rightClass || leftClass) {
3075
- size =
3076
- clamp(0, this.options.overlayModel.size.value, width) /
3077
- width;
3300
+ size = clamp(0, sizeOptions.value, width) / width;
3078
3301
  }
3079
3302
  if (topClass || bottomClass) {
3080
- size =
3081
- clamp(0, this.options.overlayModel.size.value, height) /
3082
- height;
3303
+ size = clamp(0, sizeOptions.value, height) / height;
3083
3304
  }
3084
3305
  }
3085
3306
  const translate = (1 - size) / 2;
@@ -3101,39 +3322,22 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3101
3322
  transform = '';
3102
3323
  }
3103
3324
  this.overlayElement.style.transform = transform;
3104
- toggleClass(this.overlayElement, 'small-right', isSmallX && isRight);
3105
- toggleClass(this.overlayElement, 'small-left', isSmallX && isLeft);
3106
- toggleClass(this.overlayElement, 'small-top', isSmallY && isTop);
3107
- toggleClass(this.overlayElement, 'small-bottom', isSmallY && isBottom);
3108
- }
3109
- setState(quadrant) {
3110
- switch (quadrant) {
3111
- case 'top':
3112
- this._state = 'top';
3113
- break;
3114
- case 'left':
3115
- this._state = 'left';
3116
- break;
3117
- case 'bottom':
3118
- this._state = 'bottom';
3119
- break;
3120
- case 'right':
3121
- this._state = 'right';
3122
- break;
3123
- case 'center':
3124
- this._state = 'center';
3125
- break;
3126
- }
3325
+ toggleClass(this.overlayElement, 'dv-drop-target-small-vertical', isSmallY);
3326
+ toggleClass(this.overlayElement, 'dv-drop-target-small-horizontal', isSmallX);
3327
+ toggleClass(this.overlayElement, 'dv-drop-target-left', isLeft);
3328
+ toggleClass(this.overlayElement, 'dv-drop-target-right', isRight);
3329
+ toggleClass(this.overlayElement, 'dv-drop-target-top', isTop);
3330
+ toggleClass(this.overlayElement, 'dv-drop-target-bottom', isBottom);
3331
+ toggleClass(this.overlayElement, 'dv-drop-target-center', quadrant === 'center');
3127
3332
  }
3128
3333
  calculateQuadrant(overlayType, x, y, width, height) {
3129
- var _a, _b, _c, _d, _e, _f;
3130
- const isPercentage = ((_a = this.options.overlayModel) === null || _a === void 0 ? void 0 : _a.activationSize) === undefined ||
3131
- ((_c = (_b = this.options.overlayModel) === null || _b === void 0 ? void 0 : _b.activationSize) === null || _c === void 0 ? void 0 : _c.type) === 'percentage';
3132
- const value = numberOrFallback((_f = (_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.overlayModel) === null || _e === void 0 ? void 0 : _e.activationSize) === null || _f === void 0 ? void 0 : _f.value, 20);
3334
+ var _a, _b;
3335
+ const activationSizeOptions = (_b = (_a = this.options.overlayModel) === null || _a === void 0 ? void 0 : _a.activationSize) !== null && _b !== void 0 ? _b : DEFAULT_ACTIVATION_SIZE;
3336
+ const isPercentage = activationSizeOptions.type === 'percentage';
3133
3337
  if (isPercentage) {
3134
- return calculateQuadrantAsPercentage(overlayType, x, y, width, height, value);
3338
+ return calculateQuadrantAsPercentage(overlayType, x, y, width, height, activationSizeOptions.value);
3135
3339
  }
3136
- return calculateQuadrantAsPixels(overlayType, x, y, width, height, value);
3340
+ return calculateQuadrantAsPixels(overlayType, x, y, width, height, activationSizeOptions.value);
3137
3341
  }
3138
3342
  removeDropTarget() {
3139
3343
  if (this.targetElement) {
@@ -3185,12 +3389,22 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3185
3389
  return 'center';
3186
3390
  }
3187
3391
 
3392
+ exports.DockviewDropTargets = void 0;
3393
+ (function (DockviewDropTargets) {
3394
+ DockviewDropTargets[DockviewDropTargets["Tab"] = 0] = "Tab";
3395
+ DockviewDropTargets[DockviewDropTargets["Panel"] = 1] = "Panel";
3396
+ DockviewDropTargets[DockviewDropTargets["TabContainer"] = 2] = "TabContainer";
3397
+ DockviewDropTargets[DockviewDropTargets["Edge"] = 3] = "Edge";
3398
+ })(exports.DockviewDropTargets || (exports.DockviewDropTargets = {}));
3399
+
3188
3400
  class ContentContainer extends CompositeDisposable {
3189
3401
  get element() {
3190
3402
  return this._element;
3191
3403
  }
3192
- constructor() {
3404
+ constructor(accessor, group) {
3193
3405
  super();
3406
+ this.accessor = accessor;
3407
+ this.group = group;
3194
3408
  this.disposable = new MutableDisposable();
3195
3409
  this._onDidFocus = new Emitter();
3196
3410
  this.onDidFocus = this._onDidFocus.event;
@@ -3200,11 +3414,38 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3200
3414
  this._element.className = 'content-container';
3201
3415
  this._element.tabIndex = -1;
3202
3416
  this.addDisposables(this._onDidFocus, this._onDidBlur);
3203
- // for hosted containers
3204
- // 1) register a drop target on the host
3205
- // 2) register window dragStart events to disable pointer events
3206
- // 3) register dragEnd events
3207
- // 4) register mouseMove events (if no buttons are present we take this as a dragEnd event)
3417
+ this.dropTarget = new Droptarget(this.element, {
3418
+ acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
3419
+ canDisplayOverlay: (event, position) => {
3420
+ if (this.group.locked === 'no-drop-target' ||
3421
+ (this.group.locked && position === 'center')) {
3422
+ return false;
3423
+ }
3424
+ const data = getPanelData();
3425
+ if (!data &&
3426
+ event.shiftKey &&
3427
+ this.group.location !== 'floating') {
3428
+ return false;
3429
+ }
3430
+ if (data && data.viewId === this.accessor.id) {
3431
+ if (data.groupId === this.group.id) {
3432
+ if (position === 'center') {
3433
+ // don't allow to drop on self for center position
3434
+ return false;
3435
+ }
3436
+ if (data.panelId === null) {
3437
+ // don't allow group move to drop anywhere on self
3438
+ return false;
3439
+ }
3440
+ }
3441
+ const groupHasOnePanelAndIsActiveDragElement = this.group.panels.length === 1 &&
3442
+ data.groupId === this.group.id;
3443
+ return !groupHasOnePanelAndIsActiveDragElement;
3444
+ }
3445
+ return this.group.canDisplayOverlay(event, position, exports.DockviewDropTargets.Panel);
3446
+ },
3447
+ });
3448
+ this.addDisposables(this.dropTarget);
3208
3449
  }
3209
3450
  show() {
3210
3451
  this.element.style.display = '';
@@ -3212,23 +3453,43 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3212
3453
  hide() {
3213
3454
  this.element.style.display = 'none';
3214
3455
  }
3215
- openPanel(panel) {
3216
- var _a;
3217
- if (this.panel === panel) {
3218
- return;
3219
- }
3220
- if (this.panel) {
3221
- if ((_a = this.panel.view) === null || _a === void 0 ? void 0 : _a.content) {
3222
- this._element.removeChild(this.panel.view.content.element);
3223
- }
3224
- this.panel = undefined;
3456
+ renderPanel(panel, options = { asActive: true }) {
3457
+ const doRender = options.asActive ||
3458
+ (this.panel && this.group.isPanelActive(this.panel));
3459
+ if (this.panel &&
3460
+ this.panel.view.content.element.parentElement === this._element) {
3461
+ /**
3462
+ * If the currently attached panel is mounted directly to the content then remove it
3463
+ */
3464
+ this._element.removeChild(this.panel.view.content.element);
3225
3465
  }
3226
3466
  this.panel = panel;
3227
- const disposable = new CompositeDisposable();
3228
- if (this.panel.view) {
3229
- const _onDidFocus = this.panel.view.content.onDidFocus;
3230
- const _onDidBlur = this.panel.view.content.onDidBlur;
3231
- const focusTracker = trackFocus(this._element);
3467
+ let container;
3468
+ switch (panel.api.renderer) {
3469
+ case 'onlyWhenVisibile':
3470
+ this.accessor.overlayRenderContainer.detatch(panel);
3471
+ if (this.panel) {
3472
+ if (doRender) {
3473
+ this._element.appendChild(this.panel.view.content.element);
3474
+ }
3475
+ }
3476
+ container = this._element;
3477
+ break;
3478
+ case 'always':
3479
+ if (panel.view.content.element.parentElement === this._element) {
3480
+ this._element.removeChild(panel.view.content.element);
3481
+ }
3482
+ container = this.accessor.overlayRenderContainer.attach({
3483
+ panel,
3484
+ referenceContainer: this,
3485
+ });
3486
+ break;
3487
+ }
3488
+ if (doRender) {
3489
+ const _onDidFocus = panel.view.content.onDidFocus;
3490
+ const _onDidBlur = panel.view.content.onDidBlur;
3491
+ const focusTracker = trackFocus(container);
3492
+ const disposable = new CompositeDisposable();
3232
3493
  disposable.addDisposables(focusTracker, focusTracker.onDidFocus(() => this._onDidFocus.fire()), focusTracker.onDidBlur(() => this._onDidBlur.fire()));
3233
3494
  if (_onDidFocus) {
3234
3495
  disposable.addDisposables(_onDidFocus(() => this._onDidFocus.fire()));
@@ -3236,17 +3497,23 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3236
3497
  if (_onDidBlur) {
3237
3498
  disposable.addDisposables(_onDidBlur(() => this._onDidBlur.fire()));
3238
3499
  }
3239
- this._element.appendChild(this.panel.view.content.element);
3500
+ this.disposable.value = disposable;
3240
3501
  }
3241
- this.disposable.value = disposable;
3502
+ }
3503
+ openPanel(panel) {
3504
+ if (this.panel === panel) {
3505
+ return;
3506
+ }
3507
+ this.renderPanel(panel);
3242
3508
  }
3243
3509
  layout(_width, _height) {
3244
3510
  // noop
3245
3511
  }
3246
3512
  closePanel() {
3247
- var _a, _b, _c;
3248
- 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) {
3249
- this._element.removeChild(this.panel.view.content.element);
3513
+ if (this.panel) {
3514
+ if (this.accessor.options.defaultRenderer === 'onlyWhenVisibile') {
3515
+ this._element.removeChild(this.panel.view.content.element);
3516
+ }
3250
3517
  this.panel = undefined;
3251
3518
  }
3252
3519
  }
@@ -3256,14 +3523,6 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3256
3523
  }
3257
3524
  }
3258
3525
 
3259
- exports.DockviewDropTargets = void 0;
3260
- (function (DockviewDropTargets) {
3261
- DockviewDropTargets[DockviewDropTargets["Tab"] = 0] = "Tab";
3262
- DockviewDropTargets[DockviewDropTargets["Panel"] = 1] = "Panel";
3263
- DockviewDropTargets[DockviewDropTargets["TabContainer"] = 2] = "TabContainer";
3264
- DockviewDropTargets[DockviewDropTargets["Edge"] = 3] = "Edge";
3265
- })(exports.DockviewDropTargets || (exports.DockviewDropTargets = {}));
3266
-
3267
3526
  class DragHandler extends CompositeDisposable {
3268
3527
  constructor(el) {
3269
3528
  super();
@@ -3438,7 +3697,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3438
3697
  }, true));
3439
3698
  }
3440
3699
  isCancelled(_event) {
3441
- if (this.group.api.isFloating && !_event.shiftKey) {
3700
+ if (this.group.api.location === 'floating' && !_event.shiftKey) {
3442
3701
  return true;
3443
3702
  }
3444
3703
  return false;
@@ -3640,7 +3899,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3640
3899
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3641
3900
  if (isFloatingGroupsEnabled &&
3642
3901
  event.shiftKey &&
3643
- !this.group.api.isFloating) {
3902
+ this.group.api.location !== 'floating') {
3644
3903
  event.preventDefault();
3645
3904
  const { top, left } = this.element.getBoundingClientRect();
3646
3905
  const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
@@ -3705,7 +3964,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3705
3964
  }), tab.onChanged((event) => {
3706
3965
  var _a;
3707
3966
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3708
- const isFloatingWithOnePanel = this.group.api.isFloating && this.size === 1;
3967
+ const isFloatingWithOnePanel = this.group.api.location === 'floating' && this.size === 1;
3709
3968
  if (isFloatingGroupsEnabled &&
3710
3969
  !isFloatingWithOnePanel &&
3711
3970
  event.shiftKey) {
@@ -3788,15 +4047,37 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3788
4047
  }
3789
4048
  return isAncestor(document.activeElement, this.contentContainer.element);
3790
4049
  }
3791
- get isFloating() {
3792
- return this._isFloating;
3793
- }
3794
- set isFloating(value) {
3795
- this._isFloating = value;
3796
- this.dropTarget.setTargetZones(value ? ['center'] : ['top', 'bottom', 'left', 'right', 'center']);
3797
- toggleClass(this.container, 'dv-groupview-floating', value);
3798
- this.groupPanel.api._onDidFloatingStateChange.fire({
3799
- isFloating: this.isFloating,
4050
+ get location() {
4051
+ return this._location;
4052
+ }
4053
+ set location(value) {
4054
+ this._location = value;
4055
+ toggleClass(this.container, 'dv-groupview-floating', false);
4056
+ toggleClass(this.container, 'dv-groupview-popout', false);
4057
+ switch (value) {
4058
+ case 'grid':
4059
+ this.contentContainer.dropTarget.setTargetZones([
4060
+ 'top',
4061
+ 'bottom',
4062
+ 'left',
4063
+ 'right',
4064
+ 'center',
4065
+ ]);
4066
+ break;
4067
+ case 'floating':
4068
+ this.contentContainer.dropTarget.setTargetZones(['center']);
4069
+ this.contentContainer.dropTarget.setTargetZones(value
4070
+ ? ['center']
4071
+ : ['top', 'bottom', 'left', 'right', 'center']);
4072
+ toggleClass(this.container, 'dv-groupview-floating', true);
4073
+ break;
4074
+ case 'popout':
4075
+ this.contentContainer.dropTarget.setTargetZones(['center']);
4076
+ toggleClass(this.container, 'dv-groupview-popout', true);
4077
+ break;
4078
+ }
4079
+ this.groupPanel.api._onDidLocationChange.fire({
4080
+ location: this.location,
3800
4081
  });
3801
4082
  }
3802
4083
  constructor(container, accessor, id, options, groupPanel) {
@@ -3809,7 +4090,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3809
4090
  this.groupPanel = groupPanel;
3810
4091
  this._isGroupActive = false;
3811
4092
  this._locked = false;
3812
- this._isFloating = false;
4093
+ this._location = 'grid';
3813
4094
  this.mostRecentlyUsed = [];
3814
4095
  this._onDidChange = new Emitter();
3815
4096
  this.onDidChange = this._onDidChange.event;
@@ -3832,35 +4113,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3832
4113
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
3833
4114
  toggleClass(this.container, 'groupview', true);
3834
4115
  this.tabsContainer = new TabsContainer(this.accessor, this.groupPanel);
3835
- this.contentContainer = new ContentContainer();
3836
- this.dropTarget = new Droptarget(this.contentContainer.element, {
3837
- acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
3838
- canDisplayOverlay: (event, position) => {
3839
- if (this.locked === 'no-drop-target' ||
3840
- (this.locked && position === 'center')) {
3841
- return false;
3842
- }
3843
- const data = getPanelData();
3844
- if (!data && event.shiftKey && !this.isFloating) {
3845
- return false;
3846
- }
3847
- if (data && data.viewId === this.accessor.id) {
3848
- if (data.groupId === this.id) {
3849
- if (position === 'center') {
3850
- // don't allow to drop on self for center position
3851
- return false;
3852
- }
3853
- if (data.panelId === null) {
3854
- // don't allow group move to drop anywhere on self
3855
- return false;
3856
- }
3857
- }
3858
- const groupHasOnePanelAndIsActiveDragElement = this._panels.length === 1 && data.groupId === this.id;
3859
- return !groupHasOnePanelAndIsActiveDragElement;
3860
- }
3861
- return this.canDisplayOverlay(event, position, exports.DockviewDropTargets.Panel);
3862
- },
3863
- });
4116
+ this.contentContainer = new ContentContainer(this.accessor, this);
3864
4117
  container.append(this.tabsContainer.element, this.contentContainer.element);
3865
4118
  this.header.hidden = !!options.hideHeader;
3866
4119
  this.locked = (_a = options.locked) !== null && _a !== void 0 ? _a : false;
@@ -3874,7 +4127,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3874
4127
  this.accessor.doSetGroupActive(this.groupPanel, true);
3875
4128
  }), this.contentContainer.onDidBlur(() => {
3876
4129
  // noop
3877
- }), this.dropTarget.onDrop((event) => {
4130
+ }), this.contentContainer.dropTarget.onDrop((event) => {
3878
4131
  this.handleDropEvent(event.nativeEvent, event.position);
3879
4132
  }), this._onMove, this._onDidChange, this._onDidDrop, this._onDidAddPanel, this._onDidRemovePanel, this._onDidActivePanelChange);
3880
4133
  }
@@ -3923,6 +4176,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3923
4176
  this.tabsContainer.setPrefixActionsElement(this._prefixHeaderActions.element);
3924
4177
  }
3925
4178
  }
4179
+ rerender(panel) {
4180
+ this.contentContainer.renderPanel(panel, { asActive: false });
4181
+ }
3926
4182
  indexOf(panel) {
3927
4183
  return this.tabsContainer.indexOf(panel.id);
3928
4184
  }
@@ -4114,12 +4370,12 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
4114
4370
  doAddPanel(panel, index = this.panels.length, skipSetActive = false) {
4115
4371
  const existingPanel = this._panels.indexOf(panel);
4116
4372
  const hasExistingPanel = existingPanel > -1;
4373
+ this.tabsContainer.show();
4374
+ this.contentContainer.show();
4117
4375
  this.tabsContainer.openPanel(panel, index);
4118
4376
  if (!skipSetActive) {
4119
4377
  this.contentContainer.openPanel(panel);
4120
4378
  }
4121
- this.tabsContainer.show();
4122
- this.contentContainer.show();
4123
4379
  if (hasExistingPanel) {
4124
4380
  // TODO - need to ensure ordering hasn't changed and if it has need to re-order this.panels
4125
4381
  return;
@@ -4235,7 +4491,6 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
4235
4491
  for (const panel of this.panels) {
4236
4492
  panel.dispose();
4237
4493
  }
4238
- this.dropTarget.dispose();
4239
4494
  this.tabsContainer.dispose();
4240
4495
  this.contentContainer.dispose();
4241
4496
  }
@@ -4274,7 +4529,22 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
4274
4529
  if (this.disableResizing) {
4275
4530
  return;
4276
4531
  }
4277
- if (!document.body.contains(this._element)) {
4532
+ if (!this._element.offsetParent) {
4533
+ /**
4534
+ * offsetParent === null is equivalent to display: none being set on the element or one
4535
+ * of it's parents. In the display: none case the size will become (0, 0) which we do
4536
+ * not want to propagate.
4537
+ *
4538
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent
4539
+ *
4540
+ * You could use checkVisibility() but at the time of writing it's not supported across
4541
+ * all Browsers
4542
+ *
4543
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/checkVisibility
4544
+ */
4545
+ return;
4546
+ }
4547
+ if (!isInDocument(this._element)) {
4278
4548
  /**
4279
4549
  * since the event is dispatched through requestAnimationFrame there is a small chance
4280
4550
  * the component is no longer attached to the DOM, if that is the case the dimensions
@@ -4366,6 +4636,21 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
4366
4636
  isVisible(panel) {
4367
4637
  return this.gridview.isViewVisible(getGridLocation(panel.element));
4368
4638
  }
4639
+ maximizeGroup(panel) {
4640
+ this.gridview.maximizeView(panel);
4641
+ }
4642
+ isMaximizedGroup(panel) {
4643
+ return this.gridview.maximizedView() === panel;
4644
+ }
4645
+ exitMaximizedGroup() {
4646
+ this.gridview.exitMaximizedView();
4647
+ }
4648
+ hasMaximizedGroup() {
4649
+ return this.gridview.hasMaximizedView();
4650
+ }
4651
+ get onDidMaxmizedGroupChange() {
4652
+ return this.gridview.onDidMaxmizedNodeChange;
4653
+ }
4369
4654
  doAddGroup(group, location = [0], size) {
4370
4655
  this.gridview.addView(group, size !== null && size !== void 0 ? size : exports.Sizing.Distribute, location);
4371
4656
  this._onDidAddGroup.fire(group);
@@ -5142,32 +5427,63 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5142
5427
  }
5143
5428
  }
5144
5429
 
5430
+ // TODO find a better way to initialize and avoid needing null checks
5431
+ const NOT_INITIALIZED_MESSAGE = 'DockviewGroupPanelApiImpl not initialized';
5145
5432
  class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
5146
- get isFloating() {
5433
+ get location() {
5147
5434
  if (!this._group) {
5148
- throw new Error(`DockviewGroupPanelApiImpl not initialized`);
5435
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5149
5436
  }
5150
- return this._group.model.isFloating;
5437
+ return this._group.model.location;
5151
5438
  }
5152
5439
  constructor(id, accessor) {
5153
5440
  super(id);
5154
5441
  this.accessor = accessor;
5155
- this._onDidFloatingStateChange = new Emitter();
5156
- this.onDidFloatingStateChange = this._onDidFloatingStateChange.event;
5157
- this.addDisposables(this._onDidFloatingStateChange);
5442
+ this._onDidLocationChange = new Emitter();
5443
+ this.onDidLocationChange = this._onDidLocationChange.event;
5444
+ this.addDisposables(this._onDidLocationChange);
5158
5445
  }
5159
5446
  moveTo(options) {
5160
- var _a;
5447
+ var _a, _b, _c;
5448
+ if (!this._group) {
5449
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5450
+ }
5451
+ const group = (_a = options.group) !== null && _a !== void 0 ? _a : this.accessor.addGroup({
5452
+ direction: positionToDirection((_b = options.position) !== null && _b !== void 0 ? _b : 'right'),
5453
+ });
5454
+ this.accessor.moveGroupOrPanel(group, this._group.id, undefined, options.group ? (_c = options.position) !== null && _c !== void 0 ? _c : 'center' : 'center');
5455
+ }
5456
+ maximize() {
5457
+ if (!this._group) {
5458
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5459
+ }
5460
+ if (this.location !== 'grid') {
5461
+ // only grid groups can be maximized
5462
+ return;
5463
+ }
5464
+ this.accessor.maximizeGroup(this._group);
5465
+ }
5466
+ isMaximized() {
5161
5467
  if (!this._group) {
5162
- throw new Error(`DockviewGroupPanelApiImpl not initialized`);
5468
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5469
+ }
5470
+ return this.accessor.isMaximizedGroup(this._group);
5471
+ }
5472
+ exitMaximized() {
5473
+ if (!this._group) {
5474
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5475
+ }
5476
+ if (this.isMaximized()) {
5477
+ this.accessor.exitMaximizedGroup();
5163
5478
  }
5164
- this.accessor.moveGroupOrPanel(options.group, this._group.id, undefined, (_a = options.position) !== null && _a !== void 0 ? _a : 'center');
5165
5479
  }
5166
5480
  initialize(group) {
5167
5481
  this._group = group;
5168
5482
  }
5169
5483
  }
5170
5484
 
5485
+ const MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH = 100;
5486
+ const MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT = 100;
5171
5487
  class DockviewGroupPanel extends GridviewPanel {
5172
5488
  get panels() {
5173
5489
  return this._model.panels;
@@ -5192,8 +5508,8 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5192
5508
  }
5193
5509
  constructor(accessor, id, options) {
5194
5510
  super(id, 'groupview_default', {
5195
- minimumHeight: 100,
5196
- minimumWidth: 100,
5511
+ minimumHeight: MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT,
5512
+ minimumWidth: MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH,
5197
5513
  }, new DockviewGroupPanelApiImpl(id, accessor));
5198
5514
  this.api.initialize(this); // cannot use 'this' after after 'super' call
5199
5515
  this._model = new DockviewGroupPanelModel(this.element, accessor, id, options, this);
@@ -5247,8 +5563,10 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5247
5563
  return this.panel.title;
5248
5564
  }
5249
5565
  get isGroupActive() {
5250
- var _a;
5251
- return !!((_a = this.group) === null || _a === void 0 ? void 0 : _a.isActive);
5566
+ return this.group.isActive;
5567
+ }
5568
+ get renderer() {
5569
+ return this.panel.renderer;
5252
5570
  }
5253
5571
  set group(value) {
5254
5572
  const isOldGroupActive = this.isGroupActive;
@@ -5276,10 +5594,12 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5276
5594
  this.onDidActiveGroupChange = this._onDidActiveGroupChange.event;
5277
5595
  this._onDidGroupChange = new Emitter();
5278
5596
  this.onDidGroupChange = this._onDidGroupChange.event;
5597
+ this._onDidRendererChange = new Emitter();
5598
+ this.onDidRendererChange = this._onDidRendererChange.event;
5279
5599
  this.disposable = new MutableDisposable();
5280
5600
  this.initialize(panel);
5281
5601
  this._group = group;
5282
- this.addDisposables(this.disposable, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange);
5602
+ this.addDisposables(this.disposable, this._onDidRendererChange, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange);
5283
5603
  }
5284
5604
  moveTo(options) {
5285
5605
  var _a;
@@ -5288,9 +5608,21 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5288
5608
  setTitle(title) {
5289
5609
  this.panel.setTitle(title);
5290
5610
  }
5611
+ setRenderer(renderer) {
5612
+ this.panel.setRenderer(renderer);
5613
+ }
5291
5614
  close() {
5292
5615
  this.group.model.closePanel(this.panel);
5293
5616
  }
5617
+ maximize() {
5618
+ this.group.api.maximize();
5619
+ }
5620
+ isMaximized() {
5621
+ return this.group.api.isMaximized();
5622
+ }
5623
+ exitMaximized() {
5624
+ this.group.api.exitMaximized();
5625
+ }
5294
5626
  }
5295
5627
 
5296
5628
  class DockviewPanel extends CompositeDisposable {
@@ -5303,11 +5635,17 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5303
5635
  get group() {
5304
5636
  return this._group;
5305
5637
  }
5306
- constructor(id, accessor, containerApi, group, view) {
5638
+ get renderer() {
5639
+ var _a;
5640
+ return (_a = this._renderer) !== null && _a !== void 0 ? _a : this.accessor.renderer;
5641
+ }
5642
+ constructor(id, accessor, containerApi, group, view, options) {
5307
5643
  super();
5308
5644
  this.id = id;
5645
+ this.accessor = accessor;
5309
5646
  this.containerApi = containerApi;
5310
5647
  this.view = view;
5648
+ this._renderer = options.renderer;
5311
5649
  this._group = group;
5312
5650
  this.api = new DockviewPanelApiImpl(this, this._group, accessor);
5313
5651
  this.addDisposables(this.api.onActiveChange(() => {
@@ -5316,6 +5654,8 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5316
5654
  // forward the resize event to the group since if you want to resize a panel
5317
5655
  // you are actually just resizing the panels parent which is the group
5318
5656
  this.group.api.setSize(event);
5657
+ }), this.api.onDidRendererChange((event) => {
5658
+ this.group.model.rerender(this);
5319
5659
  }));
5320
5660
  }
5321
5661
  init(params) {
@@ -5335,6 +5675,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5335
5675
  ? this._params
5336
5676
  : undefined,
5337
5677
  title: this.title,
5678
+ renderer: this._renderer,
5338
5679
  };
5339
5680
  }
5340
5681
  setTitle(title) {
@@ -5350,6 +5691,15 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5350
5691
  this.api._onDidTitleChange.fire({ title });
5351
5692
  }
5352
5693
  }
5694
+ setRenderer(renderer) {
5695
+ const didChange = renderer !== this.renderer;
5696
+ if (didChange) {
5697
+ this._renderer = renderer;
5698
+ this.api._onDidRendererChange.fire({
5699
+ renderer: renderer,
5700
+ });
5701
+ }
5702
+ }
5353
5703
  update(event) {
5354
5704
  var _a;
5355
5705
  // merge the new parameters with the existing parameters
@@ -5568,8 +5918,8 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5568
5918
  }
5569
5919
 
5570
5920
  class DefaultDockviewDeserialzier {
5571
- constructor(layout) {
5572
- this.layout = layout;
5921
+ constructor(accessor) {
5922
+ this.accessor = accessor;
5573
5923
  }
5574
5924
  fromJSON(panelData, group) {
5575
5925
  var _a, _b;
@@ -5583,8 +5933,10 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5583
5933
  const tabComponent = viewData
5584
5934
  ? (_b = viewData.tab) === null || _b === void 0 ? void 0 : _b.id
5585
5935
  : panelData.tabComponent;
5586
- const view = new DockviewPanelModel(this.layout, panelId, contentComponent, tabComponent);
5587
- const panel = new DockviewPanel(panelId, this.layout, new DockviewApi(this.layout), group, view);
5936
+ const view = new DockviewPanelModel(this.accessor, panelId, contentComponent, tabComponent);
5937
+ const panel = new DockviewPanel(panelId, this.accessor, new DockviewApi(this.accessor), group, view, {
5938
+ renderer: panelData.renderer,
5939
+ });
5588
5940
  panel.init({
5589
5941
  title: title !== null && title !== void 0 ? title : panelId,
5590
5942
  params: params !== null && params !== void 0 ? params : {},
@@ -5964,7 +6316,265 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5964
6316
  }
5965
6317
  }
5966
6318
 
6319
+ class PopoutWindow extends CompositeDisposable {
6320
+ constructor(id, className, options) {
6321
+ super();
6322
+ this.id = id;
6323
+ this.className = className;
6324
+ this.options = options;
6325
+ this._onDidClose = new Emitter();
6326
+ this.onDidClose = this._onDidClose.event;
6327
+ this._window = null;
6328
+ this.addDisposables(this._onDidClose, {
6329
+ dispose: () => {
6330
+ this.close();
6331
+ },
6332
+ });
6333
+ }
6334
+ dimensions() {
6335
+ if (!this._window) {
6336
+ return null;
6337
+ }
6338
+ const left = this._window.value.screenX;
6339
+ const top = this._window.value.screenY;
6340
+ const width = this._window.value.innerWidth;
6341
+ const height = this._window.value.innerHeight;
6342
+ return { top, left, width, height };
6343
+ }
6344
+ close() {
6345
+ if (this._window) {
6346
+ this._window.disposable.dispose();
6347
+ this._window.value.close();
6348
+ this._window = null;
6349
+ }
6350
+ }
6351
+ open(content) {
6352
+ if (this._window) {
6353
+ throw new Error('instance of popout window is already open');
6354
+ }
6355
+ const url = `${this.options.url}`;
6356
+ const features = Object.entries({
6357
+ top: this.options.top,
6358
+ left: this.options.left,
6359
+ width: this.options.width,
6360
+ height: this.options.height,
6361
+ })
6362
+ .map(([key, value]) => `${key}=${value}`)
6363
+ .join(',');
6364
+ // https://developer.mozilla.org/en-US/docs/Web/API/Window/open
6365
+ const externalWindow = window.open(url, this.id, features);
6366
+ if (!externalWindow) {
6367
+ return;
6368
+ }
6369
+ const disposable = new CompositeDisposable();
6370
+ this._window = { value: externalWindow, disposable };
6371
+ const cleanUp = () => {
6372
+ this._onDidClose.fire();
6373
+ this._window = null;
6374
+ };
6375
+ // prevent any default content from loading
6376
+ // externalWindow.document.body.replaceWith(document.createElement('div'));
6377
+ disposable.addDisposables(addDisposableWindowListener(window, 'beforeunload', () => {
6378
+ cleanUp();
6379
+ this.close();
6380
+ }));
6381
+ externalWindow.addEventListener('load', () => {
6382
+ const externalDocument = externalWindow.document;
6383
+ externalDocument.title = document.title;
6384
+ const div = document.createElement('div');
6385
+ div.classList.add('dv-popout-window');
6386
+ div.style.position = 'absolute';
6387
+ div.style.width = '100%';
6388
+ div.style.height = '100%';
6389
+ div.style.top = '0px';
6390
+ div.style.left = '0px';
6391
+ div.classList.add(this.className);
6392
+ div.appendChild(content);
6393
+ externalDocument.body.replaceChildren(div);
6394
+ externalDocument.body.classList.add(this.className);
6395
+ addStyles(externalDocument, window.document.styleSheets);
6396
+ externalWindow.addEventListener('beforeunload', () => {
6397
+ // TODO: indicate external window is closing
6398
+ cleanUp();
6399
+ });
6400
+ });
6401
+ }
6402
+ }
6403
+
6404
+ class DockviewPopoutGroupPanel extends CompositeDisposable {
6405
+ constructor(id, group, options) {
6406
+ var _a;
6407
+ super();
6408
+ this.id = id;
6409
+ this.group = group;
6410
+ this.options = options;
6411
+ this.window = new PopoutWindow(id, (_a = options.className) !== null && _a !== void 0 ? _a : '', {
6412
+ url: this.options.popoutUrl,
6413
+ left: this.options.box.left,
6414
+ top: this.options.box.top,
6415
+ width: this.options.box.width,
6416
+ height: this.options.box.height,
6417
+ });
6418
+ group.model.location = 'popout';
6419
+ this.addDisposables(this.window, {
6420
+ dispose: () => {
6421
+ group.model.location = 'grid';
6422
+ },
6423
+ }, this.window.onDidClose(() => {
6424
+ this.dispose();
6425
+ }));
6426
+ this.window.open(group.element);
6427
+ }
6428
+ }
6429
+
5967
6430
  const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100;
6431
+ const DEFAULT_FLOATING_GROUP_POSITION = { left: 100, top: 100 };
6432
+
6433
+ function createFocusableElement() {
6434
+ const element = document.createElement('div');
6435
+ element.tabIndex = -1;
6436
+ return element;
6437
+ }
6438
+ class OverlayRenderContainer extends CompositeDisposable {
6439
+ constructor(element) {
6440
+ super();
6441
+ this.element = element;
6442
+ this.map = {};
6443
+ this.addDisposables(Disposable.from(() => {
6444
+ for (const value of Object.values(this.map)) {
6445
+ value.disposable.dispose();
6446
+ value.destroy.dispose();
6447
+ }
6448
+ }));
6449
+ }
6450
+ detatch(panel) {
6451
+ if (this.map[panel.api.id]) {
6452
+ const { disposable, destroy } = this.map[panel.api.id];
6453
+ disposable.dispose();
6454
+ destroy.dispose();
6455
+ delete this.map[panel.api.id];
6456
+ return true;
6457
+ }
6458
+ return false;
6459
+ }
6460
+ attach(options) {
6461
+ const { panel, referenceContainer } = options;
6462
+ if (!this.map[panel.api.id]) {
6463
+ const element = createFocusableElement();
6464
+ element.className = 'dv-render-overlay';
6465
+ this.map[panel.api.id] = {
6466
+ panel,
6467
+ disposable: Disposable.NONE,
6468
+ destroy: Disposable.NONE,
6469
+ element,
6470
+ };
6471
+ }
6472
+ const focusContainer = this.map[panel.api.id].element;
6473
+ if (panel.view.content.element.parentElement !== focusContainer) {
6474
+ focusContainer.appendChild(panel.view.content.element);
6475
+ }
6476
+ if (focusContainer.parentElement !== this.element) {
6477
+ this.element.appendChild(focusContainer);
6478
+ }
6479
+ const resize = () => {
6480
+ // TODO propagate position to avoid getDomNodePagePosition calls, possible performance bottleneck?
6481
+ const box = getDomNodePagePosition(referenceContainer.element);
6482
+ const box2 = getDomNodePagePosition(this.element);
6483
+ focusContainer.style.left = `${box.left - box2.left}px`;
6484
+ focusContainer.style.top = `${box.top - box2.top}px`;
6485
+ focusContainer.style.width = `${box.width}px`;
6486
+ focusContainer.style.height = `${box.height}px`;
6487
+ toggleClass(focusContainer, 'dv-render-overlay-float', panel.group.api.location === 'floating');
6488
+ };
6489
+ const visibilityChanged = () => {
6490
+ if (panel.api.isVisible) {
6491
+ resize();
6492
+ }
6493
+ focusContainer.style.display = panel.api.isVisible ? '' : 'none';
6494
+ };
6495
+ const disposable = new CompositeDisposable(
6496
+ /**
6497
+ * since container is positioned absoutely we must explicitly forward
6498
+ * the dnd events for the expect behaviours to continue to occur in terms of dnd
6499
+ *
6500
+ * the dnd observer does not need to be conditional on whether the panel is visible since
6501
+ * non-visible panels are 'display: none' and in such case the dnd observer will not fire.
6502
+ */
6503
+ new DragAndDropObserver(focusContainer, {
6504
+ onDragEnd: (e) => {
6505
+ referenceContainer.dropTarget.dnd.onDragEnd(e);
6506
+ },
6507
+ onDragEnter: (e) => {
6508
+ referenceContainer.dropTarget.dnd.onDragEnter(e);
6509
+ },
6510
+ onDragLeave: (e) => {
6511
+ referenceContainer.dropTarget.dnd.onDragLeave(e);
6512
+ },
6513
+ onDrop: (e) => {
6514
+ referenceContainer.dropTarget.dnd.onDrop(e);
6515
+ },
6516
+ onDragOver: (e) => {
6517
+ referenceContainer.dropTarget.dnd.onDragOver(e);
6518
+ },
6519
+ }), panel.api.onDidVisibilityChange((event) => {
6520
+ /**
6521
+ * Control the visibility of the content, however even when not visible (display: none)
6522
+ * the content is still maintained within the DOM hence DOM specific attributes
6523
+ * such as scroll position are maintained when next made visible.
6524
+ */
6525
+ visibilityChanged();
6526
+ }), panel.api.onDidDimensionsChange(() => {
6527
+ if (!panel.api.isVisible) {
6528
+ return;
6529
+ }
6530
+ resize();
6531
+ }));
6532
+ this.map[panel.api.id].destroy = Disposable.from(() => {
6533
+ focusContainer.removeChild(panel.view.content.element);
6534
+ this.element.removeChild(focusContainer);
6535
+ });
6536
+ queueMicrotask(() => {
6537
+ if (this.isDisposed) {
6538
+ return;
6539
+ }
6540
+ /**
6541
+ * wait until everything has finished in the current stack-frame call before
6542
+ * calling the first resize as other size-altering events may still occur before
6543
+ * the end of the stack-frame.
6544
+ */
6545
+ visibilityChanged();
6546
+ });
6547
+ // dispose of logic asoccciated with previous reference-container
6548
+ this.map[panel.api.id].disposable.dispose();
6549
+ // and reset the disposable to the active reference-container
6550
+ this.map[panel.api.id].disposable = disposable;
6551
+ return focusContainer;
6552
+ }
6553
+ }
6554
+
6555
+ const DEFAULT_ROOT_OVERLAY_MODEL = {
6556
+ activationSize: { type: 'pixels', value: 10 },
6557
+ size: { type: 'pixels', value: 20 },
6558
+ };
6559
+ function getTheme(element) {
6560
+ function toClassList(element) {
6561
+ const list = [];
6562
+ for (let i = 0; i < element.classList.length; i++) {
6563
+ list.push(element.classList.item(i));
6564
+ }
6565
+ return list;
6566
+ }
6567
+ let theme = undefined;
6568
+ let parent = element;
6569
+ while (parent !== null) {
6570
+ theme = toClassList(parent).find((cls) => cls.startsWith('dockview-theme-'));
6571
+ if (typeof theme === 'string') {
6572
+ break;
6573
+ }
6574
+ parent = parent.parentElement;
6575
+ }
6576
+ return theme;
6577
+ }
5968
6578
  class DockviewComponent extends BaseGrid {
5969
6579
  get orientation() {
5970
6580
  return this.gridview.orientation;
@@ -5985,8 +6595,12 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5985
6595
  }
5986
6596
  return activeGroup.activePanel;
5987
6597
  }
5988
- constructor(options) {
6598
+ get renderer() {
5989
6599
  var _a;
6600
+ return (_a = this.options.defaultRenderer) !== null && _a !== void 0 ? _a : 'onlyWhenVisibile';
6601
+ }
6602
+ constructor(options) {
6603
+ var _a, _b;
5990
6604
  super({
5991
6605
  proportionalLayout: true,
5992
6606
  orientation: (_a = options.orientation) !== null && _a !== void 0 ? _a : exports.Orientation.HORIZONTAL,
@@ -6011,12 +6625,27 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6011
6625
  this.onDidLayoutFromJSON = this._onDidLayoutFromJSON.event;
6012
6626
  this._onDidActivePanelChange = new Emitter();
6013
6627
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
6014
- this.floatingGroups = [];
6628
+ this._floatingGroups = [];
6629
+ this._popoutGroups = [];
6630
+ const gready = document.createElement('div');
6631
+ gready.className = 'dv-overlay-render-container';
6632
+ this.gridview.element.appendChild(gready);
6633
+ this.overlayRenderContainer = new OverlayRenderContainer(gready);
6015
6634
  toggleClass(this.gridview.element, 'dv-dockview', true);
6016
- this.addDisposables(this._onWillDragPanel, this._onWillDragGroup, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
6635
+ toggleClass(this.element, 'dv-debug', !!options.debug);
6636
+ 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)(() => {
6017
6637
  this.updateWatermark();
6018
6638
  }), exports.DockviewEvent.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => {
6019
6639
  this._bufferOnDidLayoutChange.fire();
6640
+ }), Disposable.from(() => {
6641
+ // iterate over a copy of the array since .dispose() mutates the original array
6642
+ for (const group of [...this._floatingGroups]) {
6643
+ group.dispose();
6644
+ }
6645
+ // iterate over a copy of the array since .dispose() mutates the original array
6646
+ for (const group of [...this._popoutGroups]) {
6647
+ group.dispose();
6648
+ }
6020
6649
  }));
6021
6650
  this._options = options;
6022
6651
  if (!this.options.components) {
@@ -6035,7 +6664,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6035
6664
  !this.options.watermarkFrameworkComponent) {
6036
6665
  this.options.watermarkComponent = Watermark;
6037
6666
  }
6038
- const dropTarget = new Droptarget(this.element, {
6667
+ this._rootDropTarget = new Droptarget(this.element, {
6039
6668
  canDisplayOverlay: (event, position) => {
6040
6669
  const data = getPanelData();
6041
6670
  if (data) {
@@ -6068,12 +6697,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6068
6697
  return false;
6069
6698
  },
6070
6699
  acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
6071
- overlayModel: {
6072
- activationSize: { type: 'pixels', value: 10 },
6073
- size: { type: 'pixels', value: 20 },
6074
- },
6700
+ overlayModel: (_b = this.options.rootOverlayModel) !== null && _b !== void 0 ? _b : DEFAULT_ROOT_OVERLAY_MODEL,
6075
6701
  });
6076
- this.addDisposables(dropTarget.onDrop((event) => {
6702
+ this.addDisposables(this._rootDropTarget.onDrop((event) => {
6077
6703
  var _a;
6078
6704
  const data = getPanelData();
6079
6705
  if (data) {
@@ -6082,10 +6708,59 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6082
6708
  else {
6083
6709
  this._onDidDrop.fire(Object.assign(Object.assign({}, event), { api: this._api, group: null, getData: getPanelData }));
6084
6710
  }
6085
- }), dropTarget);
6711
+ }), this._rootDropTarget);
6086
6712
  this._api = new DockviewApi(this);
6087
6713
  this.updateWatermark();
6088
6714
  }
6715
+ addPopoutGroup(item, options) {
6716
+ var _a;
6717
+ let group;
6718
+ let box = options === null || options === void 0 ? void 0 : options.position;
6719
+ if (item instanceof DockviewPanel) {
6720
+ group = this.createGroup();
6721
+ this.removePanel(item, {
6722
+ removeEmptyGroup: true,
6723
+ skipDispose: true,
6724
+ });
6725
+ group.model.openPanel(item);
6726
+ if (!box) {
6727
+ box = this.element.getBoundingClientRect();
6728
+ }
6729
+ }
6730
+ else {
6731
+ group = item;
6732
+ if (!box) {
6733
+ box = group.element.getBoundingClientRect();
6734
+ }
6735
+ const skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' &&
6736
+ options.skipRemoveGroup;
6737
+ if (!skip) {
6738
+ this.doRemoveGroup(item, { skipDispose: true });
6739
+ }
6740
+ }
6741
+ const theme = getTheme(this.gridview.element);
6742
+ const popoutWindow = new DockviewPopoutGroupPanel(`${this.id}-${group.id}`, // globally unique within dockview
6743
+ group, {
6744
+ className: theme !== null && theme !== void 0 ? theme : '',
6745
+ popoutUrl: (_a = options === null || options === void 0 ? void 0 : options.popoutUrl) !== null && _a !== void 0 ? _a : '/popout.html',
6746
+ box: {
6747
+ left: window.screenX + box.left,
6748
+ top: window.screenY + box.top,
6749
+ width: box.width,
6750
+ height: box.height,
6751
+ },
6752
+ });
6753
+ popoutWindow.addDisposables({
6754
+ dispose: () => {
6755
+ remove(this._popoutGroups, popoutWindow);
6756
+ this.updateWatermark();
6757
+ },
6758
+ }, popoutWindow.window.onDidClose(() => {
6759
+ this.doAddGroup(group, [0]);
6760
+ }));
6761
+ this._popoutGroups.push(popoutWindow);
6762
+ this.updateWatermark();
6763
+ }
6089
6764
  addFloatingGroup(item, coord, options) {
6090
6765
  var _a, _b, _c, _d, _e, _f;
6091
6766
  let group;
@@ -6105,9 +6780,13 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6105
6780
  this.doRemoveGroup(item, { skipDispose: true });
6106
6781
  }
6107
6782
  }
6108
- group.model.isFloating = true;
6109
- const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number' ? Math.max(coord.x, 0) : 100;
6110
- const overlayTop = typeof (coord === null || coord === void 0 ? void 0 : coord.y) === 'number' ? Math.max(coord.y, 0) : 100;
6783
+ group.model.location = 'floating';
6784
+ const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number'
6785
+ ? Math.max(coord.x, 0)
6786
+ : DEFAULT_FLOATING_GROUP_POSITION.left;
6787
+ const overlayTop = typeof (coord === null || coord === void 0 ? void 0 : coord.y) === 'number'
6788
+ ? Math.max(coord.y, 0)
6789
+ : DEFAULT_FLOATING_GROUP_POSITION.top;
6111
6790
  const overlay = new Overlay({
6112
6791
  container: this.gridview.element,
6113
6792
  content: group.element,
@@ -6151,12 +6830,12 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6151
6830
  }), {
6152
6831
  dispose: () => {
6153
6832
  disposable.dispose();
6154
- group.model.isFloating = false;
6155
- remove(this.floatingGroups, floatingGroupPanel);
6833
+ group.model.location = 'grid';
6834
+ remove(this._floatingGroups, floatingGroupPanel);
6156
6835
  this.updateWatermark();
6157
6836
  },
6158
6837
  });
6159
- this.floatingGroups.push(floatingGroupPanel);
6838
+ this._floatingGroups.push(floatingGroupPanel);
6160
6839
  this.updateWatermark();
6161
6840
  }
6162
6841
  orthogonalize(position) {
@@ -6192,16 +6871,18 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6192
6871
  }
6193
6872
  updateOptions(options) {
6194
6873
  var _a, _b;
6195
- const hasOrientationChanged = typeof options.orientation === 'string' &&
6874
+ const changed_orientation = typeof options.orientation === 'string' &&
6196
6875
  this.gridview.orientation !== options.orientation;
6197
- const hasFloatingGroupOptionsChanged = options.floatingGroupBounds !== undefined &&
6876
+ const changed_floatingGroupBounds = options.floatingGroupBounds !== undefined &&
6198
6877
  options.floatingGroupBounds !== this.options.floatingGroupBounds;
6878
+ const changed_rootOverlayOptions = options.rootOverlayModel !== undefined &&
6879
+ options.rootOverlayModel !== this.options.rootOverlayModel;
6199
6880
  this._options = Object.assign(Object.assign({}, this.options), options);
6200
- if (hasOrientationChanged) {
6881
+ if (changed_orientation) {
6201
6882
  this.gridview.orientation = options.orientation;
6202
6883
  }
6203
- if (hasFloatingGroupOptionsChanged) {
6204
- for (const group of this.floatingGroups) {
6884
+ if (changed_floatingGroupBounds) {
6885
+ for (const group of this._floatingGroups) {
6205
6886
  switch (this.options.floatingGroupBounds) {
6206
6887
  case 'boundedWithinViewport':
6207
6888
  group.overlay.minimumInViewportHeight = undefined;
@@ -6222,12 +6903,15 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6222
6903
  group.overlay.setBounds({});
6223
6904
  }
6224
6905
  }
6906
+ if (changed_rootOverlayOptions) {
6907
+ this._rootDropTarget.setOverlayModel(options.rootOverlayModel);
6908
+ }
6225
6909
  this.layout(this.gridview.width, this.gridview.height, true);
6226
6910
  }
6227
6911
  layout(width, height, forceResize) {
6228
6912
  super.layout(width, height, forceResize);
6229
- if (this.floatingGroups) {
6230
- for (const floating of this.floatingGroups) {
6913
+ if (this._floatingGroups) {
6914
+ for (const floating of this._floatingGroups) {
6231
6915
  // ensure floting groups stay within visible boundaries
6232
6916
  floating.overlay.setBounds();
6233
6917
  }
@@ -6295,10 +6979,16 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6295
6979
  collection[panel.id] = panel.toJSON();
6296
6980
  return collection;
6297
6981
  }, {});
6298
- const floats = this.floatingGroups.map((floatingGroup) => {
6982
+ const floats = this._floatingGroups.map((group) => {
6299
6983
  return {
6300
- data: floatingGroup.group.toJSON(),
6301
- position: floatingGroup.overlay.toJSON(),
6984
+ data: group.group.toJSON(),
6985
+ position: group.overlay.toJSON(),
6986
+ };
6987
+ });
6988
+ const popoutGroups = this._popoutGroups.map((group) => {
6989
+ return {
6990
+ data: group.group.toJSON(),
6991
+ position: group.window.dimensions(),
6302
6992
  };
6303
6993
  });
6304
6994
  const result = {
@@ -6309,10 +6999,13 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6309
6999
  if (floats.length > 0) {
6310
7000
  result.floatingGroups = floats;
6311
7001
  }
7002
+ if (popoutGroups.length > 0) {
7003
+ result.popoutGroups = popoutGroups;
7004
+ }
6312
7005
  return result;
6313
7006
  }
6314
7007
  fromJSON(data) {
6315
- var _a;
7008
+ var _a, _b;
6316
7009
  this.clear();
6317
7010
  if (typeof data !== 'object' || data === null) {
6318
7011
  throw new Error('serialized layout must be a non-null object');
@@ -6379,7 +7072,16 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6379
7072
  width: position.width,
6380
7073
  }, { skipRemoveGroup: true, inDragMode: false });
6381
7074
  }
6382
- for (const floatingGroup of this.floatingGroups) {
7075
+ const serializedPopoutGroups = (_b = data.popoutGroups) !== null && _b !== void 0 ? _b : [];
7076
+ for (const serializedPopoutGroup of serializedPopoutGroups) {
7077
+ const { data, position } = serializedPopoutGroup;
7078
+ const group = createGroupFromSerializedState(data);
7079
+ this.addPopoutGroup(group, {
7080
+ skipRemoveGroup: true,
7081
+ position: position !== null && position !== void 0 ? position : undefined,
7082
+ });
7083
+ }
7084
+ for (const floatingGroup of this._floatingGroups) {
6383
7085
  floatingGroup.overlay.setBounds();
6384
7086
  }
6385
7087
  if (typeof activeGroup === 'string') {
@@ -6411,7 +7113,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6411
7113
  this._onDidRemoveGroup.fire(group);
6412
7114
  }
6413
7115
  // iterate over a reassigned array since original array will be modified
6414
- for (const floatingGroup of [...this.floatingGroups]) {
7116
+ for (const floatingGroup of [...this._floatingGroups]) {
6415
7117
  floatingGroup.dispose();
6416
7118
  }
6417
7119
  // fires clean-up events and clears the underlying HTML gridview.
@@ -6503,7 +7205,8 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6503
7205
  group.model.openPanel(panel);
6504
7206
  this.doSetGroupAndPanelActive(group);
6505
7207
  }
6506
- else if (referenceGroup.api.isFloating || target === 'center') {
7208
+ else if (referenceGroup.api.location === 'floating' ||
7209
+ target === 'center') {
6507
7210
  panel = this.createPanel(options, referenceGroup);
6508
7211
  referenceGroup.model.openPanel(panel);
6509
7212
  }
@@ -6547,6 +7250,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6547
7250
  }
6548
7251
  group.model.removePanel(panel);
6549
7252
  if (!options.skipDispose) {
7253
+ this.overlayRenderContainer.detatch(panel);
6550
7254
  panel.dispose();
6551
7255
  }
6552
7256
  if (group.size === 0 && options.removeEmptyGroup) {
@@ -6563,7 +7267,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6563
7267
  }
6564
7268
  updateWatermark() {
6565
7269
  var _a, _b;
6566
- if (this.groups.filter((x) => !x.api.isFloating).length === 0) {
7270
+ if (this.groups.filter((x) => x.api.location === 'grid').length === 0) {
6567
7271
  if (!this.watermark) {
6568
7272
  this.watermark = this.createWatermarkComponent();
6569
7273
  this.watermark.init({
@@ -6638,19 +7342,40 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6638
7342
  }
6639
7343
  }
6640
7344
  doRemoveGroup(group, options) {
6641
- const floatingGroup = this.floatingGroups.find((_) => _.group === group);
6642
- if (floatingGroup) {
6643
- if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
6644
- floatingGroup.group.dispose();
6645
- this._groups.delete(group.id);
6646
- this._onDidRemoveGroup.fire(group);
7345
+ if (group.api.location === 'floating') {
7346
+ const floatingGroup = this._floatingGroups.find((_) => _.group === group);
7347
+ if (floatingGroup) {
7348
+ if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
7349
+ floatingGroup.group.dispose();
7350
+ this._groups.delete(group.id);
7351
+ this._onDidRemoveGroup.fire(group);
7352
+ }
7353
+ remove(this._floatingGroups, floatingGroup);
7354
+ floatingGroup.dispose();
7355
+ if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
7356
+ const groups = Array.from(this._groups.values());
7357
+ this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7358
+ }
7359
+ return floatingGroup.group;
6647
7360
  }
6648
- floatingGroup.dispose();
6649
- if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
6650
- const groups = Array.from(this._groups.values());
6651
- this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7361
+ throw new Error('failed to find floating group');
7362
+ }
7363
+ if (group.api.location === 'popout') {
7364
+ const selectedGroup = this._popoutGroups.find((_) => _.group === group);
7365
+ if (selectedGroup) {
7366
+ if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
7367
+ selectedGroup.group.dispose();
7368
+ this._groups.delete(group.id);
7369
+ this._onDidRemoveGroup.fire(group);
7370
+ }
7371
+ selectedGroup.dispose();
7372
+ if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
7373
+ const groups = Array.from(this._groups.values());
7374
+ this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7375
+ }
7376
+ return selectedGroup.group;
6652
7377
  }
6653
- return floatingGroup.group;
7378
+ throw new Error('failed to find popout group');
6654
7379
  }
6655
7380
  return super.doRemoveGroup(group, options);
6656
7381
  }
@@ -6682,8 +7407,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6682
7407
  const targetLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
6683
7408
  if (sourceGroup && sourceGroup.size < 2) {
6684
7409
  const [targetParentLocation, to] = tail(targetLocation);
6685
- const isFloating = this.floatingGroups.find((x) => x.group === sourceGroup);
6686
- if (!isFloating) {
7410
+ if (sourceGroup.api.location === 'grid') {
6687
7411
  const sourceLocation = getGridLocation(sourceGroup.element);
6688
7412
  const [sourceParentLocation, from] = tail(sourceLocation);
6689
7413
  if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
@@ -6729,12 +7453,25 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6729
7453
  }
6730
7454
  }
6731
7455
  else {
6732
- const floatingGroup = this.floatingGroups.find((x) => x.group === sourceGroup);
6733
- if (floatingGroup) {
6734
- floatingGroup.dispose();
6735
- }
6736
- else {
6737
- this.gridview.removeView(getGridLocation(sourceGroup.element));
7456
+ switch (sourceGroup.api.location) {
7457
+ case 'grid':
7458
+ this.gridview.removeView(getGridLocation(sourceGroup.element));
7459
+ break;
7460
+ case 'floating': {
7461
+ const selectedFloatingGroup = this._floatingGroups.find((x) => x.group === sourceGroup);
7462
+ if (!selectedFloatingGroup) {
7463
+ throw new Error('failed to find floating group');
7464
+ }
7465
+ selectedFloatingGroup.dispose();
7466
+ break;
7467
+ }
7468
+ case 'popout': {
7469
+ const selectedPopoutGroup = this._popoutGroups.find((x) => x.group === sourceGroup);
7470
+ if (!selectedPopoutGroup) {
7471
+ throw new Error('failed to find popout group');
7472
+ }
7473
+ selectedPopoutGroup.dispose();
7474
+ }
6738
7475
  }
6739
7476
  const referenceLocation = getGridLocation(referenceGroup.element);
6740
7477
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, target);
@@ -6796,7 +7533,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6796
7533
  const contentComponent = options.component;
6797
7534
  const tabComponent = (_a = options.tabComponent) !== null && _a !== void 0 ? _a : this.options.defaultTabComponent;
6798
7535
  const view = new DockviewPanelModel(this, options.id, contentComponent, tabComponent);
6799
- const panel = new DockviewPanel(options.id, this, this._api, group, view);
7536
+ const panel = new DockviewPanel(options.id, this, this._api, group, view, { renderer: options.renderer });
6800
7537
  panel.init({
6801
7538
  title: (_b = options.title) !== null && _b !== void 0 ? _b : options.id,
6802
7539
  params: (_c = options === null || options === void 0 ? void 0 : options.params) !== null && _c !== void 0 ? _c : {},
@@ -8142,6 +8879,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
8142
8879
  singleTabMode: props.singleTabMode,
8143
8880
  disableFloatingGroups: props.disableFloatingGroups,
8144
8881
  floatingGroupBounds: props.floatingGroupBounds,
8882
+ defaultRenderer: props.defaultRenderer,
8883
+ debug: props.debug,
8884
+ rootOverlayModel: props.rootOverlayModel,
8145
8885
  });
8146
8886
  const { clientWidth, clientHeight } = domRef.current;
8147
8887
  dockview.layout(clientWidth, clientHeight);
@@ -8249,6 +8989,14 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
8249
8989
  createLeftHeaderActionsElement: createGroupControlElement(props.leftHeaderActionsComponent, { addPortal }),
8250
8990
  });
8251
8991
  }, [props.leftHeaderActionsComponent]);
8992
+ React__namespace.useEffect(() => {
8993
+ if (!dockviewRef.current) {
8994
+ return;
8995
+ }
8996
+ dockviewRef.current.updateOptions({
8997
+ rootOverlayModel: props.rootOverlayModel,
8998
+ });
8999
+ }, [props.rootOverlayModel]);
8252
9000
  React__namespace.useEffect(() => {
8253
9001
  if (!dockviewRef.current) {
8254
9002
  return;