dockview-core 1.7.5 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/README.md +2 -1
  2. package/dist/cjs/api/component.api.d.ts +6 -1
  3. package/dist/cjs/api/component.api.d.ts.map +1 -1
  4. package/dist/cjs/api/component.api.js +6 -0
  5. package/dist/cjs/api/component.api.js.map +1 -1
  6. package/dist/cjs/api/dockviewGroupPanelApi.d.ts +30 -0
  7. package/dist/cjs/api/dockviewGroupPanelApi.d.ts.map +1 -0
  8. package/dist/cjs/api/dockviewGroupPanelApi.js +54 -0
  9. package/dist/cjs/api/dockviewGroupPanelApi.js.map +1 -0
  10. package/dist/cjs/api/dockviewPanelApi.d.ts +14 -1
  11. package/dist/cjs/api/dockviewPanelApi.d.ts.map +1 -1
  12. package/dist/cjs/api/dockviewPanelApi.js +6 -1
  13. package/dist/cjs/api/dockviewPanelApi.js.map +1 -1
  14. package/dist/cjs/array.d.ts +1 -0
  15. package/dist/cjs/array.d.ts.map +1 -1
  16. package/dist/cjs/array.js +10 -1
  17. package/dist/cjs/array.js.map +1 -1
  18. package/dist/cjs/dnd/abstractDragHandler.d.ts +1 -0
  19. package/dist/cjs/dnd/abstractDragHandler.d.ts.map +1 -1
  20. package/dist/cjs/dnd/abstractDragHandler.js +7 -0
  21. package/dist/cjs/dnd/abstractDragHandler.js.map +1 -1
  22. package/dist/cjs/dnd/droptarget.d.ts +11 -0
  23. package/dist/cjs/dnd/droptarget.d.ts.map +1 -1
  24. package/dist/cjs/dnd/droptarget.js +32 -9
  25. package/dist/cjs/dnd/droptarget.js.map +1 -1
  26. package/dist/cjs/dnd/groupDragHandler.d.ts +1 -0
  27. package/dist/cjs/dnd/groupDragHandler.d.ts.map +1 -1
  28. package/dist/cjs/dnd/groupDragHandler.js +18 -0
  29. package/dist/cjs/dnd/groupDragHandler.js.map +1 -1
  30. package/dist/cjs/dnd/overlay.d.ts +40 -0
  31. package/dist/cjs/dnd/overlay.d.ts.map +1 -0
  32. package/dist/cjs/dnd/overlay.js +382 -0
  33. package/dist/cjs/dnd/overlay.js.map +1 -0
  34. package/dist/cjs/dockview/components/tab/tab.d.ts +2 -2
  35. package/dist/cjs/dockview/components/tab/tab.d.ts.map +1 -1
  36. package/dist/cjs/dockview/components/tab/tab.js +0 -7
  37. package/dist/cjs/dockview/components/tab/tab.js.map +1 -1
  38. package/dist/cjs/dockview/components/titlebar/tabsContainer.d.ts +8 -4
  39. package/dist/cjs/dockview/components/titlebar/tabsContainer.d.ts.map +1 -1
  40. package/dist/cjs/dockview/components/titlebar/tabsContainer.js +54 -10
  41. package/dist/cjs/dockview/components/titlebar/tabsContainer.js.map +1 -1
  42. package/dist/cjs/dockview/deserializer.d.ts +2 -2
  43. package/dist/cjs/dockview/deserializer.d.ts.map +1 -1
  44. package/dist/cjs/dockview/deserializer.js.map +1 -1
  45. package/dist/cjs/dockview/dockviewComponent.d.ts +41 -9
  46. package/dist/cjs/dockview/dockviewComponent.d.ts.map +1 -1
  47. package/dist/cjs/dockview/dockviewComponent.js +277 -76
  48. package/dist/cjs/dockview/dockviewComponent.js.map +1 -1
  49. package/dist/cjs/dockview/dockviewFloatingGroupPanel.d.ts +24 -0
  50. package/dist/cjs/dockview/dockviewFloatingGroupPanel.d.ts.map +1 -0
  51. package/dist/cjs/dockview/dockviewFloatingGroupPanel.js +35 -0
  52. package/dist/cjs/dockview/dockviewFloatingGroupPanel.js.map +1 -0
  53. package/dist/cjs/dockview/dockviewGroupPanel.d.ts +5 -6
  54. package/dist/cjs/dockview/dockviewGroupPanel.d.ts.map +1 -1
  55. package/dist/cjs/dockview/dockviewGroupPanel.js +3 -2
  56. package/dist/cjs/dockview/dockviewGroupPanel.js.map +1 -1
  57. package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts +5 -1
  58. package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts.map +1 -1
  59. package/dist/cjs/dockview/dockviewGroupPanelModel.js +43 -12
  60. package/dist/cjs/dockview/dockviewGroupPanelModel.js.map +1 -1
  61. package/dist/cjs/dockview/dockviewPanel.d.ts +2 -2
  62. package/dist/cjs/dockview/dockviewPanel.d.ts.map +1 -1
  63. package/dist/cjs/dockview/dockviewPanel.js +1 -1
  64. package/dist/cjs/dockview/dockviewPanel.js.map +1 -1
  65. package/dist/cjs/dockview/options.d.ts +22 -6
  66. package/dist/cjs/dockview/options.d.ts.map +1 -1
  67. package/dist/cjs/dockview/options.js.map +1 -1
  68. package/dist/cjs/dom.d.ts +5 -3
  69. package/dist/cjs/dom.d.ts.map +1 -1
  70. package/dist/cjs/dom.js +13 -1
  71. package/dist/cjs/dom.js.map +1 -1
  72. package/dist/cjs/events.d.ts.map +1 -1
  73. package/dist/cjs/gridview/branchNode.js +2 -2
  74. package/dist/cjs/gridview/branchNode.js.map +1 -1
  75. package/dist/cjs/gridview/gridview.d.ts.map +1 -1
  76. package/dist/cjs/gridview/gridview.js +40 -20
  77. package/dist/cjs/gridview/gridview.js.map +1 -1
  78. package/dist/cjs/gridview/gridviewComponent.d.ts.map +1 -1
  79. package/dist/cjs/gridview/gridviewComponent.js +4 -1
  80. package/dist/cjs/gridview/gridviewComponent.js.map +1 -1
  81. package/dist/cjs/gridview/gridviewPanel.d.ts +3 -3
  82. package/dist/cjs/gridview/gridviewPanel.d.ts.map +1 -1
  83. package/dist/cjs/gridview/gridviewPanel.js +2 -2
  84. package/dist/cjs/gridview/gridviewPanel.js.map +1 -1
  85. package/dist/cjs/index.d.ts +1 -1
  86. package/dist/cjs/index.d.ts.map +1 -1
  87. package/dist/cjs/index.js +1 -3
  88. package/dist/cjs/index.js.map +1 -1
  89. package/dist/cjs/math.d.ts.map +1 -1
  90. package/dist/cjs/paneview/paneviewComponent.d.ts.map +1 -1
  91. package/dist/cjs/paneview/paneviewComponent.js +4 -1
  92. package/dist/cjs/paneview/paneviewComponent.js.map +1 -1
  93. package/dist/cjs/splitview/splitview.d.ts.map +1 -1
  94. package/dist/cjs/splitview/splitview.js +12 -11
  95. package/dist/cjs/splitview/splitview.js.map +1 -1
  96. package/dist/cjs/splitview/splitviewComponent.d.ts.map +1 -1
  97. package/dist/cjs/splitview/splitviewComponent.js +4 -1
  98. package/dist/cjs/splitview/splitviewComponent.js.map +1 -1
  99. package/dist/dockview-core.amd.js +808 -158
  100. package/dist/dockview-core.amd.js.map +1 -0
  101. package/dist/dockview-core.amd.min.js +3 -2
  102. package/dist/dockview-core.amd.min.js.map +1 -0
  103. package/dist/dockview-core.amd.min.noStyle.js +3 -2
  104. package/dist/dockview-core.amd.min.noStyle.js.map +1 -0
  105. package/dist/dockview-core.amd.noStyle.js +807 -157
  106. package/dist/dockview-core.amd.noStyle.js.map +1 -0
  107. package/dist/dockview-core.cjs.js +808 -158
  108. package/dist/dockview-core.cjs.js.map +1 -0
  109. package/dist/dockview-core.esm.js +809 -158
  110. package/dist/dockview-core.esm.js.map +1 -0
  111. package/dist/dockview-core.esm.min.js +3 -2
  112. package/dist/dockview-core.esm.min.js.map +1 -0
  113. package/dist/dockview-core.js +808 -158
  114. package/dist/dockview-core.js.map +1 -0
  115. package/dist/dockview-core.min.js +3 -2
  116. package/dist/dockview-core.min.js.map +1 -0
  117. package/dist/dockview-core.min.noStyle.js +3 -2
  118. package/dist/dockview-core.min.noStyle.js.map +1 -0
  119. package/dist/dockview-core.noStyle.js +807 -157
  120. package/dist/dockview-core.noStyle.js.map +1 -0
  121. package/dist/esm/api/component.api.d.ts +6 -1
  122. package/dist/esm/api/component.api.d.ts.map +1 -1
  123. package/dist/esm/api/component.api.js +6 -0
  124. package/dist/esm/api/component.api.js.map +1 -1
  125. package/dist/esm/api/dockviewGroupPanelApi.d.ts +30 -0
  126. package/dist/esm/api/dockviewGroupPanelApi.d.ts.map +1 -0
  127. package/dist/esm/api/dockviewGroupPanelApi.js +28 -0
  128. package/dist/esm/api/dockviewGroupPanelApi.js.map +1 -0
  129. package/dist/esm/api/dockviewPanelApi.d.ts +14 -1
  130. package/dist/esm/api/dockviewPanelApi.d.ts.map +1 -1
  131. package/dist/esm/api/dockviewPanelApi.js +6 -1
  132. package/dist/esm/api/dockviewPanelApi.js.map +1 -1
  133. package/dist/esm/array.d.ts +1 -0
  134. package/dist/esm/array.d.ts.map +1 -1
  135. package/dist/esm/array.js +8 -0
  136. package/dist/esm/array.js.map +1 -1
  137. package/dist/esm/dnd/abstractDragHandler.d.ts +1 -0
  138. package/dist/esm/dnd/abstractDragHandler.d.ts.map +1 -1
  139. package/dist/esm/dnd/abstractDragHandler.js +7 -0
  140. package/dist/esm/dnd/abstractDragHandler.js.map +1 -1
  141. package/dist/esm/dnd/droptarget.d.ts +11 -0
  142. package/dist/esm/dnd/droptarget.d.ts.map +1 -1
  143. package/dist/esm/dnd/droptarget.js +32 -9
  144. package/dist/esm/dnd/droptarget.js.map +1 -1
  145. package/dist/esm/dnd/groupDragHandler.d.ts +1 -0
  146. package/dist/esm/dnd/groupDragHandler.d.ts.map +1 -1
  147. package/dist/esm/dnd/groupDragHandler.js +18 -0
  148. package/dist/esm/dnd/groupDragHandler.js.map +1 -1
  149. package/dist/esm/dnd/overlay.d.ts +40 -0
  150. package/dist/esm/dnd/overlay.d.ts.map +1 -0
  151. package/dist/esm/dnd/overlay.js +282 -0
  152. package/dist/esm/dnd/overlay.js.map +1 -0
  153. package/dist/esm/dockview/components/tab/tab.d.ts +2 -2
  154. package/dist/esm/dockview/components/tab/tab.d.ts.map +1 -1
  155. package/dist/esm/dockview/components/tab/tab.js +0 -7
  156. package/dist/esm/dockview/components/tab/tab.js.map +1 -1
  157. package/dist/esm/dockview/components/titlebar/tabsContainer.d.ts +8 -4
  158. package/dist/esm/dockview/components/titlebar/tabsContainer.d.ts.map +1 -1
  159. package/dist/esm/dockview/components/titlebar/tabsContainer.js +54 -10
  160. package/dist/esm/dockview/components/titlebar/tabsContainer.js.map +1 -1
  161. package/dist/esm/dockview/deserializer.d.ts +2 -2
  162. package/dist/esm/dockview/deserializer.d.ts.map +1 -1
  163. package/dist/esm/dockview/deserializer.js.map +1 -1
  164. package/dist/esm/dockview/dockviewComponent.d.ts +41 -9
  165. package/dist/esm/dockview/dockviewComponent.d.ts.map +1 -1
  166. package/dist/esm/dockview/dockviewComponent.js +223 -54
  167. package/dist/esm/dockview/dockviewComponent.js.map +1 -1
  168. package/dist/esm/dockview/dockviewFloatingGroupPanel.d.ts +24 -0
  169. package/dist/esm/dockview/dockviewFloatingGroupPanel.d.ts.map +1 -0
  170. package/dist/esm/dockview/dockviewFloatingGroupPanel.js +13 -0
  171. package/dist/esm/dockview/dockviewFloatingGroupPanel.js.map +1 -0
  172. package/dist/esm/dockview/dockviewGroupPanel.d.ts +5 -6
  173. package/dist/esm/dockview/dockviewGroupPanel.d.ts.map +1 -1
  174. package/dist/esm/dockview/dockviewGroupPanel.js +3 -2
  175. package/dist/esm/dockview/dockviewGroupPanel.js.map +1 -1
  176. package/dist/esm/dockview/dockviewGroupPanelModel.d.ts +5 -1
  177. package/dist/esm/dockview/dockviewGroupPanelModel.d.ts.map +1 -1
  178. package/dist/esm/dockview/dockviewGroupPanelModel.js +36 -9
  179. package/dist/esm/dockview/dockviewGroupPanelModel.js.map +1 -1
  180. package/dist/esm/dockview/dockviewPanel.d.ts +2 -2
  181. package/dist/esm/dockview/dockviewPanel.d.ts.map +1 -1
  182. package/dist/esm/dockview/dockviewPanel.js +1 -1
  183. package/dist/esm/dockview/dockviewPanel.js.map +1 -1
  184. package/dist/esm/dockview/options.d.ts +22 -6
  185. package/dist/esm/dockview/options.d.ts.map +1 -1
  186. package/dist/esm/dockview/options.js.map +1 -1
  187. package/dist/esm/dom.d.ts +5 -3
  188. package/dist/esm/dom.d.ts.map +1 -1
  189. package/dist/esm/dom.js +10 -0
  190. package/dist/esm/dom.js.map +1 -1
  191. package/dist/esm/events.d.ts.map +1 -1
  192. package/dist/esm/gridview/branchNode.js +2 -2
  193. package/dist/esm/gridview/branchNode.js.map +1 -1
  194. package/dist/esm/gridview/gridview.d.ts.map +1 -1
  195. package/dist/esm/gridview/gridview.js +40 -19
  196. package/dist/esm/gridview/gridview.js.map +1 -1
  197. package/dist/esm/gridview/gridviewComponent.d.ts.map +1 -1
  198. package/dist/esm/gridview/gridviewComponent.js +4 -1
  199. package/dist/esm/gridview/gridviewComponent.js.map +1 -1
  200. package/dist/esm/gridview/gridviewPanel.d.ts +3 -3
  201. package/dist/esm/gridview/gridviewPanel.d.ts.map +1 -1
  202. package/dist/esm/gridview/gridviewPanel.js +2 -2
  203. package/dist/esm/gridview/gridviewPanel.js.map +1 -1
  204. package/dist/esm/index.d.ts +1 -1
  205. package/dist/esm/index.d.ts.map +1 -1
  206. package/dist/esm/index.js +0 -1
  207. package/dist/esm/index.js.map +1 -1
  208. package/dist/esm/math.d.ts.map +1 -1
  209. package/dist/esm/math.js.map +1 -1
  210. package/dist/esm/paneview/paneviewComponent.d.ts.map +1 -1
  211. package/dist/esm/paneview/paneviewComponent.js +4 -1
  212. package/dist/esm/paneview/paneviewComponent.js.map +1 -1
  213. package/dist/esm/splitview/splitview.d.ts.map +1 -1
  214. package/dist/esm/splitview/splitview.js +12 -11
  215. package/dist/esm/splitview/splitview.js.map +1 -1
  216. package/dist/esm/splitview/splitviewComponent.d.ts.map +1 -1
  217. package/dist/esm/splitview/splitviewComponent.js +4 -1
  218. package/dist/esm/splitview/splitviewComponent.js.map +1 -1
  219. package/dist/styles/dockview.css +217 -1
  220. package/package.json +5 -5
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * dockview-core
3
- * @version 1.7.5
3
+ * @version 1.8.0
4
4
  * @link https://github.com/mathuo/dockview
