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
  */
@@ -273,6 +273,31 @@ define(['exports'], (function (exports) { 'use strict';
273
273
  }
274
274
  }
275
275
 
276
+ function createComponent(id, componentName, components = {}, frameworkComponents = {}, createFrameworkComponent, fallback) {
277
+ const Component = typeof componentName === 'string'
278
+ ? components[componentName]
279
+ : undefined;
280
+ const FrameworkComponent = typeof componentName === 'string'
281
+ ? frameworkComponents[componentName]
282
+ : undefined;
283
+ if (Component && FrameworkComponent) {
284
+ throw new Error(`Cannot create '${id}'. component '${componentName}' registered as both a component and frameworkComponent`);
285
+ }
286
+ if (FrameworkComponent) {
287
+ if (!createFrameworkComponent) {
288
+ throw new Error(`Cannot create '${id}' for framework component '${componentName}'. you must register a frameworkPanelWrapper to use framework components`);
289
+ }
290
+ return createFrameworkComponent.createComponent(id, componentName, FrameworkComponent);
291
+ }
292
+ if (!Component) {
293
+ if (fallback) {
294
+ return fallback();
295
+ }
296
+ throw new Error(`Cannot create '${id}', no component '${componentName}' provided`);
297
+ }
298
+ return new Component(id, componentName);
299
+ }
300
+
276
301
  function watchElementResize(element, cb) {
277
302
  const observer = new ResizeObserver((entires) => {
278
303
  /**
@@ -386,31 +411,16 @@ define(['exports'], (function (exports) { 'use strict';
386
411
  refreshState() {
387
412
  this._refreshStateHandler();
388
413
  }
389
- }
390
-
391
- function createComponent(id, componentName, components = {}, frameworkComponents = {}, createFrameworkComponent, fallback) {
392
- const Component = typeof componentName === 'string'
393
- ? components[componentName]
394
- : undefined;
395
- const FrameworkComponent = typeof componentName === 'string'
396
- ? frameworkComponents[componentName]
397
- : undefined;
398
- if (Component && FrameworkComponent) {
399
- throw new Error(`Cannot create '${id}'. component '${componentName}' registered as both a component and frameworkComponent`);
400
- }
401
- if (FrameworkComponent) {
402
- if (!createFrameworkComponent) {
403
- throw new Error(`Cannot create '${id}' for framework component '${componentName}'. you must register a frameworkPanelWrapper to use framework components`);
404
- }
405
- return createFrameworkComponent.createComponent(id, componentName, FrameworkComponent);
406
- }
407
- if (!Component) {
408
- if (fallback) {
409
- return fallback();
410
- }
411
- throw new Error(`Cannot create '${id}', no component '${componentName}' provided`);
412
- }
413
- return new Component(id, componentName);
414
+ }
415
+ // quasi: apparently, but not really; seemingly
416
+ const QUASI_PREVENT_DEFAULT_KEY = 'dv-quasiPreventDefault';
417
+ // mark an event directly for other listeners to check
418
+ function quasiPreventDefault(event) {
419
+ event[QUASI_PREVENT_DEFAULT_KEY] = true;
420
+ }
421
+ // check if this event has been marked
422
+ function quasiDefaultPrevented(event) {
423
+ return event[QUASI_PREVENT_DEFAULT_KEY];
414
424
  }
415
425
 
416
426
  function tail(arr) {
@@ -461,6 +471,14 @@ define(['exports'], (function (exports) { 'use strict';
461
471
  }
462
472
  }
463
473
  return -1;
474
+ }
475
+ function remove(array, value) {
476
+ const index = array.findIndex((t) => t === value);
477
+ if (index > -1) {
478
+ array.splice(index, 1);
479
+ return true;
480
+ }
481
+ return false;
464
482
  }
465
483
 
466
484
  const clamp = (value, min, max) => {
@@ -890,7 +908,7 @@ define(['exports'], (function (exports) { 'use strict';
890
908
  //add sash
891
909
  const sash = document.createElement('div');
892
910
  sash.className = 'sash';
893
- const onStart = (event) => {
911
+ const onPointerStart = (event) => {
894
912
  for (const item of this.viewItems) {
895
913
  item.enabled = false;
896
914
  }
@@ -949,11 +967,10 @@ define(['exports'], (function (exports) { 'use strict';
949
967
  size: snappedViewItem.size,
950
968
  };
951
969
  }
952
- //
953
- const mousemove = (mousemoveEvent) => {
970
+ const onPointerMove = (event) => {
954
971
  const current = this._orientation === exports.Orientation.HORIZONTAL
955
- ? mousemoveEvent.clientX
956
- : mousemoveEvent.clientY;
972
+ ? event.clientX
973
+ : event.clientY;
957
974
  const delta = current - start;
958
975
  this.resize(sashIndex, delta, sizes, undefined, undefined, minDelta, maxDelta, snapBefore, snapAfter);
959
976
  this.distributeEmptySpace();
@@ -967,18 +984,20 @@ define(['exports'], (function (exports) { 'use strict';
967
984
  iframe.style.pointerEvents = 'auto';
968
985
  }
969
986
  this.saveProportions();
970
- document.removeEventListener('mousemove', mousemove);
971
- document.removeEventListener('mouseup', end);
987
+ document.removeEventListener('pointermove', onPointerMove);
988
+ document.removeEventListener('pointerup', end);
989
+ document.removeEventListener('pointercancel', end);
972
990
  this._onDidSashEnd.fire(undefined);
973
991
  };
974
- document.addEventListener('mousemove', mousemove);
975
- document.addEventListener('mouseup', end);
992
+ document.addEventListener('pointermove', onPointerMove);
993
+ document.addEventListener('pointerup', end);
994
+ document.addEventListener('pointercancel', end);
976
995
  };
977
- sash.addEventListener('mousedown', onStart);
996
+ sash.addEventListener('pointerdown', onPointerStart);
978
997
  const sashItem = {
979
998
  container: sash,
980
999
  disposable: () => {
981
- sash.removeEventListener('mousedown', onStart);
1000
+ sash.removeEventListener('pointerdown', onPointerStart);
982
1001
  this.sashContainer.removeChild(sash);
983
1002
  },
984
1003
  };
@@ -1602,7 +1621,7 @@ define(['exports'], (function (exports) { 'use strict';
1602
1621
  : true,
1603
1622
  };
1604
1623
  }),
1605
- size: this.size,
1624
+ size: this.orthogonalSize,
1606
1625
  };
1607
1626
  this.children = childDescriptors.map((c) => c.node);
1608
1627
  this.splitview = new Splitview(this.element, {
@@ -1665,7 +1684,7 @@ define(['exports'], (function (exports) { 'use strict';
1665
1684
  layout(size, orthogonalSize) {
1666
1685
  this._size = orthogonalSize;
1667
1686
  this._orthogonalSize = size;
1668
- this.splitview.layout(this.size, this.orthogonalSize);
1687
+ this.splitview.layout(orthogonalSize, size);
1669
1688
  }
1670
1689
  addChild(node, size, index, skipLayout) {
1671
1690
  if (index < 0 || index > this.children.length) {
@@ -1890,9 +1909,9 @@ define(['exports'], (function (exports) { 'use strict';
1890
1909
  this._deserialize(json.root, orientation, deserializer, height);
1891
1910
  }
1892
1911
  _deserialize(root, orientation, deserializer, orthogonalSize) {
1893
- this.root = this._deserializeNode(root, orientation, deserializer, orthogonalSize, true);
1912
+ this.root = this._deserializeNode(root, orientation, deserializer, orthogonalSize);
1894
1913
  }
1895
- _deserializeNode(node, orientation, deserializer, orthogonalSize, isRoot = false) {
1914
+ _deserializeNode(node, orientation, deserializer, orthogonalSize) {
1896
1915
  let result;
1897
1916
  if (node.type === 'branch') {
1898
1917
  const serializedChildren = node.data;
@@ -1902,9 +1921,9 @@ define(['exports'], (function (exports) { 'use strict';
1902
1921
  visible: serializedChild.visible,
1903
1922
  };
1904
1923
  });
1905
- // HORIZONTAL => height=orthogonalsize width=size
1906
- // VERTICAL => height=size width=orthogonalsize
1907
- result = new BranchNode(orientation, this.proportionalLayout, this.styles, isRoot ? orthogonalSize : node.size, isRoot ? node.size : orthogonalSize, children);
1924
+ result = new BranchNode(orientation, this.proportionalLayout, this.styles, node.size, // <- orthogonal size - flips at each depth
1925
+ orthogonalSize, // <- size - flips at each depth
1926
+ children);
1908
1927
  }
1909
1928
  else {
1910
1929
  result = new LeafNode(deserializer.fromJSON(node), orientation, orthogonalSize, node.size);
@@ -1937,7 +1956,8 @@ define(['exports'], (function (exports) { 'use strict';
1937
1956
  const oldRoot = this.root;
1938
1957
  oldRoot.element.remove();
1939
1958
  this._root = new BranchNode(orthogonal(oldRoot.orientation), this.proportionalLayout, this.styles, this.root.orthogonalSize, this.root.size);
1940
- if (oldRoot.children.length === 1) {
1959
+ if (oldRoot.children.length === 0) ;
1960
+ else if (oldRoot.children.length === 1) {
1941
1961
  // can remove one level of redundant branching if there is only a single child
1942
1962
  const childReference = oldRoot.children[0];
1943
1963
  const child = oldRoot.removeChild(0); // remove to prevent disposal when disposing of unwanted root
@@ -2071,52 +2091,70 @@ define(['exports'], (function (exports) { 'use strict';
2071
2091
  if (!(parent instanceof BranchNode)) {
2072
2092
  throw new Error('Invalid location');
2073
2093
  }
2074
- const node = parent.children[index];
2075
- if (!(node instanceof LeafNode)) {
2094
+ const nodeToRemove = parent.children[index];
2095
+ if (!(nodeToRemove instanceof LeafNode)) {
2076
2096
  throw new Error('Invalid location');
2077
2097
  }
2078
2098
  parent.removeChild(index, sizing);
2079
- if (parent.children.length === 0) {
2080
- return node.view;
2081
- }
2082
- if (parent.children.length > 1) {
2083
- return node.view;
2084
- }
2099
+ nodeToRemove.dispose();
2100
+ if (parent.children.length !== 1) {
2101
+ return nodeToRemove.view;
2102
+ }
2103
+ // if the parent has only one child and we know the parent is a BranchNode we can make the tree
2104
+ // more efficiently spaced by replacing the parent BranchNode with the child.
2105
+ // if that child is a LeafNode then we simply replace the BranchNode with the child otherwise if the child
2106
+ // is a BranchNode too we should spread it's children into the grandparent.
2107
+ // refer to the remaining child as the sibling
2085
2108
  const sibling = parent.children[0];
2086
2109
  if (pathToParent.length === 0) {
2087
- // parent is root
2110
+ // if the parent is root
2088
2111
  if (sibling instanceof LeafNode) {
2089
- return node.view;
2112
+ // if the sibling is a leaf node no action is required
2113
+ return nodeToRemove.view;
2090
2114
  }
2091
- // we must promote sibling to be the new root
2115
+ // otherwise the sibling is a branch node. since the parent is the root and the root has only one child
2116
+ // which is a branch node we can just set this branch node to be the new root node
2117
+ // for good housekeeping we'll removing the sibling from it's existing tree
2092
2118
  parent.removeChild(0, sizing);
2119
+ // and set that sibling node to be root
2093
2120
  this.root = sibling;
2094
- return node.view;
2121
+ return nodeToRemove.view;
2095
2122
  }
2123
+ // otherwise the parent is apart of a large sub-tree
2096
2124
  const [grandParent, ..._] = [...pathToParent].reverse();
2097
2125
  const [parentIndex, ...__] = [...rest].reverse();
2098
2126
  const isSiblingVisible = parent.isChildVisible(0);
2127
+ // either way we need to remove the sibling from it's existing tree
2099
2128
  parent.removeChild(0, sizing);
2129
+ // note the sizes of all of the grandparents children
2100
2130
  const sizes = grandParent.children.map((_size, i) => grandParent.getChildSize(i));
2101
- grandParent.removeChild(parentIndex, sizing);
2131
+ // remove the parent from the grandparent since we are moving the sibling to take the parents place
2132
+ // this parent is no longer used and can be disposed of
2133
+ grandParent.removeChild(parentIndex, sizing).dispose();
2102
2134
  if (sibling instanceof BranchNode) {
2135
+ // replace the parent with the siblings children
2103
2136
  sizes.splice(parentIndex, 1, ...sibling.children.map((c) => c.size));
2137
+ // and add those siblings to the grandparent
2104
2138
  for (let i = 0; i < sibling.children.length; i++) {
2105
2139
  const child = sibling.children[i];
2106
2140
  grandParent.addChild(child, child.size, parentIndex + i);
2107
2141
  }
2108
2142
  }
2109
2143
  else {
2144
+ // otherwise create a new leaf node and add that to the grandparent
2110
2145
  const newSibling = new LeafNode(sibling.view, orthogonal(sibling.orientation), sibling.size);
2111
2146
  const siblingSizing = isSiblingVisible
2112
2147
  ? sibling.orthogonalSize
2113
2148
  : exports.Sizing.Invisible(sibling.orthogonalSize);
2114
2149
  grandParent.addChild(newSibling, siblingSizing, parentIndex);
2115
2150
  }
2151
+ // the containing node of the sibling is no longer required and can be disposed of
2152
+ sibling.dispose();
2153
+ // resize everything
2116
2154
  for (let i = 0; i < sizes.length; i++) {
2117
2155
  grandParent.resizeChild(i, sizes[i]);
2118
2156
  }
2119
- return node.view;
2157
+ return nodeToRemove.view;
2120
2158
  }
2121
2159
  layout(width, height) {
2122
2160
  const [size, orthogonalSize] = this.root.orientation === exports.Orientation.HORIZONTAL
@@ -2435,6 +2473,9 @@ define(['exports'], (function (exports) { 'use strict';
2435
2473
  addPanel(options) {
2436
2474
  return this.component.addPanel(options);
2437
2475
  }
2476
+ removePanel(panel) {
2477
+ this.component.removePanel(panel);
2478
+ }
2438
2479
  addGroup(options) {
2439
2480
  return this.component.addGroup(options);
2440
2481
  }
@@ -2453,6 +2494,9 @@ define(['exports'], (function (exports) { 'use strict';
2453
2494
  getGroup(id) {
2454
2495
  return this.component.getPanel(id);
2455
2496
  }
2497
+ addFloatingGroup(item, coord) {
2498
+ return this.component.addFloatingGroup(item, coord);
2499
+ }
2456
2500
  fromJSON(data) {
2457
2501
  this.component.fromJSON(data);
2458
2502
  }
@@ -2545,10 +2589,14 @@ define(['exports'], (function (exports) { 'use strict';
2545
2589
  this._onDrop = new Emitter();
2546
2590
  this.onDrop = this._onDrop.event;
2547
2591
  // use a set to take advantage of #<set>.has
2548
- const acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
2592
+ this._acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
2549
2593
  this.addDisposables(this._onDrop, new DragAndDropObserver(this.element, {
2550
2594
  onDragEnter: () => undefined,
2551
2595
  onDragOver: (e) => {
2596
+ if (this._acceptedTargetZonesSet.size === 0) {
2597
+ this.removeDropTarget();
2598
+ return;
2599
+ }
2552
2600
  const width = this.element.clientWidth;
2553
2601
  const height = this.element.clientHeight;
2554
2602
  if (width === 0 || height === 0) {
@@ -2557,20 +2605,28 @@ define(['exports'], (function (exports) { 'use strict';
2557
2605
  const rect = e.currentTarget.getBoundingClientRect();
2558
2606
  const x = e.clientX - rect.left;
2559
2607
  const y = e.clientY - rect.top;
2560
- const quadrant = this.calculateQuadrant(acceptedTargetZonesSet, x, y, width, height);
2561
- if (quadrant === null) {
2608
+ const quadrant = this.calculateQuadrant(this._acceptedTargetZonesSet, x, y, width, height);
2609
+ /**
2610
+ * If the event has already been used by another DropTarget instance
2611
+ * then don't show a second drop target, only one target should be
2612
+ * active at any one time
2613
+ */
2614
+ if (this.isAlreadyUsed(e) || quadrant === null) {
2562
2615
  // no drop target should be displayed
2563
2616
  this.removeDropTarget();
2564
2617
  return;
2565
2618
  }
2566
2619
  if (typeof this.options.canDisplayOverlay === 'boolean') {
2567
2620
  if (!this.options.canDisplayOverlay) {
2621
+ this.removeDropTarget();
2568
2622
  return;
2569
2623
  }
2570
2624
  }
2571
2625
  else if (!this.options.canDisplayOverlay(e, quadrant)) {
2626
+ this.removeDropTarget();
2572
2627
  return;
2573
2628
  }
2629
+ this.markAsUsed(e);
2574
2630
  if (!this.targetElement) {
2575
2631
  this.targetElement = document.createElement('div');
2576
2632
  this.targetElement.className = 'drop-target-dropzone';
@@ -2581,12 +2637,6 @@ define(['exports'], (function (exports) { 'use strict';
2581
2637
  this.element.classList.add('drop-target');
2582
2638
  this.element.append(this.targetElement);
2583
2639
  }
2584
- if (this.options.acceptedTargetZones.length === 0) {
2585
- return;
2586
- }
2587
- if (!this.targetElement || !this.overlayElement) {
2588
- return;
2589
- }
2590
2640
  this.toggleClasses(quadrant, width, height);
2591
2641
  this.setState(quadrant);
2592
2642
  },
@@ -2609,10 +2659,26 @@ define(['exports'], (function (exports) { 'use strict';
2609
2659
  },
2610
2660
  }));
2611
2661
  }
2662
+ setTargetZones(acceptedTargetZones) {
2663
+ this._acceptedTargetZonesSet = new Set(acceptedTargetZones);
2664
+ }
2612
2665
  dispose() {
2613
2666
  this.removeDropTarget();
2614
2667
  super.dispose();
2615
2668
  }
2669
+ /**
2670
+ * Add a property to the event object for other potential listeners to check
2671
+ */
2672
+ markAsUsed(event) {
2673
+ event[Droptarget.USED_EVENT_ID] = true;
2674
+ }
2675
+ /**
2676
+ * Check is the event has already been used by another instance od DropTarget
2677
+ */
2678
+ isAlreadyUsed(event) {
2679
+ const value = event[Droptarget.USED_EVENT_ID];
2680
+ return typeof value === 'boolean' && value;
2681
+ }
2616
2682
  toggleClasses(quadrant, width, height) {
2617
2683
  var _a, _b, _c, _d;
2618
2684
  if (!this.overlayElement) {
@@ -2707,6 +2773,7 @@ define(['exports'], (function (exports) { 'use strict';
2707
2773
  }
2708
2774
  }
2709
2775
  }
2776
+ Droptarget.USED_EVENT_ID = '__dockview_droptarget_event_is_used__';
2710
2777
  function calculateQuadrantAsPercentage(overlayType, x, y, width, height, threshold) {
2711
2778
  const xp = (100 * x) / width;
2712
2779
  const yp = (100 * y) / height;
@@ -2836,8 +2903,15 @@ define(['exports'], (function (exports) { 'use strict';
2836
2903
  this.addDisposables(this._onDragStart, this.dataDisposable, this.pointerEventsDisposable);
2837
2904
  this.configure();
2838
2905
  }
2906
+ isCancelled(_event) {
2907
+ return false;
2908
+ }
2839
2909
  configure() {
2840
2910
  this.addDisposables(this._onDragStart, addDisposableListener(this.el, 'dragstart', (event) => {
2911
+ if (this.isCancelled(event)) {
2912
+ event.preventDefault();
2913
+ return;
2914
+ }
2841
2915
  const iframes = [
2842
2916
  ...getElementsByTagName('iframe'),
2843
2917
  ...getElementsByTagName('webview'),
@@ -2911,13 +2985,6 @@ define(['exports'], (function (exports) { 'use strict';
2911
2985
  if (event.defaultPrevented) {
2912
2986
  return;
2913
2987
  }
2914
- /**
2915
- * TODO: alternative to stopPropagation
2916
- *
2917
- * I need to stop the event propagation here since otherwise it'll be intercepted by event handlers
2918
- * on the tabs-container. I cannot use event.preventDefault() since I need the on DragStart event to occur
2919
- */
2920
- event.stopPropagation();
2921
2988
  this._onChanged.fire(event);
2922
2989
  }));
2923
2990
  this.droptarget = new Droptarget(this._element, {
@@ -2975,6 +3042,22 @@ define(['exports'], (function (exports) { 'use strict';
2975
3042
  this.accessorId = accessorId;
2976
3043
  this.group = group;
2977
3044
  this.panelTransfer = LocalSelectionTransfer.getInstance();
3045
+ this.addDisposables(addDisposableListener(element, 'mousedown', (e) => {
3046
+ if (e.shiftKey) {
3047
+ /**
3048
+ * You cannot call e.preventDefault() because that will prevent drag events from firing
3049
+ * but we also need to stop any group overlay drag events from occuring
3050
+ * Use a custom event marker that can be checked by the overlay drag events
3051
+ */
3052
+ quasiPreventDefault(e);
3053
+ }
3054
+ }, true));
3055
+ }
3056
+ isCancelled(_event) {
3057
+ if (this.group.api.isFloating && !_event.shiftKey) {
3058
+ return true;
3059
+ }
3060
+ return false;
2978
3061
  }
2979
3062
  getData(dataTransfer) {
2980
3063
  this.panelTransfer.setData([new PanelTransfer(this.accessorId, this.group.id, null)], PanelTransfer.prototype);
@@ -3065,17 +3148,30 @@ define(['exports'], (function (exports) { 'use strict';
3065
3148
  hide() {
3066
3149
  this._element.style.display = 'none';
3067
3150
  }
3068
- setActionElement(element) {
3069
- if (this.actions === element) {
3151
+ setRightActionsElement(element) {
3152
+ if (this.rightActions === element) {
3070
3153
  return;
3071
3154
  }
3072
- if (this.actions) {
3073
- this.actions.remove();
3074
- this.actions = undefined;
3155
+ if (this.rightActions) {
3156
+ this.rightActions.remove();
3157
+ this.rightActions = undefined;
3075
3158
  }
3076
3159
  if (element) {
3077
- this.actionContainer.appendChild(element);
3078
- this.actions = element;
3160
+ this.rightActionsContainer.appendChild(element);
3161
+ this.rightActions = element;
3162
+ }
3163
+ }
3164
+ setLeftActionsElement(element) {
3165
+ if (this.leftActions === element) {
3166
+ return;
3167
+ }
3168
+ if (this.leftActions) {
3169
+ this.leftActions.remove();
3170
+ this.leftActions = undefined;
3171
+ }
3172
+ if (element) {
3173
+ this.leftActionsContainer.appendChild(element);
3174
+ this.leftActions = element;
3079
3175
  }
3080
3176
  }
3081
3177
  get element() {
@@ -3110,19 +3206,35 @@ define(['exports'], (function (exports) { 'use strict';
3110
3206
  toggleClass(this._element, 'dv-single-tab', this.size === 1);
3111
3207
  }
3112
3208
  }));
3113
- this.actionContainer = document.createElement('div');
3114
- this.actionContainer.className = 'action-container';
3209
+ this.rightActionsContainer = document.createElement('div');
3210
+ this.rightActionsContainer.className = 'right-actions-container';
3211
+ this.leftActionsContainer = document.createElement('div');
3212
+ this.leftActionsContainer.className = 'left-actions-container';
3115
3213
  this.tabContainer = document.createElement('div');
3116
3214
  this.tabContainer.className = 'tabs-container';
3117
3215
  this.voidContainer = new VoidContainer(this.accessor, this.group);
3118
3216
  this._element.appendChild(this.tabContainer);
3217
+ this._element.appendChild(this.leftActionsContainer);
3119
3218
  this._element.appendChild(this.voidContainer.element);
3120
- this._element.appendChild(this.actionContainer);
3219
+ this._element.appendChild(this.rightActionsContainer);
3121
3220
  this.addDisposables(this.voidContainer, this.voidContainer.onDrop((event) => {
3122
3221
  this._onDrop.fire({
3123
3222
  event: event.nativeEvent,
3124
3223
  index: this.tabs.length,
3125
3224
  });
3225
+ }), addDisposableListener(this.voidContainer.element, 'mousedown', (event) => {
3226
+ const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3227
+ if (isFloatingGroupsEnabled &&
3228
+ event.shiftKey &&
3229
+ !this.group.api.isFloating) {
3230
+ event.preventDefault();
3231
+ const { top, left } = this.element.getBoundingClientRect();
3232
+ const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
3233
+ this.accessor.addFloatingGroup(this.group, {
3234
+ x: left - rootLeft + 20,
3235
+ y: top - rootTop + 20,
3236
+ }, { inDragMode: true });
3237
+ }
3126
3238
  }), addDisposableListener(this.tabContainer, 'mousedown', (event) => {
3127
3239
  if (event.defaultPrevented) {
3128
3240
  return;
@@ -3176,6 +3288,21 @@ define(['exports'], (function (exports) { 'use strict';
3176
3288
  tabToAdd.setContent(panel.view.tab);
3177
3289
  const disposable = CompositeDisposable.from(tabToAdd.onChanged((event) => {
3178
3290
  var _a;
3291
+ const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3292
+ const isFloatingWithOnePanel = this.group.api.isFloating && this.size === 1;
3293
+ if (isFloatingGroupsEnabled &&
3294
+ !isFloatingWithOnePanel &&
3295
+ event.shiftKey) {
3296
+ event.preventDefault();
3297
+ const panel = this.accessor.getGroupPanel(tabToAdd.panelId);
3298
+ const { top, left } = tabToAdd.element.getBoundingClientRect();
3299
+ const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
3300
+ this.accessor.addFloatingGroup(panel, {
3301
+ x: left - rootLeft,
3302
+ y: top - rootTop,
3303
+ }, { inDragMode: true });
3304
+ return;
3305
+ }
3179
3306
  const alreadyFocused = panel.id === ((_a = this.group.model.activePanel) === null || _a === void 0 ? void 0 : _a.id) &&
3180
3307
  this.group.model.isContentFocused;
3181
3308
  const isLeftClick = event.button === 0;
@@ -3245,6 +3372,17 @@ define(['exports'], (function (exports) { 'use strict';
3245
3372
  }
3246
3373
  return isAncestor(document.activeElement, this.contentContainer.element);
3247
3374
  }
3375
+ get isFloating() {
3376
+ return this._isFloating;
3377
+ }
3378
+ set isFloating(value) {
3379
+ this._isFloating = value;
3380
+ this.dropTarget.setTargetZones(value ? ['center'] : ['top', 'bottom', 'left', 'right', 'center']);
3381
+ toggleClass(this.container, 'dv-groupview-floating', value);
3382
+ this.groupPanel.api._onDidFloatingStateChange.fire({
3383
+ isFloating: this.isFloating,
3384
+ });
3385
+ }
3248
3386
  constructor(container, accessor, id, options, groupPanel) {
3249
3387
  super();
3250
3388
  this.container = container;
@@ -3254,6 +3392,7 @@ define(['exports'], (function (exports) { 'use strict';
3254
3392
  this.groupPanel = groupPanel;
3255
3393
  this._isGroupActive = false;
3256
3394
  this._locked = false;
3395
+ this._isFloating = false;
3257
3396
  this.mostRecentlyUsed = [];
3258
3397
  this._onDidChange = new Emitter();
3259
3398
  this.onDidChange = this._onDidChange.event;
@@ -3270,7 +3409,7 @@ define(['exports'], (function (exports) { 'use strict';
3270
3409
  this.onDidRemovePanel = this._onDidRemovePanel.event;
3271
3410
  this._onDidActivePanelChange = new Emitter();
3272
3411
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
3273
- this.container.classList.add('groupview');
3412
+ toggleClass(this.container, 'groupview', true);
3274
3413
  this.tabsContainer = new TabsContainer(this.accessor, this.groupPanel);
3275
3414
  this.contentContainer = new ContentContainer();
3276
3415
  this.dropTarget = new Droptarget(this.contentContainer.element, {
@@ -3280,6 +3419,9 @@ define(['exports'], (function (exports) { 'use strict';
3280
3419
  return false;
3281
3420
  }
3282
3421
  const data = getPanelData();
3422
+ if (!data && event.shiftKey && !this.isFloating) {
3423
+ return false;
3424
+ }
3283
3425
  if (data && data.viewId === this.accessor.id) {
3284
3426
  if (data.groupId === this.id) {
3285
3427
  if (position === 'center') {
@@ -3324,14 +3466,25 @@ define(['exports'], (function (exports) { 'use strict';
3324
3466
  // correctly initialized
3325
3467
  this.setActive(this.isActive, true, true);
3326
3468
  this.updateContainer();
3327
- if (this.accessor.options.createGroupControlElement) {
3328
- this._control = this.accessor.options.createGroupControlElement(this.groupPanel);
3329
- this.addDisposables(this._control);
3330
- this._control.init({
3469
+ if (this.accessor.options.createRightHeaderActionsElement) {
3470
+ this._rightHeaderActions =
3471
+ this.accessor.options.createRightHeaderActionsElement(this.groupPanel);
3472
+ this.addDisposables(this._rightHeaderActions);
3473
+ this._rightHeaderActions.init({
3331
3474
  containerApi: new DockviewApi(this.accessor),
3332
3475
  api: this.groupPanel.api,
3333
3476
  });
3334
- this.tabsContainer.setActionElement(this._control.element);
3477
+ this.tabsContainer.setRightActionsElement(this._rightHeaderActions.element);
3478
+ }
3479
+ if (this.accessor.options.createLeftHeaderActionsElement) {
3480
+ this._leftHeaderActions =
3481
+ this.accessor.options.createLeftHeaderActionsElement(this.groupPanel);
3482
+ this.addDisposables(this._leftHeaderActions);
3483
+ this._leftHeaderActions.init({
3484
+ containerApi: new DockviewApi(this.accessor),
3485
+ api: this.groupPanel.api,
3486
+ });
3487
+ this.tabsContainer.setLeftActionsElement(this._leftHeaderActions.element);
3335
3488
  }
3336
3489
  }
3337
3490
  indexOf(panel) {
@@ -3464,7 +3617,7 @@ define(['exports'], (function (exports) { 'use strict';
3464
3617
  return this._activePanel === panel;
3465
3618
  }
3466
3619
  updateActions(element) {
3467
- this.tabsContainer.setActionElement(element);
3620
+ this.tabsContainer.setRightActionsElement(element);
3468
3621
  }
3469
3622
  setActive(isGroupActive, skipFocus = false, force = false) {
3470
3623
  var _a, _b, _c, _d;
@@ -3636,9 +3789,10 @@ define(['exports'], (function (exports) { 'use strict';
3636
3789
  }
3637
3790
  }
3638
3791
  dispose() {
3639
- var _a, _b;
3792
+ var _a, _b, _c;
3640
3793
  super.dispose();
3641
- (_b = (_a = this.watermark) === null || _a === void 0 ? void 0 : _a.dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
3794
+ (_a = this.watermark) === null || _a === void 0 ? void 0 : _a.element.remove();
3795
+ (_c = (_b = this.watermark) === null || _b === void 0 ? void 0 : _b.dispose) === null || _c === void 0 ? void 0 : _c.call(_b);
3642
3796
  for (const panel of this.panels) {
3643
3797
  panel.dispose();
3644
3798
  }
@@ -4432,8 +4586,8 @@ define(['exports'], (function (exports) { 'use strict';
4432
4586
  get isActive() {
4433
4587
  return this.api.isActive;
4434
4588
  }
4435
- constructor(id, component, options) {
4436
- super(id, component, new GridviewPanelApiImpl(id));
4589
+ constructor(id, component, options, api) {
4590
+ super(id, component, api !== null && api !== void 0 ? api : new GridviewPanelApiImpl(id));
4437
4591
  this._evaluatedMinimumWidth = 0;
4438
4592
  this._evaluatedMaximumWidth = Number.MAX_SAFE_INTEGER;
4439
4593
  this._evaluatedMinimumHeight = 0;
@@ -4531,6 +4685,32 @@ define(['exports'], (function (exports) { 'use strict';
4531
4685
  }
4532
4686
  }
4533
4687
 
4688
+ class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
4689
+ get isFloating() {
4690
+ if (!this._group) {
4691
+ throw new Error(`DockviewGroupPanelApiImpl not initialized`);
4692
+ }
4693
+ return this._group.model.isFloating;
4694
+ }
4695
+ constructor(id, accessor) {
4696
+ super(id);
4697
+ this.accessor = accessor;
4698
+ this._onDidFloatingStateChange = new Emitter();
4699
+ this.onDidFloatingStateChange = this._onDidFloatingStateChange.event;
4700
+ this.addDisposables(this._onDidFloatingStateChange);
4701
+ }
4702
+ moveTo(options) {
4703
+ var _a;
4704
+ if (!this._group) {
4705
+ throw new Error(`DockviewGroupPanelApiImpl not initialized`);
4706
+ }
4707
+ this.accessor.moveGroupOrPanel(options.group, this._group.id, undefined, (_a = options.position) !== null && _a !== void 0 ? _a : 'center');
4708
+ }
4709
+ initialize(group) {
4710
+ this._group = group;
4711
+ }
4712
+ }
4713
+
4534
4714
  class DockviewGroupPanel extends GridviewPanel {
4535
4715
  get panels() {
4536
4716
  return this._model.panels;
@@ -4557,7 +4737,8 @@ define(['exports'], (function (exports) { 'use strict';
4557
4737
  super(id, 'groupview_default', {
4558
4738
  minimumHeight: 100,
4559
4739
  minimumWidth: 100,
4560
- });
4740
+ }, new DockviewGroupPanelApiImpl(id, accessor));
4741
+ this.api.initialize(this); // cannot use 'this' after after 'super' call
4561
4742
  this._model = new DockviewGroupPanelModel(this.element, accessor, id, options, this);
4562
4743
  }
4563
4744
  initialize() {
@@ -4575,7 +4756,6 @@ define(['exports'], (function (exports) { 'use strict';
4575
4756
  return this._model;
4576
4757
  }
4577
4758
  toJSON() {
4578
- // TODO fix typing
4579
4759
  return this.model.toJSON();
4580
4760
  }
4581
4761
  }
@@ -4629,9 +4809,10 @@ define(['exports'], (function (exports) { 'use strict';
4629
4809
  get group() {
4630
4810
  return this._group;
4631
4811
  }
4632
- constructor(panel, group) {
4812
+ constructor(panel, group, accessor) {
4633
4813
  super(panel.id);
4634
4814
  this.panel = panel;
4815
+ this.accessor = accessor;
4635
4816
  this._onDidTitleChange = new Emitter();
4636
4817
  this.onDidTitleChange = this._onDidTitleChange.event;
4637
4818
  this._onDidActiveGroupChange = new Emitter();
@@ -4643,6 +4824,10 @@ define(['exports'], (function (exports) { 'use strict';
4643
4824
  this._group = group;
4644
4825
  this.addDisposables(this.disposable, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange);
4645
4826
  }
4827
+ moveTo(options) {
4828
+ var _a;
4829
+ this.accessor.moveGroupOrPanel(options.group, this._group.id, this.panel.id, (_a = options.position) !== null && _a !== void 0 ? _a : 'center', options.index);
4830
+ }
4646
4831
  setTitle(title) {
4647
4832
  this.panel.setTitle(title);
4648
4833
  }
@@ -4667,7 +4852,7 @@ define(['exports'], (function (exports) { 'use strict';
4667
4852
  this.containerApi = containerApi;
4668
4853
  this.view = view;
4669
4854
  this._group = group;
4670
- this.api = new DockviewPanelApiImpl(this, this._group);
4855
+ this.api = new DockviewPanelApiImpl(this, this._group, accessor);
4671
4856
  this.addDisposables(this.api.onActiveChange(() => {
4672
4857
  accessor.setActivePanel(this);
4673
4858
  }), this.api.onDidSizeChange((event) => {
@@ -5008,6 +5193,296 @@ define(['exports'], (function (exports) { 'use strict';
5008
5193
  }
5009
5194
  }
5010
5195
 
5196
+ const bringElementToFront = (() => {
5197
+ let previous = null;
5198
+ function pushToTop(element) {
5199
+ if (previous !== element && previous !== null) {
5200
+ toggleClass(previous, 'dv-bring-to-front', false);
5201
+ }
5202
+ toggleClass(element, 'dv-bring-to-front', true);
5203
+ previous = element;
5204
+ }
5205
+ return pushToTop;
5206
+ })();
5207
+ class Overlay extends CompositeDisposable {
5208
+ constructor(options) {
5209
+ super();
5210
+ this.options = options;
5211
+ this._element = document.createElement('div');
5212
+ this._onDidChange = new Emitter();
5213
+ this.onDidChange = this._onDidChange.event;
5214
+ this._onDidChangeEnd = new Emitter();
5215
+ this.onDidChangeEnd = this._onDidChangeEnd.event;
5216
+ this.addDisposables(this._onDidChange, this._onDidChangeEnd);
5217
+ this._element.className = 'dv-resize-container';
5218
+ this.setupResize('top');
5219
+ this.setupResize('bottom');
5220
+ this.setupResize('left');
5221
+ this.setupResize('right');
5222
+ this.setupResize('topleft');
5223
+ this.setupResize('topright');
5224
+ this.setupResize('bottomleft');
5225
+ this.setupResize('bottomright');
5226
+ this._element.appendChild(this.options.content);
5227
+ this.options.container.appendChild(this._element);
5228
+ // if input bad resize within acceptable boundaries
5229
+ this.setBounds({
5230
+ height: this.options.height,
5231
+ width: this.options.width,
5232
+ top: this.options.top,
5233
+ left: this.options.left,
5234
+ });
5235
+ }
5236
+ setBounds(bounds = {}) {
5237
+ if (typeof bounds.height === 'number') {
5238
+ this._element.style.height = `${bounds.height}px`;
5239
+ }
5240
+ if (typeof bounds.width === 'number') {
5241
+ this._element.style.width = `${bounds.width}px`;
5242
+ }
5243
+ if (typeof bounds.top === 'number') {
5244
+ this._element.style.top = `${bounds.top}px`;
5245
+ }
5246
+ if (typeof bounds.left === 'number') {
5247
+ this._element.style.left = `${bounds.left}px`;
5248
+ }
5249
+ const containerRect = this.options.container.getBoundingClientRect();
5250
+ const overlayRect = this._element.getBoundingClientRect();
5251
+ // region: ensure bounds within allowable limits
5252
+ // a minimum width of minimumViewportWidth must be inside the viewport
5253
+ const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5254
+ // a minimum height of minimumViewportHeight must be inside the viewport
5255
+ const yOffset = Math.max(0, overlayRect.height - this.options.minimumInViewportHeight);
5256
+ const left = clamp(overlayRect.left - containerRect.left, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5257
+ const top = clamp(overlayRect.top - containerRect.top, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5258
+ this._element.style.left = `${left}px`;
5259
+ this._element.style.top = `${top}px`;
5260
+ this._onDidChange.fire();
5261
+ }
5262
+ toJSON() {
5263
+ const container = this.options.container.getBoundingClientRect();
5264
+ const element = this._element.getBoundingClientRect();
5265
+ return {
5266
+ top: element.top - container.top,
5267
+ left: element.left - container.left,
5268
+ width: element.width,
5269
+ height: element.height,
5270
+ };
5271
+ }
5272
+ setupDrag(dragTarget, options = { inDragMode: false }) {
5273
+ const move = new MutableDisposable();
5274
+ const track = () => {
5275
+ let offset = null;
5276
+ const iframes = [
5277
+ ...getElementsByTagName('iframe'),
5278
+ ...getElementsByTagName('webview'),
5279
+ ];
5280
+ for (const iframe of iframes) {
5281
+ iframe.style.pointerEvents = 'none';
5282
+ }
5283
+ move.value = new CompositeDisposable({
5284
+ dispose: () => {
5285
+ for (const iframe of iframes) {
5286
+ iframe.style.pointerEvents = 'auto';
5287
+ }
5288
+ },
5289
+ }, addDisposableWindowListener(window, 'mousemove', (e) => {
5290
+ const containerRect = this.options.container.getBoundingClientRect();
5291
+ const x = e.clientX - containerRect.left;
5292
+ const y = e.clientY - containerRect.top;
5293
+ toggleClass(this._element, 'dv-resize-container-dragging', true);
5294
+ const overlayRect = this._element.getBoundingClientRect();
5295
+ if (offset === null) {
5296
+ offset = {
5297
+ x: e.clientX - overlayRect.left,
5298
+ y: e.clientY - overlayRect.top,
5299
+ };
5300
+ }
5301
+ const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5302
+ const yOffset = Math.max(0, overlayRect.height -
5303
+ this.options.minimumInViewportHeight);
5304
+ const left = clamp(x - offset.x, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5305
+ const top = clamp(y - offset.y, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5306
+ this.setBounds({ top, left });
5307
+ }), addDisposableWindowListener(window, 'mouseup', () => {
5308
+ toggleClass(this._element, 'dv-resize-container-dragging', false);
5309
+ move.dispose();
5310
+ this._onDidChangeEnd.fire();
5311
+ }));
5312
+ };
5313
+ this.addDisposables(move, addDisposableListener(dragTarget, 'mousedown', (event) => {
5314
+ if (event.defaultPrevented) {
5315
+ event.preventDefault();
5316
+ return;
5317
+ }
5318
+ // if somebody has marked this event then treat as a defaultPrevented
5319
+ // without actually calling event.preventDefault()
5320
+ if (quasiDefaultPrevented(event)) {
5321
+ return;
5322
+ }
5323
+ track();
5324
+ }), addDisposableListener(this.options.content, 'mousedown', (event) => {
5325
+ if (event.defaultPrevented) {
5326
+ return;
5327
+ }
5328
+ // if somebody has marked this event then treat as a defaultPrevented
5329
+ // without actually calling event.preventDefault()
5330
+ if (quasiDefaultPrevented(event)) {
5331
+ return;
5332
+ }
5333
+ if (event.shiftKey) {
5334
+ track();
5335
+ }
5336
+ }), addDisposableListener(this.options.content, 'mousedown', () => {
5337
+ bringElementToFront(this._element);
5338
+ }, true));
5339
+ bringElementToFront(this._element);
5340
+ if (options.inDragMode) {
5341
+ track();
5342
+ }
5343
+ }
5344
+ setupResize(direction) {
5345
+ const resizeHandleElement = document.createElement('div');
5346
+ resizeHandleElement.className = `dv-resize-handle-${direction}`;
5347
+ this._element.appendChild(resizeHandleElement);
5348
+ const move = new MutableDisposable();
5349
+ this.addDisposables(move, addDisposableListener(resizeHandleElement, 'mousedown', (e) => {
5350
+ e.preventDefault();
5351
+ let startPosition = null;
5352
+ const iframes = [
5353
+ ...getElementsByTagName('iframe'),
5354
+ ...getElementsByTagName('webview'),
5355
+ ];
5356
+ for (const iframe of iframes) {
5357
+ iframe.style.pointerEvents = 'none';
5358
+ }
5359
+ move.value = new CompositeDisposable(addDisposableWindowListener(window, 'mousemove', (e) => {
5360
+ const containerRect = this.options.container.getBoundingClientRect();
5361
+ const overlayRect = this._element.getBoundingClientRect();
5362
+ const y = e.clientY - containerRect.top;
5363
+ const x = e.clientX - containerRect.left;
5364
+ if (startPosition === null) {
5365
+ // record the initial dimensions since as all subsequence moves are relative to this
5366
+ startPosition = {
5367
+ originalY: y,
5368
+ originalHeight: overlayRect.height,
5369
+ originalX: x,
5370
+ originalWidth: overlayRect.width,
5371
+ };
5372
+ }
5373
+ let top = undefined;
5374
+ let height = undefined;
5375
+ let left = undefined;
5376
+ let width = undefined;
5377
+ const minimumInViewportHeight = this.options.minimumInViewportHeight;
5378
+ const minimumInViewportWidth = this.options.minimumInViewportWidth;
5379
+ function moveTop() {
5380
+ top = clamp(y, -Number.MAX_VALUE, startPosition.originalY +
5381
+ startPosition.originalHeight >
5382
+ containerRect.height
5383
+ ? containerRect.height -
5384
+ minimumInViewportHeight
5385
+ : Math.max(0, startPosition.originalY +
5386
+ startPosition.originalHeight -
5387
+ Overlay.MINIMUM_HEIGHT));
5388
+ height =
5389
+ startPosition.originalY +
5390
+ startPosition.originalHeight -
5391
+ top;
5392
+ }
5393
+ function moveBottom() {
5394
+ top =
5395
+ startPosition.originalY -
5396
+ startPosition.originalHeight;
5397
+ height = clamp(y - top, top < 0
5398
+ ? -top + minimumInViewportHeight
5399
+ : Overlay.MINIMUM_HEIGHT, Number.MAX_VALUE);
5400
+ }
5401
+ function moveLeft() {
5402
+ left = clamp(x, -Number.MAX_VALUE, startPosition.originalX +
5403
+ startPosition.originalWidth >
5404
+ containerRect.width
5405
+ ? containerRect.width -
5406
+ minimumInViewportWidth
5407
+ : Math.max(0, startPosition.originalX +
5408
+ startPosition.originalWidth -
5409
+ Overlay.MINIMUM_WIDTH));
5410
+ width =
5411
+ startPosition.originalX +
5412
+ startPosition.originalWidth -
5413
+ left;
5414
+ }
5415
+ function moveRight() {
5416
+ left =
5417
+ startPosition.originalX -
5418
+ startPosition.originalWidth;
5419
+ width = clamp(x - left, left < 0
5420
+ ? -left + minimumInViewportWidth
5421
+ : Overlay.MINIMUM_WIDTH, Number.MAX_VALUE);
5422
+ }
5423
+ switch (direction) {
5424
+ case 'top':
5425
+ moveTop();
5426
+ break;
5427
+ case 'bottom':
5428
+ moveBottom();
5429
+ break;
5430
+ case 'left':
5431
+ moveLeft();
5432
+ break;
5433
+ case 'right':
5434
+ moveRight();
5435
+ break;
5436
+ case 'topleft':
5437
+ moveTop();
5438
+ moveLeft();
5439
+ break;
5440
+ case 'topright':
5441
+ moveTop();
5442
+ moveRight();
5443
+ break;
5444
+ case 'bottomleft':
5445
+ moveBottom();
5446
+ moveLeft();
5447
+ break;
5448
+ case 'bottomright':
5449
+ moveBottom();
5450
+ moveRight();
5451
+ break;
5452
+ }
5453
+ this.setBounds({ height, width, top, left });
5454
+ }), {
5455
+ dispose: () => {
5456
+ for (const iframe of iframes) {
5457
+ iframe.style.pointerEvents = 'auto';
5458
+ }
5459
+ },
5460
+ }, addDisposableWindowListener(window, 'mouseup', () => {
5461
+ move.dispose();
5462
+ this._onDidChangeEnd.fire();
5463
+ }));
5464
+ }));
5465
+ }
5466
+ dispose() {
5467
+ this._element.remove();
5468
+ super.dispose();
5469
+ }
5470
+ }
5471
+ Overlay.MINIMUM_HEIGHT = 20;
5472
+ Overlay.MINIMUM_WIDTH = 20;
5473
+
5474
+ class DockviewFloatingGroupPanel extends CompositeDisposable {
5475
+ constructor(group, overlay) {
5476
+ super();
5477
+ this.group = group;
5478
+ this.overlay = overlay;
5479
+ this.addDisposables(overlay);
5480
+ }
5481
+ position(bounds) {
5482
+ this.overlay.setBounds(bounds);
5483
+ }
5484
+ }
5485
+
5011
5486
  class DockviewComponent extends BaseGrid {
5012
5487
  get orientation() {
5013
5488
  return this.gridview.orientation;
@@ -5048,7 +5523,8 @@ define(['exports'], (function (exports) { 'use strict';
5048
5523
  this.onDidLayoutFromJSON = this._onDidLayoutFromJSON.event;
5049
5524
  this._onDidActivePanelChange = new Emitter();
5050
5525
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
5051
- this.element.classList.add('dv-dockview');
5526
+ this.floatingGroups = [];
5527
+ toggleClass(this.gridview.element, 'dv-dockview', true);
5052
5528
  this.addDisposables(this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
5053
5529
  this.updateWatermark();
5054
5530
  }), exports.DockviewEvent.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => {
@@ -5078,6 +5554,11 @@ define(['exports'], (function (exports) { 'use strict';
5078
5554
  if (data.viewId !== this.id) {
5079
5555
  return false;
5080
5556
  }
5557
+ if (position === 'center') {
5558
+ // center drop target is only allowed if there are no panels in the grid
5559
+ // floating panels are allowed
5560
+ return this.gridview.length === 0;
5561
+ }
5081
5562
  return true;
5082
5563
  }
5083
5564
  if (this.options.showDndOverlay) {
@@ -5090,7 +5571,7 @@ define(['exports'], (function (exports) { 'use strict';
5090
5571
  }
5091
5572
  return false;
5092
5573
  },
5093
- acceptedTargetZones: ['top', 'bottom', 'left', 'right'],
5574
+ acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
5094
5575
  overlayModel: {
5095
5576
  activationSize: { type: 'pixels', value: 10 },
5096
5577
  size: { type: 'pixels', value: 20 },
@@ -5108,6 +5589,75 @@ define(['exports'], (function (exports) { 'use strict';
5108
5589
  this._api = new DockviewApi(this);
5109
5590
  this.updateWatermark();
5110
5591
  }
5592
+ addFloatingGroup(item, coord, options) {
5593
+ var _a, _b;
5594
+ let group;
5595
+ if (item instanceof DockviewPanel) {
5596
+ group = this.createGroup();
5597
+ this.removePanel(item, {
5598
+ removeEmptyGroup: true,
5599
+ skipDispose: true,
5600
+ });
5601
+ group.model.openPanel(item);
5602
+ }
5603
+ else {
5604
+ group = item;
5605
+ const skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' &&
5606
+ options.skipRemoveGroup;
5607
+ if (!skip) {
5608
+ this.doRemoveGroup(item, { skipDispose: true });
5609
+ }
5610
+ }
5611
+ group.model.isFloating = true;
5612
+ const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number' ? Math.max(coord.x, 0) : 100;
5613
+ const overlayTop = typeof (coord === null || coord === void 0 ? void 0 : coord.y) === 'number' ? Math.max(coord.y, 0) : 100;
5614
+ const overlay = new Overlay({
5615
+ container: this.gridview.element,
5616
+ content: group.element,
5617
+ height: (_a = coord === null || coord === void 0 ? void 0 : coord.height) !== null && _a !== void 0 ? _a : 300,
5618
+ width: (_b = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _b !== void 0 ? _b : 300,
5619
+ left: overlayLeft,
5620
+ top: overlayTop,
5621
+ minimumInViewportWidth: 100,
5622
+ minimumInViewportHeight: 100,
5623
+ });
5624
+ const el = group.element.querySelector('.void-container');
5625
+ if (!el) {
5626
+ throw new Error('failed to find drag handle');
5627
+ }
5628
+ overlay.setupDrag(el, {
5629
+ inDragMode: typeof (options === null || options === void 0 ? void 0 : options.inDragMode) === 'boolean'
5630
+ ? options.inDragMode
5631
+ : false,
5632
+ });
5633
+ const floatingGroupPanel = new DockviewFloatingGroupPanel(group, overlay);
5634
+ const disposable = watchElementResize(group.element, (entry) => {
5635
+ const { width, height } = entry.contentRect;
5636
+ group.layout(width, height); // let the group know it's size is changing so it can fire events to the panel
5637
+ });
5638
+ floatingGroupPanel.addDisposables(overlay.onDidChange(() => {
5639
+ // this is either a resize or a move
5640
+ // to inform the panels .layout(...) the group with it's current size
5641
+ // don't care about resize since the above watcher handles that
5642
+ group.layout(group.height, group.width);
5643
+ }), overlay.onDidChangeEnd(() => {
5644
+ this._bufferOnDidLayoutChange.fire();
5645
+ }), group.onDidChange((event) => {
5646
+ overlay.setBounds({
5647
+ height: event === null || event === void 0 ? void 0 : event.height,
5648
+ width: event === null || event === void 0 ? void 0 : event.width,
5649
+ });
5650
+ }), {
5651
+ dispose: () => {
5652
+ disposable.dispose();
5653
+ group.model.isFloating = false;
5654
+ remove(this.floatingGroups, floatingGroupPanel);
5655
+ this.updateWatermark();
5656
+ },
5657
+ });
5658
+ this.floatingGroups.push(floatingGroupPanel);
5659
+ this.updateWatermark();
5660
+ }
5111
5661
  orthogonalize(position) {
5112
5662
  switch (position) {
5113
5663
  case 'top':
@@ -5130,6 +5680,7 @@ define(['exports'], (function (exports) { 'use strict';
5130
5680
  switch (position) {
5131
5681
  case 'top':
5132
5682
  case 'left':
5683
+ case 'center':
5133
5684
  return this.createGroupAtLocation([0]); // insert into first position
5134
5685
  case 'bottom':
5135
5686
  case 'right':
@@ -5147,6 +5698,15 @@ define(['exports'], (function (exports) { 'use strict';
5147
5698
  }
5148
5699
  this.layout(this.gridview.width, this.gridview.height, true);
5149
5700
  }
5701
+ layout(width, height, forceResize) {
5702
+ super.layout(width, height, forceResize);
5703
+ if (this.floatingGroups) {
5704
+ for (const floating of this.floatingGroups) {
5705
+ // ensure floting groups stay within visible boundaries
5706
+ floating.overlay.setBounds();
5707
+ }
5708
+ }
5709
+ }
5150
5710
  focus() {
5151
5711
  var _a;
5152
5712
  (_a = this.activeGroup) === null || _a === void 0 ? void 0 : _a.focus();
@@ -5209,51 +5769,81 @@ define(['exports'], (function (exports) { 'use strict';
5209
5769
  collection[panel.id] = panel.toJSON();
5210
5770
  return collection;
5211
5771
  }, {});
5212
- return {
5772
+ const floats = this.floatingGroups.map((floatingGroup) => {
5773
+ return {
5774
+ data: floatingGroup.group.toJSON(),
5775
+ position: floatingGroup.overlay.toJSON(),
5776
+ };
5777
+ });
5778
+ const result = {
5213
5779
  grid: data,
5214
5780
  panels,
5215
5781
  activeGroup: (_a = this.activeGroup) === null || _a === void 0 ? void 0 : _a.id,
5216
5782
  };
5783
+ if (floats.length > 0) {
5784
+ result.floatingGroups = floats;
5785
+ }
5786
+ return result;
5217
5787
  }
5218
5788
  fromJSON(data) {
5789
+ var _a;
5219
5790
  this.clear();
5220
5791
  const { grid, panels, activeGroup } = data;
5221
5792
  if (grid.root.type !== 'branch' || !Array.isArray(grid.root.data)) {
5222
5793
  throw new Error('root must be of type branch');
5223
5794
  }
5795
+ // take note of the existing dimensions
5796
+ const width = this.width;
5797
+ const height = this.height;
5798
+ const createGroupFromSerializedState = (data) => {
5799
+ const { id, locked, hideHeader, views, activeView } = data;
5800
+ const group = this.createGroup({
5801
+ id,
5802
+ locked: !!locked,
5803
+ hideHeader: !!hideHeader,
5804
+ });
5805
+ this._onDidAddGroup.fire(group);
5806
+ for (const child of views) {
5807
+ const panel = this._deserializer.fromJSON(panels[child], group);
5808
+ const isActive = typeof activeView === 'string' && activeView === panel.id;
5809
+ group.model.openPanel(panel, {
5810
+ skipSetPanelActive: !isActive,
5811
+ skipSetGroupActive: true,
5812
+ });
5813
+ }
5814
+ if (!group.activePanel && group.panels.length > 0) {
5815
+ group.model.openPanel(group.panels[group.panels.length - 1], {
5816
+ skipSetGroupActive: true,
5817
+ });
5818
+ }
5819
+ return group;
5820
+ };
5224
5821
  this.gridview.deserialize(grid, {
5225
5822
  fromJSON: (node) => {
5226
- const { id, locked, hideHeader, views, activeView } = node.data;
5227
- const group = this.createGroup({
5228
- id,
5229
- locked: !!locked,
5230
- hideHeader: !!hideHeader,
5231
- });
5232
- this._onDidAddGroup.fire(group);
5233
- for (const child of views) {
5234
- const panel = this._deserializer.fromJSON(panels[child], group);
5235
- const isActive = typeof activeView === 'string' &&
5236
- activeView === panel.id;
5237
- group.model.openPanel(panel, {
5238
- skipSetPanelActive: !isActive,
5239
- skipSetGroupActive: true,
5240
- });
5241
- }
5242
- if (!group.activePanel && group.panels.length > 0) {
5243
- group.model.openPanel(group.panels[group.panels.length - 1], {
5244
- skipSetGroupActive: true,
5245
- });
5246
- }
5247
- return group;
5823
+ return createGroupFromSerializedState(node.data);
5248
5824
  },
5249
5825
  });
5826
+ this.layout(width, height, true);
5827
+ const serializedFloatingGroups = (_a = data.floatingGroups) !== null && _a !== void 0 ? _a : [];
5828
+ for (const serializedFloatingGroup of serializedFloatingGroups) {
5829
+ const { data, position } = serializedFloatingGroup;
5830
+ const group = createGroupFromSerializedState(data);
5831
+ this.addFloatingGroup(group, {
5832
+ x: position.left,
5833
+ y: position.top,
5834
+ height: position.height,
5835
+ width: position.width,
5836
+ }, { skipRemoveGroup: true, inDragMode: false });
5837
+ }
5838
+ for (const floatingGroup of this.floatingGroups) {
5839
+ floatingGroup.overlay.setBounds();
5840
+ }
5250
5841
  if (typeof activeGroup === 'string') {
5251
5842
  const panel = this.getPanel(activeGroup);
5252
5843
  if (panel) {
5253
5844
  this.doSetGroupActive(panel);
5254
5845
  }
5255
5846
  }
5256
- this.gridview.layout(this.width, this.height);
5257
5847
  this._onDidLayoutFromJSON.fire();
5258
5848
  }
5259
5849
  clear() {
@@ -5262,7 +5852,7 @@ define(['exports'], (function (exports) { 'use strict';
5262
5852
  const hasActivePanel = !!this.activePanel;
5263
5853
  for (const group of groups) {
5264
5854
  // remove the group will automatically remove the panels
5265
- this.removeGroup(group, true);
5855
+ this.removeGroup(group, { skipActive: true });
5266
5856
  }
5267
5857
  if (hasActiveGroup) {
5268
5858
  this.doSetGroupActive(undefined);
@@ -5284,6 +5874,9 @@ define(['exports'], (function (exports) { 'use strict';
5284
5874
  throw new Error(`panel with id ${options.id} already exists`);
5285
5875
  }
5286
5876
  let referenceGroup;
5877
+ if (options.position && options.floating) {
5878
+ throw new Error('you can only provide one of: position, floating as arguments to .addPanel(...)');
5879
+ }
5287
5880
  if (options.position) {
5288
5881
  if (isPanelOptionsWithPanel(options.position)) {
5289
5882
  const referencePanel = typeof options.position.referencePanel === 'string'
@@ -5316,7 +5909,20 @@ define(['exports'], (function (exports) { 'use strict';
5316
5909
  let panel;
5317
5910
  if (referenceGroup) {
5318
5911
  const target = toTarget(((_b = options.position) === null || _b === void 0 ? void 0 : _b.direction) || 'within');
5319
- if (target === 'center') {
5912
+ if (options.floating) {
5913
+ const group = this.createGroup();
5914
+ panel = this.createPanel(options, group);
5915
+ group.model.openPanel(panel);
5916
+ const o = typeof options.floating === 'object' &&
5917
+ options.floating !== null
5918
+ ? options.floating
5919
+ : {};
5920
+ this.addFloatingGroup(group, o, {
5921
+ inDragMode: false,
5922
+ skipRemoveGroup: true,
5923
+ });
5924
+ }
5925
+ else if (referenceGroup.api.isFloating || target === 'center') {
5320
5926
  panel = this.createPanel(options, referenceGroup);
5321
5927
  referenceGroup.model.openPanel(panel);
5322
5928
  }
@@ -5328,6 +5934,19 @@ define(['exports'], (function (exports) { 'use strict';
5328
5934
  group.model.openPanel(panel);
5329
5935
  }
5330
5936
  }
5937
+ else if (options.floating) {
5938
+ const group = this.createGroup();
5939
+ panel = this.createPanel(options, group);
5940
+ group.model.openPanel(panel);
5941
+ const o = typeof options.floating === 'object' &&
5942
+ options.floating !== null
5943
+ ? options.floating
5944
+ : {};
5945
+ this.addFloatingGroup(group, o, {
5946
+ inDragMode: false,
5947
+ skipRemoveGroup: true,
5948
+ });
5949
+ }
5331
5950
  else {
5332
5951
  const group = this.createGroupAtLocation();
5333
5952
  panel = this.createPanel(options, group);
@@ -5344,7 +5963,9 @@ define(['exports'], (function (exports) { 'use strict';
5344
5963
  throw new Error(`cannot remove panel ${panel.id}. it's missing a group.`);
5345
5964
  }
5346
5965
  group.model.removePanel(panel);
5347
- panel.dispose();
5966
+ if (!options.skipDispose) {
5967
+ panel.dispose();
5968
+ }
5348
5969
  if (group.size === 0 && options.removeEmptyGroup) {
5349
5970
  this.removeGroup(group);
5350
5971
  }
@@ -5359,7 +5980,7 @@ define(['exports'], (function (exports) { 'use strict';
5359
5980
  }
5360
5981
  updateWatermark() {
5361
5982
  var _a, _b;
5362
- if (this.groups.length === 0) {
5983
+ if (this.groups.filter((x) => !x.api.isFloating).length === 0) {
5363
5984
  if (!this.watermark) {
5364
5985
  this.watermark = this.createWatermarkComponent();
5365
5986
  this.watermark.init({
@@ -5368,7 +5989,7 @@ define(['exports'], (function (exports) { 'use strict';
5368
5989
  const watermarkContainer = document.createElement('div');
5369
5990
  watermarkContainer.className = 'dv-watermark-container';
5370
5991
  watermarkContainer.appendChild(this.watermark.element);
5371
- this.element.appendChild(watermarkContainer);
5992
+ this.gridview.element.appendChild(watermarkContainer);
5372
5993
  }
5373
5994
  }
5374
5995
  else if (this.watermark) {
@@ -5418,15 +6039,28 @@ define(['exports'], (function (exports) { 'use strict';
5418
6039
  return group;
5419
6040
  }
5420
6041
  }
5421
- removeGroup(group, skipActive = false) {
6042
+ removeGroup(group, options) {
6043
+ var _a;
5422
6044
  const panels = [...group.panels]; // reassign since group panels will mutate
5423
6045
  for (const panel of panels) {
5424
6046
  this.removePanel(panel, {
5425
6047
  removeEmptyGroup: false,
5426
- skipDispose: false,
6048
+ skipDispose: (_a = options === null || options === void 0 ? void 0 : options.skipDispose) !== null && _a !== void 0 ? _a : false,
5427
6049
  });
5428
6050
  }
5429
- super.doRemoveGroup(group, { skipActive });
6051
+ this.doRemoveGroup(group, options);
6052
+ }
6053
+ doRemoveGroup(group, options) {
6054
+ const floatingGroup = this.floatingGroups.find((_) => _.group === group);
6055
+ if (floatingGroup) {
6056
+ if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
6057
+ floatingGroup.group.dispose();
6058
+ this._groups.delete(group.id);
6059
+ }
6060
+ floatingGroup.dispose();
6061
+ return floatingGroup.group;
6062
+ }
6063
+ return super.doRemoveGroup(group, options);
5430
6064
  }
5431
6065
  moveGroupOrPanel(destinationGroup, sourceGroupId, sourceItemId, destinationTarget, destinationIndex) {
5432
6066
  var _a;
@@ -5457,25 +6091,26 @@ define(['exports'], (function (exports) { 'use strict';
5457
6091
  const targetLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
5458
6092
  if (sourceGroup && sourceGroup.size < 2) {
5459
6093
  const [targetParentLocation, to] = tail(targetLocation);
5460
- const sourceLocation = getGridLocation(sourceGroup.element);
5461
- const [sourceParentLocation, from] = tail(sourceLocation);
5462
- if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
5463
- // special case when 'swapping' two views within same grid location
5464
- // if a group has one tab - we are essentially moving the 'group'
5465
- // which is equivalent to swapping two views in this case
5466
- this.gridview.moveView(sourceParentLocation, from, to);
5467
- }
5468
- else {
5469
- // source group will become empty so delete the group
5470
- const targetGroup = this.doRemoveGroup(sourceGroup, {
5471
- skipActive: true,
5472
- skipDispose: true,
5473
- });
5474
- // after deleting the group we need to re-evaulate the ref location
5475
- const updatedReferenceLocation = getGridLocation(destinationGroup.element);
5476
- const location = getRelativeLocation(this.gridview.orientation, updatedReferenceLocation, destinationTarget);
5477
- this.doAddGroup(targetGroup, location);
6094
+ const isFloating = this.floatingGroups.find((x) => x.group === sourceGroup);
6095
+ if (!isFloating) {
6096
+ const sourceLocation = getGridLocation(sourceGroup.element);
6097
+ const [sourceParentLocation, from] = tail(sourceLocation);
6098
+ if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
6099
+ // special case when 'swapping' two views within same grid location
6100
+ // if a group has one tab - we are essentially moving the 'group'
6101
+ // which is equivalent to swapping two views in this case
6102
+ this.gridview.moveView(sourceParentLocation, from, to);
6103
+ }
5478
6104
  }
6105
+ // source group will become empty so delete the group
6106
+ const targetGroup = this.doRemoveGroup(sourceGroup, {
6107
+ skipActive: true,
6108
+ skipDispose: true,
6109
+ });
6110
+ // after deleting the group we need to re-evaulate the ref location
6111
+ const updatedReferenceLocation = getGridLocation(destinationGroup.element);
6112
+ const location = getRelativeLocation(this.gridview.orientation, updatedReferenceLocation, destinationTarget);
6113
+ this.doAddGroup(targetGroup, location);
5479
6114
  }
5480
6115
  else {
5481
6116
  const groupItem = (sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.removePanel(sourceItemId)) ||
@@ -5504,7 +6139,13 @@ define(['exports'], (function (exports) { 'use strict';
5504
6139
  }
5505
6140
  }
5506
6141
  else {
5507
- this.gridview.removeView(getGridLocation(sourceGroup.element));
6142
+ const floatingGroup = this.floatingGroups.find((x) => x.group === sourceGroup);
6143
+ if (floatingGroup) {
6144
+ floatingGroup.dispose();
6145
+ }
6146
+ else {
6147
+ this.gridview.removeView(getGridLocation(sourceGroup.element));
6148
+ }
5508
6149
  const referenceLocation = getGridLocation(referenceGroup.element);
5509
6150
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, target);
5510
6151
  this.gridview.addView(sourceGroup, exports.Sizing.Distribute, dropLocation);
@@ -5659,6 +6300,9 @@ define(['exports'], (function (exports) { 'use strict';
5659
6300
  this.clear();
5660
6301
  const { grid, activePanel } = serializedGridview;
5661
6302
  const queue = [];
6303
+ // take note of the existing dimensions
6304
+ const width = this.width;
6305
+ const height = this.height;
5662
6306
  this.gridview.deserialize(grid, {
5663
6307
  fromJSON: (node) => {
5664
6308
  const { data } = node;
@@ -5684,7 +6328,7 @@ define(['exports'], (function (exports) { 'use strict';
5684
6328
  return view;
5685
6329
  },
5686
6330
  });
5687
- this.layout(this.width, this.height, true);
6331
+ this.layout(width, height, true);
5688
6332
  queue.forEach((f) => f());
5689
6333
  if (typeof activePanel === 'string') {
5690
6334
  const panel = this.getPanel(activePanel);
@@ -5998,6 +6642,9 @@ define(['exports'], (function (exports) { 'use strict';
5998
6642
  this.clear();
5999
6643
  const { views, orientation, size, activeView } = serializedSplitview;
6000
6644
  const queue = [];
6645
+ // take note of the existing dimensions
6646
+ const width = this.width;
6647
+ const height = this.height;
6001
6648
  this.splitview = new Splitview(this.element, {
6002
6649
  orientation,
6003
6650
  proportionalLayout: this.options.proportionalLayout,
@@ -6034,7 +6681,7 @@ define(['exports'], (function (exports) { 'use strict';
6034
6681
  }),
6035
6682
  },
6036
6683
  });
6037
- this.layout(this.width, this.height);
6684
+ this.layout(width, height);
6038
6685
  queue.forEach((f) => f());
6039
6686
  if (typeof activeView === 'string') {
6040
6687
  const panel = this.getPanel(activeView);
@@ -6301,6 +6948,9 @@ define(['exports'], (function (exports) { 'use strict';
6301
6948
  this.clear();
6302
6949
  const { views, size } = serializedPaneview;
6303
6950
  const queue = [];
6951
+ // take note of the existing dimensions
6952
+ const width = this.width;
6953
+ const height = this.height;
6304
6954
  this.paneview = new Paneview(this.element, {
6305
6955
  orientation: exports.Orientation.VERTICAL,
6306
6956
  descriptor: {
@@ -6356,7 +7006,7 @@ define(['exports'], (function (exports) { 'use strict';
6356
7006
  }),
6357
7007
  },
6358
7008
  });
6359
- this.layout(this.width, this.height);
7009
+ this.layout(width, height);
6360
7010
  queue.forEach((f) => f());
6361
7011
  this._onDidLayoutfromJSON.fire();
6362
7012
  }
@@ -6542,6 +7192,6 @@ define(['exports'], (function (exports) { 'use strict';
6542
7192
  exports.orthogonal = orthogonal;
6543
7193
  exports.positionToDirection = positionToDirection;
6544
7194
  exports.toTarget = toTarget;
6545
- exports.watchElementResize = watchElementResize;
6546
7195
 
6547
7196
  }));
7197
+ //# sourceMappingURL=dockview-core.amd.noStyle.js.map