5
5
  * @license MIT
6
6
  */
@@ -277,6 +277,31 @@
277
277
  }
278
278
  }
279
279
 
280
+ function createComponent(id, componentName, components = {}, frameworkComponents = {}, createFrameworkComponent, fallback) {
281
+ const Component = typeof componentName === 'string'
282
+ ? components[componentName]
283
+ : undefined;
284
+ const FrameworkComponent = typeof componentName === 'string'
285
+ ? frameworkComponents[componentName]
286
+ : undefined;
287
+ if (Component && FrameworkComponent) {
288
+ throw new Error(`Cannot create '${id}'. component '${componentName}' registered as both a component and frameworkComponent`);
289
+ }
290
+ if (FrameworkComponent) {
291
+ if (!createFrameworkComponent) {
292
+ throw new Error(`Cannot create '${id}' for framework component '${componentName}'. you must register a frameworkPanelWrapper to use framework components`);
293
+ }
294
+ return createFrameworkComponent.createComponent(id, componentName, FrameworkComponent);
295
+ }
296
+ if (!Component) {
297
+ if (fallback) {
298
+ return fallback();
299
+ }
300
+ throw new Error(`Cannot create '${id}', no component '${componentName}' provided`);
301
+ }
302
+ return new Component(id, componentName);
303
+ }
304
+
280
305
  function watchElementResize(element, cb) {
281
306
  const observer = new ResizeObserver((entires) => {
282
307
  /**
@@ -390,31 +415,16 @@
390
415
  refreshState() {
391
416
  this._refreshStateHandler();
392
417
  }
393
- }
394
-
395
- function createComponent(id, componentName, components = {}, frameworkComponents = {}, createFrameworkComponent, fallback) {
396
- const Component = typeof componentName === 'string'
397
- ? components[componentName]
398
- : undefined;
399
- const FrameworkComponent = typeof componentName === 'string'
400
- ? frameworkComponents[componentName]
401
- : undefined;
402
- if (Component && FrameworkComponent) {
403
- throw new Error(`Cannot create '${id}'. component '${componentName}' registered as both a component and frameworkComponent`);
404
- }
405
- if (FrameworkComponent) {
406
- if (!createFrameworkComponent) {
407
- throw new Error(`Cannot create '${id}' for framework component '${componentName}'. you must register a frameworkPanelWrapper to use framework components`);
408
- }
409
- return createFrameworkComponent.createComponent(id, componentName, FrameworkComponent);
410
- }
411
- if (!Component) {
412
- if (fallback) {
413
- return fallback();
414
- }
415
- throw new Error(`Cannot create '${id}', no component '${componentName}' provided`);
416
- }
417
- return new Component(id, componentName);
418
+ }
419
+ // quasi: apparently, but not really; seemingly
420
+ const QUASI_PREVENT_DEFAULT_KEY = 'dv-quasiPreventDefault';
421
+ // mark an event directly for other listeners to check
422
+ function quasiPreventDefault(event) {
423
+ event[QUASI_PREVENT_DEFAULT_KEY] = true;
424
+ }
425
+ // check if this event has been marked
426
+ function quasiDefaultPrevented(event) {
427
+ return event[QUASI_PREVENT_DEFAULT_KEY];
418
428
  }
419
429
 
420
430
  function tail(arr) {
@@ -465,6 +475,14 @@
465
475
  }
466
476
  }
467
477
  return -1;
478
+ }
479
+ function remove(array, value) {
480
+ const index = array.findIndex((t) => t === value);
481
+ if (index > -1) {
482
+ array.splice(index, 1);
483
+ return true;
484
+ }
485
+ return false;
468
486
  }
469
487
 
470
488
  const clamp = (value, min, max) => {
@@ -894,7 +912,7 @@
894
912
  //add sash
895
913
  const sash = document.createElement('div');
896
914
  sash.className = 'sash';
897
- const onStart = (event) => {
915
+ const onPointerStart = (event) => {
898
916
  for (const item of this.viewItems) {
899
917
  item.enabled = false;
900
918
  }
@@ -953,11 +971,10 @@
953
971
  size: snappedViewItem.size,
954
972
  };
955
973
  }
956
- //
957
- const mousemove = (mousemoveEvent) => {
974
+ const onPointerMove = (event) => {
958
975
  const current = this._orientation === exports.Orientation.HORIZONTAL
959
- ? mousemoveEvent.clientX
960
- : mousemoveEvent.clientY;
976
+ ? event.clientX
977
+ : event.clientY;
961
978
  const delta = current - start;
962
979
  this.resize(sashIndex, delta, sizes, undefined, undefined, minDelta, maxDelta, snapBefore, snapAfter);
963
980
  this.distributeEmptySpace();
@@ -971,18 +988,20 @@
971
988
  iframe.style.pointerEvents = 'auto';
972
989
  }
973
990
  this.saveProportions();
974
- document.removeEventListener('mousemove', mousemove);
975
- document.removeEventListener('mouseup', end);
991
+ document.removeEventListener('pointermove', onPointerMove);
992
+ document.removeEventListener('pointerup', end);
993
+ document.removeEventListener('pointercancel', end);
976
994
  this._onDidSashEnd.fire(undefined);
977
995
  };
978
- document.addEventListener('mousemove', mousemove);
979
- document.addEventListener('mouseup', end);
996
+ document.addEventListener('pointermove', onPointerMove);
997
+ document.addEventListener('pointerup', end);
998
+ document.addEventListener('pointercancel', end);
980
999
  };
981
- sash.addEventListener('mousedown', onStart);
1000
+ sash.addEventListener('pointerdown', onPointerStart);
982
1001
  const sashItem = {
983
1002
  container: sash,
984
1003
  disposable: () => {
985
- sash.removeEventListener('mousedown', onStart);
1004
+ sash.removeEventListener('pointerdown', onPointerStart);
986
1005
  this.sashContainer.removeChild(sash);
987
1006
  },
988
1007
  };
@@ -1606,7 +1625,7 @@
1606
1625
  : true,
1607
1626
  };
1608
1627
  }),
1609
- size: this.size,
1628
+ size: this.orthogonalSize,
1610
1629
  };
1611
1630
  this.children = childDescriptors.map((c) => c.node);
1612
1631
  this.splitview = new Splitview(this.element, {
@@ -1669,7 +1688,7 @@
1669
1688
  layout(size, orthogonalSize) {
1670
1689
  this._size = orthogonalSize;
1671
1690
  this._orthogonalSize = size;
1672
- this.splitview.layout(this.size, this.orthogonalSize);
1691
+ this.splitview.layout(orthogonalSize, size);
1673
1692
  }
1674
1693
  addChild(node, size, index, skipLayout) {
1675
1694
  if (index < 0 || index > this.children.length) {
@@ -1894,9 +1913,9 @@
1894
1913
  this._deserialize(json.root, orientation, deserializer, height);
1895
1914
  }
1896
1915
  _deserialize(root, orientation, deserializer, orthogonalSize) {
1897
- this.root = this._deserializeNode(root, orientation, deserializer, orthogonalSize, true);
1916
+ this.root = this._deserializeNode(root, orientation, deserializer, orthogonalSize);
1898
1917
  }
1899
- _deserializeNode(node, orientation, deserializer, orthogonalSize, isRoot = false) {
1918
+ _deserializeNode(node, orientation, deserializer, orthogonalSize) {
1900
1919
  let result;
1901
1920
  if (node.type === 'branch') {
1902
1921
  const serializedChildren = node.data;
@@ -1906,9 +1925,9 @@
1906
1925
  visible: serializedChild.visible,
1907
1926
  };
1908
1927
  });
1909
- // HORIZONTAL => height=orthogonalsize width=size
1910
- // VERTICAL => height=size width=orthogonalsize
1911
- result = new BranchNode(orientation, this.proportionalLayout, this.styles, isRoot ? orthogonalSize : node.size, isRoot ? node.size : orthogonalSize, children);
1928
+ result = new BranchNode(orientation, this.proportionalLayout, this.styles, node.size, // <- orthogonal size - flips at each depth
1929
+ orthogonalSize, // <- size - flips at each depth
1930
+ children);
1912
1931
  }
1913
1932
  else {
1914
1933
  result = new LeafNode(deserializer.fromJSON(node), orientation, orthogonalSize, node.size);
@@ -1941,7 +1960,8 @@
1941
1960
  const oldRoot = this.root;
1942
1961
  oldRoot.element.remove();
1943
1962
  this._root = new BranchNode(orthogonal(oldRoot.orientation), this.proportionalLayout, this.styles, this.root.orthogonalSize, this.root.size);
1944
- if (oldRoot.children.length === 1) {
1963
+ if (oldRoot.children.length === 0) ;
1964
+ else if (oldRoot.children.length === 1) {
1945
1965
  // can remove one level of redundant branching if there is only a single child
1946
1966
  const childReference = oldRoot.children[0];
1947
1967
  const child = oldRoot.removeChild(0); // remove to prevent disposal when disposing of unwanted root
@@ -2075,52 +2095,70 @@
2075
2095
  if (!(parent instanceof BranchNode)) {
2076
2096
  throw new Error('Invalid location');
2077
2097
  }
2078
- const node = parent.children[index];
2079
- if (!(node instanceof LeafNode)) {
2098
+ const nodeToRemove = parent.children[index];
2099
+ if (!(nodeToRemove instanceof LeafNode)) {
2080
2100
  throw new Error('Invalid location');
2081
2101
  }
2082
2102
  parent.removeChild(index, sizing);
2083
- if (parent.children.length === 0) {
2084
- return node.view;
2085
- }
2086
- if (parent.children.length > 1) {
2087
- return node.view;
2088
- }
2103
+ nodeToRemove.dispose();
2104
+ if (parent.children.length !== 1) {
2105
+ return nodeToRemove.view;
2106
+ }
2107
+ // if the parent has only one child and we know the parent is a BranchNode we can make the tree
2108
+ // more efficiently spaced by replacing the parent BranchNode with the child.
2109
+ // if that child is a LeafNode then we simply replace the BranchNode with the child otherwise if the child
2110
+ // is a BranchNode too we should spread it's children into the grandparent.
2111
+ // refer to the remaining child as the sibling
2089
2112
  const sibling = parent.children[0];
2090
2113
  if (pathToParent.length === 0) {
2091
- // parent is root
2114
+ // if the parent is root
2092
2115
  if (sibling instanceof LeafNode) {
2093
- return node.view;
2116
+ // if the sibling is a leaf node no action is required
2117
+ return nodeToRemove.view;
2094
2118
  }
2095
- // we must promote sibling to be the new root
2119
+ // otherwise the sibling is a branch node. since the parent is the root and the root has only one child
2120
+ // which is a branch node we can just set this branch node to be the new root node
2121
+ // for good housekeeping we'll removing the sibling from it's existing tree
2096
2122
  parent.removeChild(0, sizing);
2123
+ // and set that sibling node to be root
2097
2124
  this.root = sibling;
2098
- return node.view;
2125
+ return nodeToRemove.view;
2099
2126
  }
2127
+ // otherwise the parent is apart of a large sub-tree
2100
2128
  const [grandParent, ..._] = [...pathToParent].reverse();
2101
2129
  const [parentIndex, ...__] = [...rest].reverse();
2102
2130
  const isSiblingVisible = parent.isChildVisible(0);
2131
+ // either way we need to remove the sibling from it's existing tree
2103
2132
  parent.removeChild(0, sizing);
2133
+ // note the sizes of all of the grandparents children
2104
2134
  const sizes = grandParent.children.map((_size, i) => grandParent.getChildSize(i));
2105
- grandParent.removeChild(parentIndex, sizing);
2135
+ // remove the parent from the grandparent since we are moving the sibling to take the parents place
2136
+ // this parent is no longer used and can be disposed of
2137
+ grandParent.removeChild(parentIndex, sizing).dispose();
2106
2138
  if (sibling instanceof BranchNode) {
2139
+ // replace the parent with the siblings children
2107
2140
  sizes.splice(parentIndex, 1, ...sibling.children.map((c) => c.size));
2141
+ // and add those siblings to the grandparent
2108
2142
  for (let i = 0; i < sibling.children.length; i++) {
2109
2143
  const child = sibling.children[i];
2110
2144
  grandParent.addChild(child, child.size, parentIndex + i);
2111
2145
  }
2112
2146
  }
2113
2147
  else {
2148
+ // otherwise create a new leaf node and add that to the grandparent
2114
2149
  const newSibling = new LeafNode(sibling.view, orthogonal(sibling.orientation), sibling.size);
2115
2150
  const siblingSizing = isSiblingVisible
2116
2151
  ? sibling.orthogonalSize
2117
2152
  : exports.Sizing.Invisible(sibling.orthogonalSize);
2118
2153
  grandParent.addChild(newSibling, siblingSizing, parentIndex);
2119
2154
  }
2155
+ // the containing node of the sibling is no longer required and can be disposed of
2156
+ sibling.dispose();
2157
+ // resize everything
2120
2158
  for (let i = 0; i < sizes.length; i++) {
2121
2159
  grandParent.resizeChild(i, sizes[i]);
2122
2160
  }
2123
- return node.view;
2161
+ return nodeToRemove.view;
2124
2162
  }
2125
2163
  layout(width, height) {
2126
2164
  const [size, orthogonalSize] = this.root.orientation === exports.Orientation.HORIZONTAL
@@ -2439,6 +2477,9 @@
2439
2477
  addPanel(options) {
2440
2478
  return this.component.addPanel(options);
2441
2479
  }
2480
+ removePanel(panel) {
2481
+ this.component.removePanel(panel);
2482
+ }
2442
2483
  addGroup(options) {
2443
2484
  return this.component.addGroup(options);
2444
2485
  }
@@ -2457,6 +2498,9 @@
2457
2498
  getGroup(id) {
2458
2499
  return this.component.getPanel(id);
2459
2500
  }
2501
+ addFloatingGroup(item, coord) {
2502
+ return this.component.addFloatingGroup(item, coord);
2503
+ }
2460
2504
  fromJSON(data) {
2461
2505
  this.component.fromJSON(data);
2462
2506
  }
@@ -2549,10 +2593,14 @@
2549
2593
  this._onDrop = new Emitter();
2550
2594
  this.onDrop = this._onDrop.event;
2551
2595
  // use a set to take advantage of #<set>.has
2552
- const acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
2596
+ this._acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
2553
2597
  this.addDisposables(this._onDrop, new DragAndDropObserver(this.element, {
2554
2598
  onDragEnter: () => undefined,
2555
2599
  onDragOver: (e) => {
2600
+ if (this._acceptedTargetZonesSet.size === 0) {
2601
+ this.removeDropTarget();
2602
+ return;
2603
+ }
2556
2604
  const width = this.element.clientWidth;
2557
2605
  const height = this.element.clientHeight;
2558
2606
  if (width === 0 || height === 0) {
@@ -2561,20 +2609,28 @@
2561
2609
  const rect = e.currentTarget.getBoundingClientRect();
2562
2610
  const x = e.clientX - rect.left;
2563
2611
  const y = e.clientY - rect.top;
2564
- const quadrant = this.calculateQuadrant(acceptedTargetZonesSet, x, y, width, height);
2565
- if (quadrant === null) {
2612
+ const quadrant = this.calculateQuadrant(this._acceptedTargetZonesSet, x, y, width, height);
2613
+ /**
2614
+ * If the event has already been used by another DropTarget instance
2615
+ * then don't show a second drop target, only one target should be
2616
+ * active at any one time
2617
+ */
2618
+ if (this.isAlreadyUsed(e) || quadrant === null) {
2566
2619
  // no drop target should be displayed
2567
2620
  this.removeDropTarget();
2568
2621
  return;
2569
2622
  }
2570
2623
  if (typeof this.options.canDisplayOverlay === 'boolean') {
2571
2624
  if (!this.options.canDisplayOverlay) {
2625
+ this.removeDropTarget();
2572
2626
  return;
2573
2627
  }
2574
2628
  }
2575
2629
  else if (!this.options.canDisplayOverlay(e, quadrant)) {
2630
+ this.removeDropTarget();
2576
2631
  return;
2577
2632
  }
2633
+ this.markAsUsed(e);
2578
2634
  if (!this.targetElement) {
2579
2635
  this.targetElement = document.createElement('div');
2580
2636
  this.targetElement.className = 'drop-target-dropzone';
@@ -2585,12 +2641,6 @@
2585
2641
  this.element.classList.add('drop-target');
2586
2642
  this.element.append(this.targetElement);
2587
2643
  }
2588
- if (this.options.acceptedTargetZones.length === 0) {
2589
- return;
2590
- }
2591
- if (!this.targetElement || !this.overlayElement) {
2592
- return;
2593
- }
2594
2644
  this.toggleClasses(quadrant, width, height);
2595
2645
  this.setState(quadrant);
2596
2646
  },
@@ -2613,10 +2663,26 @@
2613
2663
  },
2614
2664
  }));
2615
2665
  }
2666
+ setTargetZones(acceptedTargetZones) {
2667
+ this._acceptedTargetZonesSet = new Set(acceptedTargetZones);
2668
+ }
2616
2669
  dispose() {
2617
2670
  this.removeDropTarget();
2618
2671
  super.dispose();
2619
2672
  }
2673
+ /**
2674
+ * Add a property to the event object for other potential listeners to check
2675
+ */
2676
+ markAsUsed(event) {
2677
+ event[Droptarget.USED_EVENT_ID] = true;
2678
+ }
2679
+ /**
2680
+ * Check is the event has already been used by another instance od DropTarget
2681
+ */
2682
+ isAlreadyUsed(event) {
2683
+ const value = event[Droptarget.USED_EVENT_ID];
2684
+ return typeof value === 'boolean' && value;
2685
+ }
2620
2686
  toggleClasses(quadrant, width, height) {
2621
2687
  var _a, _b, _c, _d;
2622
2688
  if (!this.overlayElement) {
@@ -2711,6 +2777,7 @@
2711
2777
  }
2712
2778
  }
2713
2779
  }
2780
+ Droptarget.USED_EVENT_ID = '__dockview_droptarget_event_is_used__';
2714
2781
  function calculateQuadrantAsPercentage(overlayType, x, y, width, height, threshold) {
2715
2782
  const xp = (100 * x) / width;
2716
2783
  const yp = (100 * y) / height;
@@ -2840,8 +2907,15 @@
2840
2907
  this.addDisposables(this._onDragStart, this.dataDisposable, this.pointerEventsDisposable);
2841
2908
  this.configure();
2842
2909
  }
2910
+ isCancelled(_event) {
2911
+ return false;
2912
+ }
2843
2913
  configure() {
2844
2914
  this.addDisposables(this._onDragStart, addDisposableListener(this.el, 'dragstart', (event) => {
2915
+ if (this.isCancelled(event)) {
2916
+ event.preventDefault();
2917
+ return;
2918
+ }
2845
2919
  const iframes = [
2846
2920
  ...getElementsByTagName('iframe'),
2847
2921
  ...getElementsByTagName('webview'),
@@ -2915,13 +2989,6 @@
2915
2989
  if (event.defaultPrevented) {
2916
2990
  return;
2917
2991
  }
2918
- /**
2919
- * TODO: alternative to stopPropagation
2920
- *
2921
- * I need to stop the event propagation here since otherwise it'll be intercepted by event handlers
2922
- * on the tabs-container. I cannot use event.preventDefault() since I need the on DragStart event to occur
2923
- */
2924
- event.stopPropagation();
2925
2992
  this._onChanged.fire(event);
2926
2993
  }));
2927
2994
  this.droptarget = new Droptarget(this._element, {
@@ -2979,6 +3046,22 @@
2979
3046
  this.accessorId = accessorId;
2980
3047
  this.group = group;
2981
3048
  this.panelTransfer = LocalSelectionTransfer.getInstance();
3049
+ this.addDisposables(addDisposableListener(element, 'mousedown', (e) => {
3050
+ if (e.shiftKey) {
3051
+ /**
3052
+ * You cannot call e.preventDefault() because that will prevent drag events from firing
3053
+ * but we also need to stop any group overlay drag events from occuring
3054
+ * Use a custom event marker that can be checked by the overlay drag events
3055
+ */
3056
+ quasiPreventDefault(e);
3057
+ }
3058
+ }, true));
3059
+ }
3060
+ isCancelled(_event) {
3061
+ if (this.group.api.isFloating && !_event.shiftKey) {
3062
+ return true;
3063
+ }
3064
+ return false;
2982
3065
  }
2983
3066
  getData(dataTransfer) {
2984
3067
  this.panelTransfer.setData([new PanelTransfer(this.accessorId, this.group.id, null)], PanelTransfer.prototype);
@@ -3069,17 +3152,30 @@
3069
3152
  hide() {
3070
3153
  this._element.style.display = 'none';
3071
3154
  }
3072
- setActionElement(element) {
3073
- if (this.actions === element) {
3155
+ setRightActionsElement(element) {
3156
+ if (this.rightActions === element) {
3074
3157
  return;
3075
3158
  }
3076
- if (this.actions) {
3077
- this.actions.remove();
3078
- this.actions = undefined;
3159
+ if (this.rightActions) {
3160
+ this.rightActions.remove();
3161
+ this.rightActions = undefined;
3079
3162
  }
3080
3163
  if (element) {
3081
- this.actionContainer.appendChild(element);
3082
- this.actions = element;
3164
+ this.rightActionsContainer.appendChild(element);
3165
+ this.rightActions = element;
3166
+ }
3167
+ }
3168
+ setLeftActionsElement(element) {
3169
+ if (this.leftActions === element) {
3170
+ return;
3171
+ }
3172
+ if (this.leftActions) {
3173
+ this.leftActions.remove();
3174
+ this.leftActions = undefined;
3175
+ }
3176
+ if (element) {
3177
+ this.leftActionsContainer.appendChild(element);
3178
+ this.leftActions = element;
3083
3179
  }
3084
3180
  }
3085
3181
  get element() {
@@ -3114,19 +3210,35 @@
3114
3210
  toggleClass(this._element, 'dv-single-tab', this.size === 1);
3115
3211
  }
3116
3212
  }));
3117
- this.actionContainer = document.createElement('div');
3118
- this.actionContainer.className = 'action-container';
3213
+ this.rightActionsContainer = document.createElement('div');
3214
+ this.rightActionsContainer.className = 'right-actions-container';
3215
+ this.leftActionsContainer = document.createElement('div');
3216
+ this.leftActionsContainer.className = 'left-actions-container';
3119
3217
  this.tabContainer = document.createElement('div');
3120
3218
  this.tabContainer.className = 'tabs-container';
3121
3219
  this.voidContainer = new VoidContainer(this.accessor, this.group);
3122
3220
  this._element.appendChild(this.tabContainer);
3221
+ this._element.appendChild(this.leftActionsContainer);
3123
3222
  this._element.appendChild(this.voidContainer.element);
3124
- this._element.appendChild(this.actionContainer);
3223
+ this._element.appendChild(this.rightActionsContainer);
3125
3224
  this.addDisposables(this.voidContainer, this.voidContainer.onDrop((event) => {
3126
3225
  this._onDrop.fire({
3127
3226
  event: event.nativeEvent,
3128
3227
  index: this.tabs.length,
3129
3228
  });
3229
+ }), addDisposableListener(this.voidContainer.element, 'mousedown', (event) => {
3230
+ const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3231
+ if (isFloatingGroupsEnabled &&
3232
+ event.shiftKey &&
3233
+ !this.group.api.isFloating) {
3234
+ event.preventDefault();
3235
+ const { top, left } = this.element.getBoundingClientRect();
3236
+ const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
3237
+ this.accessor.addFloatingGroup(this.group, {
3238
+ x: left - rootLeft + 20,
3239
+ y: top - rootTop + 20,
3240
+ }, { inDragMode: true });
3241
+ }
3130
3242
  }), addDisposableListener(this.tabContainer, 'mousedown', (event) => {
3131
3243
  if (event.defaultPrevented) {
3132
3244
  return;
@@ -3180,6 +3292,21 @@
3180
3292
  tabToAdd.setContent(panel.view.tab);
3181
3293
  const disposable = CompositeDisposable.from(tabToAdd.onChanged((event) => {
3182
3294
  var _a;
3295
+ const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3296
+ const isFloatingWithOnePanel = this.group.api.isFloating && this.size === 1;
3297
+ if (isFloatingGroupsEnabled &&
3298
+ !isFloatingWithOnePanel &&
3299
+ event.shiftKey) {
3300
+ event.preventDefault();
3301
+ const panel = this.accessor.getGroupPanel(tabToAdd.panelId);
3302
+ const { top, left } = tabToAdd.element.getBoundingClientRect();
3303
+ const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
3304
+ this.accessor.addFloatingGroup(panel, {
3305
+ x: left - rootLeft,
3306
+ y: top - rootTop,
3307
+ }, { inDragMode: true });
3308
+ return;
3309
+ }
3183
3310
  const alreadyFocused = panel.id === ((_a = this.group.model.activePanel) === null || _a === void 0 ? void 0 : _a.id) &&
3184
3311
  this.group.model.isContentFocused;
3185
3312
  const isLeftClick = event.button === 0;
@@ -3249,6 +3376,17 @@
3249
3376
  }
3250
3377
  return isAncestor(document.activeElement, this.contentContainer.element);
3251
3378
  }
3379
+ get isFloating() {
3380
+ return this._isFloating;
3381
+ }
3382
+ set isFloating(value) {
3383
+ this._isFloating = value;
3384
+ this.dropTarget.setTargetZones(value ? ['center'] : ['top', 'bottom', 'left', 'right', 'center']);
3385
+ toggleClass(this.container, 'dv-groupview-floating', value);
3386
+ this.groupPanel.api._onDidFloatingStateChange.fire({
3387
+ isFloating: this.isFloating,
3388
+ });
3389
+ }
3252
3390
  constructor(container, accessor, id, options, groupPanel) {
3253
3391
  super();
3254
3392
  this.container = container;
@@ -3258,6 +3396,7 @@
3258
3396
  this.groupPanel = groupPanel;
3259
3397
  this._isGroupActive = false;
3260
3398
  this._locked = false;
3399
+ this._isFloating = false;
3261
3400
  this.mostRecentlyUsed = [];
3262
3401
  this._onDidChange = new Emitter();
3263
3402
  this.onDidChange = this._onDidChange.event;
@@ -3274,7 +3413,7 @@
3274
3413
  this.onDidRemovePanel = this._onDidRemovePanel.event;
3275
3414
  this._onDidActivePanelChange = new Emitter();
3276
3415
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
3277
- this.container.classList.add('groupview');
3416
+ toggleClass(this.container, 'groupview', true);
3278
3417
  this.tabsContainer = new TabsContainer(this.accessor, this.groupPanel);
3279
3418
  this.contentContainer = new ContentContainer();
3280
3419
  this.dropTarget = new Droptarget(this.contentContainer.element, {
@@ -3284,6 +3423,9 @@
3284
3423
  return false;
3285
3424
  }
3286
3425
  const data = getPanelData();
3426
+ if (!data && event.shiftKey && !this.isFloating) {
3427
+ return false;
3428
+ }
3287
3429
  if (data && data.viewId === this.accessor.id) {
3288
3430
  if (data.groupId === this.id) {
3289
3431
  if (position === 'center') {
@@ -3328,14 +3470,25 @@
3328
3470
  // correctly initialized
3329
3471
  this.setActive(this.isActive, true, true);
3330
3472
  this.updateContainer();
3331
- if (this.accessor.options.createGroupControlElement) {
3332
- this._control = this.accessor.options.createGroupControlElement(this.groupPanel);
3333
- this.addDisposables(this._control);
3334
- this._control.init({
3473
+ if (this.accessor.options.createRightHeaderActionsElement) {
3474
+ this._rightHeaderActions =
3475
+ this.accessor.options.createRightHeaderActionsElement(this.groupPanel);
3476
+ this.addDisposables(this._rightHeaderActions);
3477
+ this._rightHeaderActions.init({
3335
3478
  containerApi: new DockviewApi(this.accessor),
3336
3479
  api: this.groupPanel.api,
3337
3480
  });
3338
- this.tabsContainer.setActionElement(this._control.element);
3481
+ this.tabsContainer.setRightActionsElement(this._rightHeaderActions.element);
3482
+ }
3483
+ if (this.accessor.options.createLeftHeaderActionsElement) {
3484
+ this._leftHeaderActions =
3485
+ this.accessor.options.createLeftHeaderActionsElement(this.groupPanel);
3486
+ this.addDisposables(this._leftHeaderActions);
3487
+ this._leftHeaderActions.init({
3488
+ containerApi: new DockviewApi(this.accessor),
3489
+ api: this.groupPanel.api,
3490
+ });
3491
+ this.tabsContainer.setLeftActionsElement(this._leftHeaderActions.element);
3339
3492
  }
3340
3493
  }
3341
3494
  indexOf(panel) {
@@ -3468,7 +3621,7 @@
3468
3621
  return this._activePanel === panel;
3469
3622
  }
3470
3623
  updateActions(element) {
3471
- this.tabsContainer.setActionElement(element);
3624
+ this.tabsContainer.setRightActionsElement(element);
3472
3625
  }
3473
3626
  setActive(isGroupActive, skipFocus = false, force = false) {
3474
3627
  var _a, _b, _c, _d;
@@ -3640,9 +3793,10 @@
3640
3793
  }
3641
3794
  }
3642
3795
  dispose() {
3643
- var _a, _b;
3796
+ var _a, _b, _c;
3644
3797
  super.dispose();
3645
- (_b = (_a = this.watermark) === null || _a === void 0 ? void 0 : _a.dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
3798
+ (_a = this.watermark) === null || _a === void 0 ? void 0 : _a.element.remove();
3799
+ (_c = (_b = this.watermark) === null || _b === void 0 ? void 0 : _b.dispose) === null || _c === void 0 ? void 0 : _c.call(_b);
3646
3800
  for (const panel of this.panels) {
3647
3801
  panel.dispose();
3648
3802
  }
@@ -4436,8 +4590,8 @@
4436
4590
  get isActive() {
4437
4591
  return this.api.isActive;
4438
4592
  }
4439
- constructor(id, component, options) {
4440
- super(id, component, new GridviewPanelApiImpl(id));
4593
+ constructor(id, component, options, api) {
4594
+ super(id, component, api !== null && api !== void 0 ? api : new GridviewPanelApiImpl(id));
4441
4595
  this._evaluatedMinimumWidth = 0;
4442
4596
  this._evaluatedMaximumWidth = Number.MAX_SAFE_INTEGER;
4443
4597
  this._evaluatedMinimumHeight = 0;
@@ -4535,6 +4689,32 @@
4535
4689
  }
4536
4690
  }
4537
4691
 
4692
+ class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
4693
+ get isFloating() {
4694
+ if (!this._group) {
4695
+ throw new Error(`DockviewGroupPanelApiImpl not initialized`);
4696
+ }
4697
+ return this._group.model.isFloating;
4698
+ }
4699
+ constructor(id, accessor) {
4700
+ super(id);
4701
+ this.accessor = accessor;
4702
+ this._onDidFloatingStateChange = new Emitter();
4703
+ this.onDidFloatingStateChange = this._onDidFloatingStateChange.event;
4704
+ this.addDisposables(this._onDidFloatingStateChange);
4705
+ }
4706
+ moveTo(options) {
4707
+ var _a;
4708
+ if (!this._group) {
4709
+ throw new Error(`DockviewGroupPanelApiImpl not initialized`);
4710
+ }
4711
+ this.accessor.moveGroupOrPanel(options.group, this._group.id, undefined, (_a = options.position) !== null && _a !== void 0 ? _a : 'center');
4712
+ }
4713
+ initialize(group) {
4714
+ this._group = group;
4715
+ }
4716
+ }
4717
+
4538
4718
  class DockviewGroupPanel extends GridviewPanel {
4539
4719
  get panels() {
4540
4720
  return this._model.panels;
@@ -4561,7 +4741,8 @@
4561
4741
  super(id, 'groupview_default', {
4562
4742
  minimumHeight: 100,
4563
4743
  minimumWidth: 100,
4564
- });
4744
+ }, new DockviewGroupPanelApiImpl(id, accessor));
4745
+ this.api.initialize(this); // cannot use 'this' after after 'super' call
4565
4746
  this._model = new DockviewGroupPanelModel(this.element, accessor, id, options, this);
4566
4747
  }
4567
4748
  initialize() {
@@ -4579,7 +4760,6 @@
4579
4760
  return this._model;
4580
4761
  }
4581
4762
  toJSON() {
4582
- // TODO fix typing
4583
4763
  return this.model.toJSON();
4584
4764
  }
4585
4765
  }
@@ -4633,9 +4813,10 @@
4633
4813
  get group() {
4634
4814
  return this._group;
4635
4815
  }
4636
- constructor(panel, group) {
4816
+ constructor(panel, group, accessor) {
4637
4817
  super(panel.id);
4638
4818
  this.panel = panel;
4819
+ this.accessor = accessor;
4639
4820
  this._onDidTitleChange = new Emitter();
4640
4821
  this.onDidTitleChange = this._onDidTitleChange.event;
4641
4822
  this._onDidActiveGroupChange = new Emitter();
@@ -4647,6 +4828,10 @@
4647
4828
  this._group = group;
4648
4829
  this.addDisposables(this.disposable, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange);
4649
4830
  }
4831
+ moveTo(options) {
4832
+ var _a;
4833
+ this.accessor.moveGroupOrPanel(options.group, this._group.id, this.panel.id, (_a = options.position) !== null && _a !== void 0 ? _a : 'center', options.index);
4834
+ }
4650
4835
  setTitle(title) {
4651
4836
  this.panel.setTitle(title);
4652
4837
  }
@@ -4671,7 +4856,7 @@
4671
4856
  this.containerApi = containerApi;
4672
4857
  this.view = view;
4673
4858
  this._group = group;
4674
- this.api = new DockviewPanelApiImpl(this, this._group);
4859
+ this.api = new DockviewPanelApiImpl(this, this._group, accessor);
4675
4860
  this.addDisposables(this.api.onActiveChange(() => {
4676
4861
  accessor.setActivePanel(this);
4677
4862
  }), this.api.onDidSizeChange((event) => {
@@ -5012,6 +5197,296 @@
5012
5197
  }
5013
5198
  }
5014
5199
 
5200
+ const bringElementToFront = (() => {
5201
+ let previous = null;
5202
+ function pushToTop(element) {
5203
+ if (previous !== element && previous !== null) {
5204
+ toggleClass(previous, 'dv-bring-to-front', false);
5205
+ }
5206
+ toggleClass(element, 'dv-bring-to-front', true);
5207
+ previous = element;
5208
+ }
5209
+ return pushToTop;
5210
+ })();
5211
+ class Overlay extends CompositeDisposable {
5212
+ constructor(options) {
5213
+ super();
5214
+ this.options = options;
5215
+ this._element = document.createElement('div');
5216
+ this._onDidChange = new Emitter();
5217
+ this.onDidChange = this._onDidChange.event;
5218
+ this._onDidChangeEnd = new Emitter();
5219
+ this.onDidChangeEnd = this._onDidChangeEnd.event;
5220
+ this.addDisposables(this._onDidChange, this._onDidChangeEnd);
5221
+ this._element.className = 'dv-resize-container';
5222
+ this.setupResize('top');
5223
+ this.setupResize('bottom');
5224
+ this.setupResize('left');
5225
+ this.setupResize('right');
5226
+ this.setupResize('topleft');
5227
+ this.setupResize('topright');
5228
+ this.setupResize('bottomleft');
5229
+ this.setupResize('bottomright');
5230
+ this._element.appendChild(this.options.content);
5231
+ this.options.container.appendChild(this._element);
5232
+ // if input bad resize within acceptable boundaries
5233
+ this.setBounds({
5234
+ height: this.options.height,
5235
+ width: this.options.width,
5236
+ top: this.options.top,
5237
+ left: this.options.left,
5238
+ });
5239
+ }
5240
+ setBounds(bounds = {}) {
5241
+ if (typeof bounds.height === 'number') {
5242
+ this._element.style.height = `${bounds.height}px`;
5243
+ }
5244
+ if (typeof bounds.width === 'number') {
5245
+ this._element.style.width = `${bounds.width}px`;
5246
+ }
5247
+ if (typeof bounds.top === 'number') {
5248
+ this._element.style.top = `${bounds.top}px`;
5249
+ }
5250
+ if (typeof bounds.left === 'number') {
5251
+ this._element.style.left = `${bounds.left}px`;
5252
+ }
5253
+ const containerRect = this.options.container.getBoundingClientRect();
5254
+ const overlayRect = this._element.getBoundingClientRect();
5255
+ // region: ensure bounds within allowable limits
5256
+ // a minimum width of minimumViewportWidth must be inside the viewport
5257
+ const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5258
+ // a minimum height of minimumViewportHeight must be inside the viewport
5259
+ const yOffset = Math.max(0, overlayRect.height - this.options.minimumInViewportHeight);
5260
+ const left = clamp(overlayRect.left - containerRect.left, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5261
+ const top = clamp(overlayRect.top - containerRect.top, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5262
+ this._element.style.left = `${left}px`;
5263
+ this._element.style.top = `${top}px`;
5264
+ this._onDidChange.fire();
5265
+ }
5266
+ toJSON() {
5267
+ const container = this.options.container.getBoundingClientRect();
5268
+ const element = this._element.getBoundingClientRect();
5269
+ return {
5270
+ top: element.top - container.top,
5271
+ left: element.left - container.left,
5272
+ width: element.width,
5273
+ height: element.height,
5274
+ };
5275
+ }
5276
+ setupDrag(dragTarget, options = { inDragMode: false }) {
5277
+ const move = new MutableDisposable();
5278
+ const track = () => {
5279
+ let offset = null;
5280
+ const iframes = [
5281
+ ...getElementsByTagName('iframe'),
5282
+ ...getElementsByTagName('webview'),
5283
+ ];
5284
+ for (const iframe of iframes) {
5285
+ iframe.style.pointerEvents = 'none';
5286
+ }
5287
+ move.value = new CompositeDisposable({
5288
+ dispose: () => {
5289
+ for (const iframe of iframes) {
5290
+ iframe.style.pointerEvents = 'auto';
5291
+ }
5292
+ },
5293
+ }, addDisposableWindowListener(window, 'mousemove', (e) => {
5294
+ const containerRect = this.options.container.getBoundingClientRect();
5295
+ const x = e.clientX - containerRect.left;
5296
+ const y = e.clientY - containerRect.top;
5297
+ toggleClass(this._element, 'dv-resize-container-dragging', true);
5298
+ const overlayRect = this._element.getBoundingClientRect();
5299
+ if (offset === null) {
5300
+ offset = {
5301
+ x: e.clientX - overlayRect.left,
5302
+ y: e.clientY - overlayRect.top,
5303
+ };
5304
+ }
5305
+ const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5306
+ const yOffset = Math.max(0, overlayRect.height -
5307
+ this.options.minimumInViewportHeight);
5308
+ const left = clamp(x - offset.x, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5309
+ const top = clamp(y - offset.y, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5310
+ this.setBounds({ top, left });
5311
+ }), addDisposableWindowListener(window, 'mouseup', () => {
5312
+ toggleClass(this._element, 'dv-resize-container-dragging', false);
5313
+ move.dispose();
5314
+ this._onDidChangeEnd.fire();
5315
+ }));
5316
+ };
5317
+ this.addDisposables(move, addDisposableListener(dragTarget, 'mousedown', (event) => {
5318
+ if (event.defaultPrevented) {
5319
+ event.preventDefault();
5320
+ return;
5321
+ }
5322
+ // if somebody has marked this event then treat as a defaultPrevented
5323
+ // without actually calling event.preventDefault()
5324
+ if (quasiDefaultPrevented(event)) {
5325
+ return;
5326
+ }
5327
+ track();
5328
+ }), addDisposableListener(this.options.content, 'mousedown', (event) => {
5329
+ if (event.defaultPrevented) {
5330
+ return;
5331
+ }
5332
+ // if somebody has marked this event then treat as a defaultPrevented
5333
+ // without actually calling event.preventDefault()
5334
+ if (quasiDefaultPrevented(event)) {
5335
+ return;
5336
+ }
5337
+ if (event.shiftKey) {
5338
+ track();
5339
+ }
5340
+ }), addDisposableListener(this.options.content, 'mousedown', () => {
5341
+ bringElementToFront(this._element);
5342
+ }, true));
5343
+ bringElementToFront(this._element);
5344
+ if (options.inDragMode) {
5345
+ track();
5346
+ }
5347
+ }
5348
+ setupResize(direction) {
5349
+ const resizeHandleElement = document.createElement('div');
5350
+ resizeHandleElement.className = `dv-resize-handle-${direction}`;
5351
+ this._element.appendChild(resizeHandleElement);
5352
+ const move = new MutableDisposable();
5353
+ this.addDisposables(move, addDisposableListener(resizeHandleElement, 'mousedown', (e) => {
5354
+ e.preventDefault();
5355
+ let startPosition = null;
5356
+ const iframes = [
5357
+ ...getElementsByTagName('iframe'),
5358
+ ...getElementsByTagName('webview'),
5359
+ ];
5360
+ for (const iframe of iframes) {
5361
+ iframe.style.pointerEvents = 'none';
5362
+ }
5363
+ move.value = new CompositeDisposable(addDisposableWindowListener(window, 'mousemove', (e) => {
5364
+ const containerRect = this.options.container.getBoundingClientRect();
5365
+ const overlayRect = this._element.getBoundingClientRect();
5366
+ const y = e.clientY - containerRect.top;
5367
+ const x = e.clientX - containerRect.left;
5368
+ if (startPosition === null) {
5369
+ // record the initial dimensions since as all subsequence moves are relative to this
5370
+ startPosition = {
5371
+ originalY: y,
5372
+ originalHeight: overlayRect.height,
5373
+ originalX: x,
5374
+ originalWidth: overlayRect.width,
5375
+ };
5376
+ }
5377
+ let top = undefined;
5378
+ let height = undefined;
5379
+ let left = undefined;
5380
+ let width = undefined;
5381
+ const minimumInViewportHeight = this.options.minimumInViewportHeight;
5382
+ const minimumInViewportWidth = this.options.minimumInViewportWidth;
5383
+ function moveTop() {
5384
+ top = clamp(y, -Number.MAX_VALUE, startPosition.originalY +
5385
+ startPosition.originalHeight >
5386
+ containerRect.height
5387
+ ? containerRect.height -
5388
+ minimumInViewportHeight
5389
+ : Math.max(0, startPosition.originalY +
5390
+ startPosition.originalHeight -
5391
+ Overlay.MINIMUM_HEIGHT));
5392
+ height =
5393
+ startPosition.originalY +
5394
+ startPosition.originalHeight -
5395
+ top;
5396
+ }
5397
+ function moveBottom() {
5398
+ top =
5399
+ startPosition.originalY -
5400
+ startPosition.originalHeight;
5401
+ height = clamp(y - top, top < 0
5402
+ ? -top + minimumInViewportHeight
5403
+ : Overlay.MINIMUM_HEIGHT, Number.MAX_VALUE);
5404
+ }
5405
+ function moveLeft() {
5406
+ left = clamp(x, -Number.MAX_VALUE, startPosition.originalX +
5407
+ startPosition.originalWidth >
5408
+ containerRect.width
5409
+ ? containerRect.width -
5410
+ minimumInViewportWidth
5411
+ : Math.max(0, startPosition.originalX +
5412
+ startPosition.originalWidth -
5413
+ Overlay.MINIMUM_WIDTH));
5414
+ width =
5415
+ startPosition.originalX +
5416
+ startPosition.originalWidth -
5417
+ left;
5418
+ }
5419
+ function moveRight() {
5420
+ left =
5421
+ startPosition.originalX -
5422
+ startPosition.originalWidth;
5423
+ width = clamp(x - left, left < 0
5424
+ ? -left + minimumInViewportWidth
5425
+ : Overlay.MINIMUM_WIDTH, Number.MAX_VALUE);
5426
+ }
5427
+ switch (direction) {
5428
+ case 'top':
5429
+ moveTop();
5430
+ break;
5431
+ case 'bottom':
5432
+ moveBottom();
5433
+ break;
5434
+ case 'left':
5435
+ moveLeft();
5436
+ break;
5437
+ case 'right':
5438
+ moveRight();
5439
+ break;
5440
+ case 'topleft':
5441
+ moveTop();
5442
+ moveLeft();
5443
+ break;
5444
+ case 'topright':
5445
+ moveTop();
5446
+ moveRight();
5447
+ break;
5448
+ case 'bottomleft':
5449
+ moveBottom();
5450
+ moveLeft();
5451
+ break;
5452
+ case 'bottomright':
5453
+ moveBottom();
5454
+ moveRight();
5455
+ break;
5456
+ }
5457
+ this.setBounds({ height, width, top, left });
5458
+ }), {
5459
+ dispose: () => {
5460
+ for (const iframe of iframes) {
5461
+ iframe.style.pointerEvents = 'auto';
5462
+ }
5463
+ },
5464
+ }, addDisposableWindowListener(window, 'mouseup', () => {
5465
+ move.dispose();
5466
+ this._onDidChangeEnd.fire();
5467
+ }));
5468
+ }));
5469
+ }
5470
+ dispose() {
5471
+ this._element.remove();
5472
+ super.dispose();
5473
+ }
5474
+ }
5475
+ Overlay.MINIMUM_HEIGHT = 20;
5476
+ Overlay.MINIMUM_WIDTH = 20;
5477
+
5478
+ class DockviewFloatingGroupPanel extends CompositeDisposable {
5479
+ constructor(group, overlay) {
5480
+ super();
5481
+ this.group = group;
5482
+ this.overlay = overlay;
5483
+ this.addDisposables(overlay);
5484
+ }
5485
+ position(bounds) {
5486
+ this.overlay.setBounds(bounds);
5487
+ }
5488
+ }
5489
+
5015
5490
  class DockviewComponent extends BaseGrid {
5016
5491
  get orientation() {
5017
5492
  return this.gridview.orientation;
@@ -5052,7 +5527,8 @@
5052
5527
  this.onDidLayoutFromJSON = this._onDidLayoutFromJSON.event;
5053
5528
  this._onDidActivePanelChange = new Emitter();
5054
5529
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
5055
- this.element.classList.add('dv-dockview');
5530
+ this.floatingGroups = [];
5531
+ toggleClass(this.gridview.element, 'dv-dockview', true);
5056
5532
  this.addDisposables(this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
5057
5533
  this.updateWatermark();
5058
5534
  }), exports.DockviewEvent.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => {
@@ -5082,6 +5558,11 @@
5082
5558
  if (data.viewId !== this.id) {
5083
5559
  return false;
5084
5560
  }
5561
+ if (position === 'center') {
5562
+ // center drop target is only allowed if there are no panels in the grid
5563
+ // floating panels are allowed
5564
+ return this.gridview.length === 0;
5565
+ }
5085
5566
  return true;
5086
5567
  }
5087
5568
  if (this.options.showDndOverlay) {
@@ -5094,7 +5575,7 @@
5094
5575
  }
5095
5576
  return false;
5096
5577
  },
5097
- acceptedTargetZones: ['top', 'bottom', 'left', 'right'],
5578
+ acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
5098
5579
  overlayModel: {
5099
5580
  activationSize: { type: 'pixels', value: 10 },
5100
5581
  size: { type: 'pixels', value: 20 },
@@ -5112,6 +5593,75 @@
5112
5593
  this._api = new DockviewApi(this);
5113
5594
  this.updateWatermark();
5114
5595
  }
5596
+ addFloatingGroup(item, coord, options) {
5597
+ var _a, _b;
5598
+ let group;
5599
+ if (item instanceof DockviewPanel) {
5600
+ group = this.createGroup();
5601
+ this.removePanel(item, {
5602
+ removeEmptyGroup: true,
5603
+ skipDispose: true,
5604
+ });
5605
+ group.model.openPanel(item);
5606
+ }
5607
+ else {
5608
+ group = item;
5609
+ const skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' &&
5610
+ options.skipRemoveGroup;
5611
+ if (!skip) {
5612
+ this.doRemoveGroup(item, { skipDispose: true });
5613
+ }
5614
+ }
5615
+ group.model.isFloating = true;
5616
+ const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number' ? Math.max(coord.x, 0) : 100;
5617
+ const overlayTop = typeof (coord === null || coord === void 0 ? void 0 : coord.y) === 'number' ? Math.max(coord.y, 0) : 100;
5618
+ const overlay = new Overlay({
5619
+ container: this.gridview.element,
5620
+ content: group.element,
5621
+ height: (_a = coord === null || coord === void 0 ? void 0 : coord.height) !== null && _a !== void 0 ? _a : 300,
5622
+ width: (_b = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _b !== void 0 ? _b : 300,
5623
+ left: overlayLeft,
5624
+ top: overlayTop,
5625
+ minimumInViewportWidth: 100,
5626
+ minimumInViewportHeight: 100,
5627
+ });
5628
+ const el = group.element.querySelector('.void-container');
5629
+ if (!el) {
5630
+ throw new Error('failed to find drag handle');
5631
+ }
5632
+ overlay.setupDrag(el, {
5633
+ inDragMode: typeof (options === null || options === void 0 ? void 0 : options.inDragMode) === 'boolean'
5634
+ ? options.inDragMode
5635
+ : false,
5636
+ });
5637
+ const floatingGroupPanel = new DockviewFloatingGroupPanel(group, overlay);
5638
+ const disposable = watchElementResize(group.element, (entry) => {
5639
+ const { width, height } = entry.contentRect;
5640
+ group.layout(width, height); // let the group know it's size is changing so it can fire events to the panel
5641
+ });
5642
+ floatingGroupPanel.addDisposables(overlay.onDidChange(() => {
5643
+ // this is either a resize or a move
5644
+ // to inform the panels .layout(...) the group with it's current size
5645
+ // don't care about resize since the above watcher handles that
5646
+ group.layout(group.height, group.width);
5647
+ }), overlay.onDidChangeEnd(() => {
5648
+ this._bufferOnDidLayoutChange.fire();
5649
+ }), group.onDidChange((event) => {
5650
+ overlay.setBounds({
5651
+ height: event === null || event === void 0 ? void 0 : event.height,
5652
+ width: event === null || event === void 0 ? void 0 : event.width,
5653
+ });
5654
+ }), {
5655
+ dispose: () => {
5656
+ disposable.dispose();
5657
+ group.model.isFloating = false;
5658
+ remove(this.floatingGroups, floatingGroupPanel);
5659
+ this.updateWatermark();
5660
+ },
5661
+ });
5662
+ this.floatingGroups.push(floatingGroupPanel);
5663
+ this.updateWatermark();
5664
+ }
5115
5665
  orthogonalize(position) {
5116
5666
  switch (position) {
5117
5667
  case 'top':
@@ -5134,6 +5684,7 @@
5134
5684
  switch (position) {
5135
5685
  case 'top':
5136
5686
  case 'left':
5687
+ case 'center':
5137
5688
  return this.createGroupAtLocation([0]); // insert into first position
5138
5689
  case 'bottom':
5139
5690
  case 'right':
@@ -5151,6 +5702,15 @@
5151
5702
  }
5152
5703
  this.layout(this.gridview.width, this.gridview.height, true);
5153
5704
  }
5705
+ layout(width, height, forceResize) {
5706
+ super.layout(width, height, forceResize);
5707
+ if (this.floatingGroups) {
5708
+ for (const floating of this.floatingGroups) {
5709
+ // ensure floting groups stay within visible boundaries
5710
+ floating.overlay.setBounds();
5711
+ }
5712
+ }
5713
+ }
5154
5714
  focus() {
5155
5715
  var _a;
5156
5716
  (_a = this.activeGroup) === null || _a === void 0 ? void 0 : _a.focus();
@@ -5213,51 +5773,81 @@
5213
5773
  collection[panel.id] = panel.toJSON();
5214
5774
  return collection;
5215
5775
  }, {});
5216
- return {
5776
+ const floats = this.floatingGroups.map((floatingGroup) => {
5777
+ return {
5778
+ data: floatingGroup.group.toJSON(),
5779
+ position: floatingGroup.overlay.toJSON(),
5780
+ };
5781
+ });
5782
+ const result = {
5217
5783
  grid: data,
5218
5784
  panels,
5219
5785
  activeGroup: (_a = this.activeGroup) === null || _a === void 0 ? void 0 : _a.id,
5220
5786
  };
5787
+ if (floats.length > 0) {
5788
+ result.floatingGroups = floats;
5789
+ }
5790
+ return result;
5221
5791
  }
5222
5792
  fromJSON(data) {
5793
+ var _a;
5223
5794
  this.clear();
5224
5795
  const { grid, panels, activeGroup } = data;
5225
5796
  if (grid.root.type !== 'branch' || !Array.isArray(grid.root.data)) {
5226
5797
  throw new Error('root must be of type branch');
5227
5798
  }
5799
+ // take note of the existing dimensions
5800
+ const width = this.width;
5801
+ const height = this.height;
5802
+ const createGroupFromSerializedState = (data) => {
5803
+ const { id, locked, hideHeader, views, activeView } = data;
5804
+ const group = this.createGroup({
5805
+ id,
5806
+ locked: !!locked,
5807
+ hideHeader: !!hideHeader,
5808
+ });
5809
+ this._onDidAddGroup.fire(group);
5810
+ for (const child of views) {
5811
+ const panel = this._deserializer.fromJSON(panels[child], group);
5812
+ const isActive = typeof activeView === 'string' && activeView === panel.id;
5813
+ group.model.openPanel(panel, {
5814
+ skipSetPanelActive: !isActive,
5815
+ skipSetGroupActive: true,
5816
+ });
5817
+ }
5818
+ if (!group.activePanel && group.panels.length > 0) {
5819
+ group.model.openPanel(group.panels[group.panels.length - 1], {
5820
+ skipSetGroupActive: true,
5821
+ });
5822
+ }
5823
+ return group;
5824
+ };
5228
5825
  this.gridview.deserialize(grid, {
5229
5826
  fromJSON: (node) => {
5230
- const { id, locked, hideHeader, views, activeView } = node.data;
5231
- const group = this.createGroup({
5232
- id,
5233
- locked: !!locked,
5234
- hideHeader: !!hideHeader,
5235
- });
5236
- this._onDidAddGroup.fire(group);
5237
- for (const child of views) {
5238
- const panel = this._deserializer.fromJSON(panels[child], group);
5239
- const isActive = typeof activeView === 'string' &&
5240
- activeView === panel.id;
5241
- group.model.openPanel(panel, {
5242
- skipSetPanelActive: !isActive,
5243
- skipSetGroupActive: true,
5244
- });
5245
- }
5246
- if (!group.activePanel && group.panels.length > 0) {
5247
- group.model.openPanel(group.panels[group.panels.length - 1], {
5248
- skipSetGroupActive: true,
5249
- });
5250
- }
5251
- return group;
5827
+ return createGroupFromSerializedState(node.data);
5252
5828
  },
5253
5829
  });
5830
+ this.layout(width, height, true);
5831
+ const serializedFloatingGroups = (_a = data.floatingGroups) !== null && _a !== void 0 ? _a : [];
5832
+ for (const serializedFloatingGroup of serializedFloatingGroups) {
5833
+ const { data, position } = serializedFloatingGroup;
5834
+ const group = createGroupFromSerializedState(data);
5835
+ this.addFloatingGroup(group, {
5836
+ x: position.left,
5837
+ y: position.top,
5838
+ height: position.height,
5839
+ width: position.width,
5840
+ }, { skipRemoveGroup: true, inDragMode: false });
5841
+ }
5842
+ for (const floatingGroup of this.floatingGroups) {
5843
+ floatingGroup.overlay.setBounds();
5844
+ }
5254
5845
  if (typeof activeGroup === 'string') {
5255
5846
  const panel = this.getPanel(activeGroup);
5256
5847
  if (panel) {
5257
5848
  this.doSetGroupActive(panel);
5258
5849
  }
5259
5850
  }
5260
- this.gridview.layout(this.width, this.height);
5261
5851
  this._onDidLayoutFromJSON.fire();
5262
5852
  }
5263
5853
  clear() {
@@ -5266,7 +5856,7 @@
5266
5856
  const hasActivePanel = !!this.activePanel;
5267
5857
  for (const group of groups) {
5268
5858
  // remove the group will automatically remove the panels
5269
- this.removeGroup(group, true);
5859
+ this.removeGroup(group, { skipActive: true });
5270
5860
  }
5271
5861
  if (hasActiveGroup) {
5272
5862
  this.doSetGroupActive(undefined);
@@ -5288,6 +5878,9 @@
5288
5878
  throw new Error(`panel with id ${options.id} already exists`);
5289
5879
  }
5290
5880
  let referenceGroup;
5881
+ if (options.position && options.floating) {
5882
+ throw new Error('you can only provide one of: position, floating as arguments to .addPanel(...)');
5883
+ }
5291
5884
  if (options.position) {
5292
5885
  if (isPanelOptionsWithPanel(options.position)) {
5293
5886
  const referencePanel = typeof options.position.referencePanel === 'string'
@@ -5320,7 +5913,20 @@
5320
5913
  let panel;
5321
5914
  if (referenceGroup) {
5322
5915
  const target = toTarget(((_b = options.position) === null || _b === void 0 ? void 0 : _b.direction) || 'within');
5323
- if (target === 'center') {
5916
+ if (options.floating) {
5917
+ const group = this.createGroup();
5918
+ panel = this.createPanel(options, group);
5919
+ group.model.openPanel(panel);
5920
+ const o = typeof options.floating === 'object' &&
5921
+ options.floating !== null
5922
+ ? options.floating
5923
+ : {};
5924
+ this.addFloatingGroup(group, o, {
5925
+ inDragMode: false,
5926
+ skipRemoveGroup: true,
5927
+ });
5928
+ }
5929
+ else if (referenceGroup.api.isFloating || target === 'center') {
5324
5930
  panel = this.createPanel(options, referenceGroup);
5325
5931
  referenceGroup.model.openPanel(panel);
5326
5932
  }
@@ -5332,6 +5938,19 @@
5332
5938
  group.model.openPanel(panel);
5333
5939
  }
5334
5940
  }
5941
+ else if (options.floating) {
5942
+ const group = this.createGroup();
5943
+ panel = this.createPanel(options, group);
5944
+ group.model.openPanel(panel);
5945
+ const o = typeof options.floating === 'object' &&
5946
+ options.floating !== null
5947
+ ? options.floating
5948
+ : {};
5949
+ this.addFloatingGroup(group, o, {
5950
+ inDragMode: false,
5951
+ skipRemoveGroup: true,
5952
+ });
5953
+ }
5335
5954
  else {
5336
5955
  const group = this.createGroupAtLocation();
5337
5956
  panel = this.createPanel(options, group);
@@ -5348,7 +5967,9 @@
5348
5967
  throw new Error(`cannot remove panel ${panel.id}. it's missing a group.`);
5349
5968
  }
5350
5969
  group.model.removePanel(panel);
5351
- panel.dispose();
5970
+ if (!options.skipDispose) {
5971
+ panel.dispose();
5972
+ }
5352
5973
  if (group.size === 0 && options.removeEmptyGroup) {
5353
5974
  this.removeGroup(group);
5354
5975
  }
@@ -5363,7 +5984,7 @@
5363
5984
  }
5364
5985
  updateWatermark() {
5365
5986
  var _a, _b;
5366
- if (this.groups.length === 0) {
5987
+ if (this.groups.filter((x) => !x.api.isFloating).length === 0) {
5367
5988
  if (!this.watermark) {
5368
5989
  this.watermark = this.createWatermarkComponent();
5369
5990
  this.watermark.init({
@@ -5372,7 +5993,7 @@
5372
5993
  const watermarkContainer = document.createElement('div');
5373
5994
  watermarkContainer.className = 'dv-watermark-container';
5374
5995
  watermarkContainer.appendChild(this.watermark.element);
5375
- this.element.appendChild(watermarkContainer);
5996
+ this.gridview.element.appendChild(watermarkContainer);
5376
5997
  }
5377
5998
  }
5378
5999
  else if (this.watermark) {
@@ -5422,15 +6043,28 @@
5422
6043
  return group;
5423
6044
  }
5424
6045
  }
5425
- removeGroup(group, skipActive = false) {
6046
+ removeGroup(group, options) {
6047
+ var _a;
5426
6048
  const panels = [...group.panels]; // reassign since group panels will mutate
5427
6049
  for (const panel of panels) {
5428
6050
  this.removePanel(panel, {
5429
6051
  removeEmptyGroup: false,
5430
- skipDispose: false,
6052
+ skipDispose: (_a = options === null || options === void 0 ? void 0 : options.skipDispose) !== null && _a !== void 0 ? _a : false,
5431
6053
  });
5432
6054
  }
5433
- super.doRemoveGroup(group, { skipActive });
6055
+ this.doRemoveGroup(group, options);
6056
+ }
6057
+ doRemoveGroup(group, options) {
6058
+ const floatingGroup = this.floatingGroups.find((_) => _.group === group);
6059
+ if (floatingGroup) {
6060
+ if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
6061
+ floatingGroup.group.dispose();
6062
+ this._groups.delete(group.id);
6063
+ }
6064
+ floatingGroup.dispose();
6065
+ return floatingGroup.group;
6066
+ }
6067
+ return super.doRemoveGroup(group, options);
5434
6068
  }
5435
6069
  moveGroupOrPanel(destinationGroup, sourceGroupId, sourceItemId, destinationTarget, destinationIndex) {
5436
6070
  var _a;
@@ -5461,25 +6095,26 @@
5461
6095
  const targetLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
5462
6096
  if (sourceGroup && sourceGroup.size < 2) {
5463
6097
  const [targetParentLocation, to] = tail(targetLocation);
5464
- const sourceLocation = getGridLocation(sourceGroup.element);
5465
- const [sourceParentLocation, from] = tail(sourceLocation);
5466
- if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
5467
- // special case when 'swapping' two views within same grid location
5468
- // if a group has one tab - we are essentially moving the 'group'
5469
- // which is equivalent to swapping two views in this case
5470
- this.gridview.moveView(sourceParentLocation, from, to);
5471
- }
5472
- else {
5473
- // source group will become empty so delete the group
5474
- const targetGroup = this.doRemoveGroup(sourceGroup, {
5475
- skipActive: true,
5476
- skipDispose: true,
5477
- });
5478
- // after deleting the group we need to re-evaulate the ref location
5479
- const updatedReferenceLocation = getGridLocation(destinationGroup.element);
5480
- const location = getRelativeLocation(this.gridview.orientation, updatedReferenceLocation, destinationTarget);
5481
- this.doAddGroup(targetGroup, location);
6098
+ const isFloating = this.floatingGroups.find((x) => x.group === sourceGroup);
6099
+ if (!isFloating) {
6100
+ const sourceLocation = getGridLocation(sourceGroup.element);
6101
+ const [sourceParentLocation, from] = tail(sourceLocation);
6102
+ if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
6103
+ // special case when 'swapping' two views within same grid location
6104
+ // if a group has one tab - we are essentially moving the 'group'
6105
+ // which is equivalent to swapping two views in this case
6106
+ this.gridview.moveView(sourceParentLocation, from, to);
6107
+ }
5482
6108
  }
6109
+ // source group will become empty so delete the group
6110
+ const targetGroup = this.doRemoveGroup(sourceGroup, {
6111
+ skipActive: true,
6112
+ skipDispose: true,
6113
+ });
6114
+ // after deleting the group we need to re-evaulate the ref location
6115
+ const updatedReferenceLocation = getGridLocation(destinationGroup.element);
6116
+ const location = getRelativeLocation(this.gridview.orientation, updatedReferenceLocation, destinationTarget);
6117
+ this.doAddGroup(targetGroup, location);
5483
6118
  }
5484
6119
  else {
5485
6120
  const groupItem = (sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.removePanel(sourceItemId)) ||
@@ -5508,7 +6143,13 @@
5508
6143
  }
5509
6144
  }
5510
6145
  else {
5511
- this.gridview.removeView(getGridLocation(sourceGroup.element));
6146
+ const floatingGroup = this.floatingGroups.find((x) => x.group === sourceGroup);
6147
+ if (floatingGroup) {
6148
+ floatingGroup.dispose();
6149
+ }
6150
+ else {
6151
+ this.gridview.removeView(getGridLocation(sourceGroup.element));
6152
+ }
5512
6153
  const referenceLocation = getGridLocation(referenceGroup.element);
5513
6154
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, target);
5514
6155
  this.gridview.addView(sourceGroup, exports.Sizing.Distribute, dropLocation);
@@ -5663,6 +6304,9 @@
5663
6304
  this.clear();
5664
6305
  const { grid, activePanel } = serializedGridview;
5665
6306
  const queue = [];
6307
+ // take note of the existing dimensions
6308
+ const width = this.width;
6309
+ const height = this.height;
5666
6310
  this.gridview.deserialize(grid, {
5667
6311
  fromJSON: (node) => {
5668
6312
  const { data } = node;
@@ -5688,7 +6332,7 @@
5688
6332
  return view;
5689
6333
  },
5690
6334
  });
5691
- this.layout(this.width, this.height, true);
6335
+ this.layout(width, height, true);
5692
6336
  queue.forEach((f) => f());
5693
6337
  if (typeof activePanel === 'string') {
5694
6338
  const panel = this.getPanel(activePanel);
@@ -6002,6 +6646,9 @@
6002
6646
  this.clear();
6003
6647
  const { views, orientation, size, activeView } = serializedSplitview;
6004
6648
  const queue = [];
6649
+ // take note of the existing dimensions
6650
+ const width = this.width;
6651
+ const height = this.height;
6005
6652
  this.splitview = new Splitview(this.element, {
6006
6653
  orientation,
6007
6654
  proportionalLayout: this.options.proportionalLayout,
@@ -6038,7 +6685,7 @@
6038
6685
  }),
6039
6686
  },
6040
6687
  });
6041
- this.layout(this.width, this.height);
6688
+ this.layout(width, height);
6042
6689
  queue.forEach((f) => f());
6043
6690
  if (typeof activeView === 'string') {
6044
6691
  const panel = this.getPanel(activeView);
@@ -6305,6 +6952,9 @@
6305
6952
  this.clear();
6306
6953
  const { views, size } = serializedPaneview;
6307
6954
  const queue = [];
6955
+ // take note of the existing dimensions
6956
+ const width = this.width;
6957
+ const height = this.height;
6308
6958
  this.paneview = new Paneview(this.element, {
6309
6959
  orientation: exports.Orientation.VERTICAL,
6310
6960
  descriptor: {
@@ -6360,7 +7010,7 @@
6360
7010
  }),
6361
7011
  },
6362
7012
  });
6363
- this.layout(this.width, this.height);
7013
+ this.layout(width, height);
6364
7014
  queue.forEach((f) => f());
6365
7015
  this._onDidLayoutfromJSON.fire();
6366
7016
  }
@@ -6546,6 +7196,6 @@
6546
7196
  exports.orthogonal = orthogonal;
6547
7197
  exports.positionToDirection = positionToDirection;
6548
7198
  exports.toTarget = toTarget;
6549
- exports.watchElementResize = watchElementResize;
6550
7199
 
6551
7200
  }));
7201
+ //# sourceMappingURL=dockview-core.noStyle.js.map