dockview 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 (50) hide show
  1. package/README.md +2 -1
  2. package/dist/cjs/dockview/dockview.d.ts +4 -2
  3. package/dist/cjs/dockview/dockview.d.ts.map +1 -1
  4. package/dist/cjs/dockview/dockview.js +23 -5
  5. package/dist/cjs/dockview/dockview.js.map +1 -1
  6. package/dist/cjs/dockview/{groupControlsRenderer.d.ts → headerActionsRenderer.d.ts} +6 -5
  7. package/dist/cjs/dockview/headerActionsRenderer.d.ts.map +1 -0
  8. package/dist/cjs/dockview/{groupControlsRenderer.js → headerActionsRenderer.js} +17 -16
  9. package/dist/cjs/dockview/{groupControlsRenderer.js.map → headerActionsRenderer.js.map} +1 -1
  10. package/dist/cjs/index.d.ts +1 -1
  11. package/dist/cjs/index.d.ts.map +1 -1
  12. package/dist/cjs/svg.d.ts +3 -3
  13. package/dist/cjs/svg.d.ts.map +1 -1
  14. package/dist/dockview.amd.js +839 -163
  15. package/dist/dockview.amd.js.map +1 -0
  16. package/dist/dockview.amd.min.js +3 -2
  17. package/dist/dockview.amd.min.js.map +1 -0
  18. package/dist/dockview.amd.min.noStyle.js +3 -2
  19. package/dist/dockview.amd.min.noStyle.js.map +1 -0
  20. package/dist/dockview.amd.noStyle.js +839 -163
  21. package/dist/dockview.amd.noStyle.js.map +1 -0
  22. package/dist/dockview.cjs.js +839 -163
  23. package/dist/dockview.cjs.js.map +1 -0
  24. package/dist/dockview.esm.js +840 -163
  25. package/dist/dockview.esm.js.map +1 -0
  26. package/dist/dockview.esm.min.js +3 -2
  27. package/dist/dockview.esm.min.js.map +1 -0
  28. package/dist/dockview.js +839 -163
  29. package/dist/dockview.js.map +1 -0
  30. package/dist/dockview.min.js +3 -2
  31. package/dist/dockview.min.js.map +1 -0
  32. package/dist/dockview.min.noStyle.js +3 -2
  33. package/dist/dockview.min.noStyle.js.map +1 -0
  34. package/dist/dockview.noStyle.js +839 -163
  35. package/dist/dockview.noStyle.js.map +1 -0
  36. package/dist/esm/dockview/dockview.d.ts +4 -2
  37. package/dist/esm/dockview/dockview.d.ts.map +1 -1
  38. package/dist/esm/dockview/dockview.js +23 -5
  39. package/dist/esm/dockview/dockview.js.map +1 -1
  40. package/dist/esm/dockview/{groupControlsRenderer.d.ts → headerActionsRenderer.d.ts} +6 -5
  41. package/dist/esm/dockview/headerActionsRenderer.d.ts.map +1 -0
  42. package/dist/esm/dockview/{groupControlsRenderer.js → headerActionsRenderer.js} +3 -2
  43. package/dist/esm/dockview/{groupControlsRenderer.js.map → headerActionsRenderer.js.map} +1 -1
  44. package/dist/esm/index.d.ts +1 -1
  45. package/dist/esm/index.d.ts.map +1 -1
  46. package/dist/esm/svg.d.ts +3 -3
  47. package/dist/esm/svg.d.ts.map +1 -1
  48. package/package.json +6 -6
  49. package/dist/cjs/dockview/groupControlsRenderer.d.ts.map +0 -1
  50. package/dist/esm/dockview/groupControlsRenderer.d.ts.map +0 -1
package/dist/dockview.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * dockview
3
- * @version 1.7.5
3
+ * @version 1.8.0
4
4
  * @link https://github.com/mathuo/dockview
5
5
  * @license MIT
6
6
  */
@@ -327,6 +327,31 @@
327
327
  }
328
328
  }
329
329
 
330
+ function createComponent(id, componentName, components = {}, frameworkComponents = {}, createFrameworkComponent, fallback) {
331
+ const Component = typeof componentName === 'string'
332
+ ? components[componentName]
333
+ : undefined;
334
+ const FrameworkComponent = typeof componentName === 'string'
335
+ ? frameworkComponents[componentName]
336
+ : undefined;
337
+ if (Component && FrameworkComponent) {
338
+ throw new Error(`Cannot create '${id}'. component '${componentName}' registered as both a component and frameworkComponent`);
339
+ }
340
+ if (FrameworkComponent) {
341
+ if (!createFrameworkComponent) {
342
+ throw new Error(`Cannot create '${id}' for framework component '${componentName}'. you must register a frameworkPanelWrapper to use framework components`);
343
+ }
344
+ return createFrameworkComponent.createComponent(id, componentName, FrameworkComponent);
345
+ }
346
+ if (!Component) {
347
+ if (fallback) {
348
+ return fallback();
349
+ }
350
+ throw new Error(`Cannot create '${id}', no component '${componentName}' provided`);
351
+ }
352
+ return new Component(id, componentName);
353
+ }
354
+
330
355
  function watchElementResize(element, cb) {
331
356
  const observer = new ResizeObserver((entires) => {
332
357
  /**
@@ -440,31 +465,16 @@
440
465
  refreshState() {
441
466
  this._refreshStateHandler();
442
467
  }
443
- }
444
-
445
- function createComponent(id, componentName, components = {}, frameworkComponents = {}, createFrameworkComponent, fallback) {
446
- const Component = typeof componentName === 'string'
447
- ? components[componentName]
448
- : undefined;
449
- const FrameworkComponent = typeof componentName === 'string'
450
- ? frameworkComponents[componentName]
451
- : undefined;
452
- if (Component && FrameworkComponent) {
453
- throw new Error(`Cannot create '${id}'. component '${componentName}' registered as both a component and frameworkComponent`);
454
- }
455
- if (FrameworkComponent) {
456
- if (!createFrameworkComponent) {
457
- throw new Error(`Cannot create '${id}' for framework component '${componentName}'. you must register a frameworkPanelWrapper to use framework components`);
458
- }
459
- return createFrameworkComponent.createComponent(id, componentName, FrameworkComponent);
460
- }
461
- if (!Component) {
462
- if (fallback) {
463
- return fallback();
464
- }
465
- throw new Error(`Cannot create '${id}', no component '${componentName}' provided`);
466
- }
467
- return new Component(id, componentName);
468
+ }
469
+ // quasi: apparently, but not really; seemingly
470
+ const QUASI_PREVENT_DEFAULT_KEY = 'dv-quasiPreventDefault';
471
+ // mark an event directly for other listeners to check
472
+ function quasiPreventDefault(event) {
473
+ event[QUASI_PREVENT_DEFAULT_KEY] = true;
474
+ }
475
+ // check if this event has been marked
476
+ function quasiDefaultPrevented(event) {
477
+ return event[QUASI_PREVENT_DEFAULT_KEY];
468
478
  }
469
479
 
470
480
  function tail(arr) {
@@ -515,6 +525,14 @@
515
525
  }
516
526
  }
517
527
  return -1;
528
+ }
529
+ function remove(array, value) {
530
+ const index = array.findIndex((t) => t === value);
531
+ if (index > -1) {
532
+ array.splice(index, 1);
533
+ return true;
534
+ }
535
+ return false;
518
536
  }
519
537
 
520
538
  const clamp = (value, min, max) => {
@@ -944,7 +962,7 @@
944
962
  //add sash
945
963
  const sash = document.createElement('div');
946
964
  sash.className = 'sash';
947
- const onStart = (event) => {
965
+ const onPointerStart = (event) => {
948
966
  for (const item of this.viewItems) {
949
967
  item.enabled = false;
950
968
  }
@@ -1003,11 +1021,10 @@
1003
1021
  size: snappedViewItem.size,
1004
1022
  };
1005
1023
  }
1006
- //
1007
- const mousemove = (mousemoveEvent) => {
1024
+ const onPointerMove = (event) => {
1008
1025
  const current = this._orientation === exports.Orientation.HORIZONTAL
1009
- ? mousemoveEvent.clientX
1010
- : mousemoveEvent.clientY;
1026
+ ? event.clientX
1027
+ : event.clientY;
1011
1028
  const delta = current - start;
1012
1029
  this.resize(sashIndex, delta, sizes, undefined, undefined, minDelta, maxDelta, snapBefore, snapAfter);
1013
1030
  this.distributeEmptySpace();
@@ -1021,18 +1038,20 @@
1021
1038
  iframe.style.pointerEvents = 'auto';
1022
1039
  }
1023
1040
  this.saveProportions();
1024
- document.removeEventListener('mousemove', mousemove);
1025
- document.removeEventListener('mouseup', end);
1041
+ document.removeEventListener('pointermove', onPointerMove);
1042
+ document.removeEventListener('pointerup', end);
1043
+ document.removeEventListener('pointercancel', end);
1026
1044
  this._onDidSashEnd.fire(undefined);
1027
1045
  };
1028
- document.addEventListener('mousemove', mousemove);
1029
- document.addEventListener('mouseup', end);
1046
+ document.addEventListener('pointermove', onPointerMove);
1047
+ document.addEventListener('pointerup', end);
1048
+ document.addEventListener('pointercancel', end);
1030
1049
  };
1031
- sash.addEventListener('mousedown', onStart);
1050
+ sash.addEventListener('pointerdown', onPointerStart);
1032
1051
  const sashItem = {
1033
1052
  container: sash,
1034
1053
  disposable: () => {
1035
- sash.removeEventListener('mousedown', onStart);
1054
+ sash.removeEventListener('pointerdown', onPointerStart);
1036
1055
  this.sashContainer.removeChild(sash);
1037
1056
  },
1038
1057
  };
@@ -1656,7 +1675,7 @@
1656
1675
  : true,
1657
1676
  };
1658
1677
  }),
1659
- size: this.size,
1678
+ size: this.orthogonalSize,
1660
1679
  };
1661
1680
  this.children = childDescriptors.map((c) => c.node);
1662
1681
  this.splitview = new Splitview(this.element, {
@@ -1719,7 +1738,7 @@
1719
1738
  layout(size, orthogonalSize) {
1720
1739
  this._size = orthogonalSize;
1721
1740
  this._orthogonalSize = size;
1722
- this.splitview.layout(this.size, this.orthogonalSize);
1741
+ this.splitview.layout(orthogonalSize, size);
1723
1742
  }
1724
1743
  addChild(node, size, index, skipLayout) {
1725
1744
  if (index < 0 || index > this.children.length) {
@@ -1944,9 +1963,9 @@
1944
1963
  this._deserialize(json.root, orientation, deserializer, height);
1945
1964
  }
1946
1965
  _deserialize(root, orientation, deserializer, orthogonalSize) {
1947
- this.root = this._deserializeNode(root, orientation, deserializer, orthogonalSize, true);
1966
+ this.root = this._deserializeNode(root, orientation, deserializer, orthogonalSize);
1948
1967
  }
1949
- _deserializeNode(node, orientation, deserializer, orthogonalSize, isRoot = false) {
1968
+ _deserializeNode(node, orientation, deserializer, orthogonalSize) {
1950
1969
  let result;
1951
1970
  if (node.type === 'branch') {
1952
1971
  const serializedChildren = node.data;
@@ -1956,9 +1975,9 @@
1956
1975
  visible: serializedChild.visible,
1957
1976
  };
1958
1977
  });
1959
- // HORIZONTAL => height=orthogonalsize width=size
1960
- // VERTICAL => height=size width=orthogonalsize
1961
- result = new BranchNode(orientation, this.proportionalLayout, this.styles, isRoot ? orthogonalSize : node.size, isRoot ? node.size : orthogonalSize, children);
1978
+ result = new BranchNode(orientation, this.proportionalLayout, this.styles, node.size, // <- orthogonal size - flips at each depth
1979
+ orthogonalSize, // <- size - flips at each depth
1980
+ children);
1962
1981
  }
1963
1982
  else {
1964
1983
  result = new LeafNode(deserializer.fromJSON(node), orientation, orthogonalSize, node.size);
@@ -1991,7 +2010,8 @@
1991
2010
  const oldRoot = this.root;
1992
2011
  oldRoot.element.remove();
1993
2012
  this._root = new BranchNode(orthogonal(oldRoot.orientation), this.proportionalLayout, this.styles, this.root.orthogonalSize, this.root.size);
1994
- if (oldRoot.children.length === 1) {
2013
+ if (oldRoot.children.length === 0) ;
2014
+ else if (oldRoot.children.length === 1) {
1995
2015
  // can remove one level of redundant branching if there is only a single child
1996
2016
  const childReference = oldRoot.children[0];
1997
2017
  const child = oldRoot.removeChild(0); // remove to prevent disposal when disposing of unwanted root
@@ -2125,52 +2145,70 @@
2125
2145
  if (!(parent instanceof BranchNode)) {
2126
2146
  throw new Error('Invalid location');
2127
2147
  }
2128
- const node = parent.children[index];
2129
- if (!(node instanceof LeafNode)) {
2148
+ const nodeToRemove = parent.children[index];
2149
+ if (!(nodeToRemove instanceof LeafNode)) {
2130
2150
  throw new Error('Invalid location');
2131
2151
  }
2132
2152
  parent.removeChild(index, sizing);
2133
- if (parent.children.length === 0) {
2134
- return node.view;
2135
- }
2136
- if (parent.children.length > 1) {
2137
- return node.view;
2138
- }
2153
+ nodeToRemove.dispose();
2154
+ if (parent.children.length !== 1) {
2155
+ return nodeToRemove.view;
2156
+ }
2157
+ // if the parent has only one child and we know the parent is a BranchNode we can make the tree
2158
+ // more efficiently spaced by replacing the parent BranchNode with the child.
2159
+ // if that child is a LeafNode then we simply replace the BranchNode with the child otherwise if the child
2160
+ // is a BranchNode too we should spread it's children into the grandparent.
2161
+ // refer to the remaining child as the sibling
2139
2162
  const sibling = parent.children[0];
2140
2163
  if (pathToParent.length === 0) {
2141
- // parent is root
2164
+ // if the parent is root
2142
2165
  if (sibling instanceof LeafNode) {
2143
- return node.view;
2166
+ // if the sibling is a leaf node no action is required
2167
+ return nodeToRemove.view;
2144
2168
  }
2145
- // we must promote sibling to be the new root
2169
+ // otherwise the sibling is a branch node. since the parent is the root and the root has only one child
2170
+ // which is a branch node we can just set this branch node to be the new root node
2171
+ // for good housekeeping we'll removing the sibling from it's existing tree
2146
2172
  parent.removeChild(0, sizing);
2173
+ // and set that sibling node to be root
2147
2174
  this.root = sibling;
2148
- return node.view;
2175
+ return nodeToRemove.view;
2149
2176
  }
2177
+ // otherwise the parent is apart of a large sub-tree
2150
2178
  const [grandParent, ..._] = [...pathToParent].reverse();
2151
2179
  const [parentIndex, ...__] = [...rest].reverse();
2152
2180
  const isSiblingVisible = parent.isChildVisible(0);
2181
+ // either way we need to remove the sibling from it's existing tree
2153
2182
  parent.removeChild(0, sizing);
2183
+ // note the sizes of all of the grandparents children
2154
2184
  const sizes = grandParent.children.map((_size, i) => grandParent.getChildSize(i));
2155
- grandParent.removeChild(parentIndex, sizing);
2185
+ // remove the parent from the grandparent since we are moving the sibling to take the parents place
2186
+ // this parent is no longer used and can be disposed of
2187
+ grandParent.removeChild(parentIndex, sizing).dispose();
2156
2188
  if (sibling instanceof BranchNode) {
2189
+ // replace the parent with the siblings children
2157
2190
  sizes.splice(parentIndex, 1, ...sibling.children.map((c) => c.size));
2191
+ // and add those siblings to the grandparent
2158
2192
  for (let i = 0; i < sibling.children.length; i++) {
2159
2193
  const child = sibling.children[i];
2160
2194
  grandParent.addChild(child, child.size, parentIndex + i);
2161
2195
  }
2162
2196
  }
2163
2197
  else {
2198
+ // otherwise create a new leaf node and add that to the grandparent
2164
2199
  const newSibling = new LeafNode(sibling.view, orthogonal(sibling.orientation), sibling.size);
2165
2200
  const siblingSizing = isSiblingVisible
2166
2201
  ? sibling.orthogonalSize
2167
2202
  : exports.Sizing.Invisible(sibling.orthogonalSize);
2168
2203
  grandParent.addChild(newSibling, siblingSizing, parentIndex);
2169
2204
  }
2205
+ // the containing node of the sibling is no longer required and can be disposed of
2206
+ sibling.dispose();
2207
+ // resize everything
2170
2208
  for (let i = 0; i < sizes.length; i++) {
2171
2209
  grandParent.resizeChild(i, sizes[i]);
2172
2210
  }
2173
- return node.view;
2211
+ return nodeToRemove.view;
2174
2212
  }
2175
2213
  layout(width, height) {
2176
2214
  const [size, orthogonalSize] = this.root.orientation === exports.Orientation.HORIZONTAL
@@ -2489,6 +2527,9 @@
2489
2527
  addPanel(options) {
2490
2528
  return this.component.addPanel(options);
2491
2529
  }
2530
+ removePanel(panel) {
2531
+ this.component.removePanel(panel);
2532
+ }
2492
2533
  addGroup(options) {
2493
2534
  return this.component.addGroup(options);
2494
2535
  }
@@ -2507,6 +2548,9 @@
2507
2548
  getGroup(id) {
2508
2549
  return this.component.getPanel(id);
2509
2550
  }
2551
+ addFloatingGroup(item, coord) {
2552
+ return this.component.addFloatingGroup(item, coord);
2553
+ }
2510
2554
  fromJSON(data) {
2511
2555
  this.component.fromJSON(data);
2512
2556
  }
@@ -2599,10 +2643,14 @@
2599
2643
  this._onDrop = new Emitter();
2600
2644
  this.onDrop = this._onDrop.event;
2601
2645
  // use a set to take advantage of #<set>.has
2602
- const acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
2646
+ this._acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
2603
2647
  this.addDisposables(this._onDrop, new DragAndDropObserver(this.element, {
2604
2648
  onDragEnter: () => undefined,
2605
2649
  onDragOver: (e) => {
2650
+ if (this._acceptedTargetZonesSet.size === 0) {
2651
+ this.removeDropTarget();
2652
+ return;
2653
+ }
2606
2654
  const width = this.element.clientWidth;
2607
2655
  const height = this.element.clientHeight;
2608
2656
  if (width === 0 || height === 0) {
@@ -2611,20 +2659,28 @@
2611
2659
  const rect = e.currentTarget.getBoundingClientRect();
2612
2660
  const x = e.clientX - rect.left;
2613
2661
  const y = e.clientY - rect.top;
2614
- const quadrant = this.calculateQuadrant(acceptedTargetZonesSet, x, y, width, height);
2615
- if (quadrant === null) {
2662
+ const quadrant = this.calculateQuadrant(this._acceptedTargetZonesSet, x, y, width, height);
2663
+ /**
2664
+ * If the event has already been used by another DropTarget instance
2665
+ * then don't show a second drop target, only one target should be
2666
+ * active at any one time
2667
+ */
2668
+ if (this.isAlreadyUsed(e) || quadrant === null) {
2616
2669
  // no drop target should be displayed
2617
2670
  this.removeDropTarget();
2618
2671
  return;
2619
2672
  }
2620
2673
  if (typeof this.options.canDisplayOverlay === 'boolean') {
2621
2674
  if (!this.options.canDisplayOverlay) {
2675
+ this.removeDropTarget();
2622
2676
  return;
2623
2677
  }
2624
2678
  }
2625
2679
  else if (!this.options.canDisplayOverlay(e, quadrant)) {
2680
+ this.removeDropTarget();
2626
2681
  return;
2627
2682
  }
2683
+ this.markAsUsed(e);
2628
2684
  if (!this.targetElement) {
2629
2685
  this.targetElement = document.createElement('div');
2630
2686
  this.targetElement.className = 'drop-target-dropzone';
@@ -2635,12 +2691,6 @@
2635
2691
  this.element.classList.add('drop-target');
2636
2692
  this.element.append(this.targetElement);
2637
2693
  }
2638
- if (this.options.acceptedTargetZones.length === 0) {
2639
- return;
2640
- }
2641
- if (!this.targetElement || !this.overlayElement) {
2642
- return;
2643
- }
2644
2694
  this.toggleClasses(quadrant, width, height);
2645
2695
  this.setState(quadrant);
2646
2696
  },
@@ -2663,10 +2713,26 @@
2663
2713
  },
2664
2714
  }));
2665
2715
  }
2716
+ setTargetZones(acceptedTargetZones) {
2717
+ this._acceptedTargetZonesSet = new Set(acceptedTargetZones);
2718
+ }
2666
2719
  dispose() {
2667
2720
  this.removeDropTarget();
2668
2721
  super.dispose();
2669
2722
  }
2723
+ /**
2724
+ * Add a property to the event object for other potential listeners to check
2725
+ */
2726
+ markAsUsed(event) {
2727
+ event[Droptarget.USED_EVENT_ID] = true;
2728
+ }
2729
+ /**
2730
+ * Check is the event has already been used by another instance od DropTarget
2731
+ */
2732
+ isAlreadyUsed(event) {
2733
+ const value = event[Droptarget.USED_EVENT_ID];
2734
+ return typeof value === 'boolean' && value;
2735
+ }
2670
2736
  toggleClasses(quadrant, width, height) {
2671
2737
  var _a, _b, _c, _d;
2672
2738
  if (!this.overlayElement) {
@@ -2761,6 +2827,7 @@
2761
2827
  }
2762
2828
  }
2763
2829
  }
2830
+ Droptarget.USED_EVENT_ID = '__dockview_droptarget_event_is_used__';
2764
2831
  function calculateQuadrantAsPercentage(overlayType, x, y, width, height, threshold) {
2765
2832
  const xp = (100 * x) / width;
2766
2833
  const yp = (100 * y) / height;
@@ -2890,8 +2957,15 @@
2890
2957
  this.addDisposables(this._onDragStart, this.dataDisposable, this.pointerEventsDisposable);
2891
2958
  this.configure();
2892
2959
  }
2960
+ isCancelled(_event) {
2961
+ return false;
2962
+ }
2893
2963
  configure() {
2894
2964
  this.addDisposables(this._onDragStart, addDisposableListener(this.el, 'dragstart', (event) => {
2965
+ if (this.isCancelled(event)) {
2966
+ event.preventDefault();
2967
+ return;
2968
+ }
2895
2969
  const iframes = [
2896
2970
  ...getElementsByTagName('iframe'),
2897
2971
  ...getElementsByTagName('webview'),
@@ -2965,13 +3039,6 @@
2965
3039
  if (event.defaultPrevented) {
2966
3040
  return;
2967
3041
  }
2968
- /**
2969
- * TODO: alternative to stopPropagation
2970
- *
2971
- * I need to stop the event propagation here since otherwise it'll be intercepted by event handlers
2972
- * on the tabs-container. I cannot use event.preventDefault() since I need the on DragStart event to occur
2973
- */
2974
- event.stopPropagation();
2975
3042
  this._onChanged.fire(event);
2976
3043
  }));
2977
3044
  this.droptarget = new Droptarget(this._element, {
@@ -3029,6 +3096,22 @@
3029
3096
  this.accessorId = accessorId;
3030
3097
  this.group = group;
3031
3098
  this.panelTransfer = LocalSelectionTransfer.getInstance();
3099
+ this.addDisposables(addDisposableListener(element, 'mousedown', (e) => {
3100
+ if (e.shiftKey) {
3101
+ /**
3102
+ * You cannot call e.preventDefault() because that will prevent drag events from firing
3103
+ * but we also need to stop any group overlay drag events from occuring
3104
+ * Use a custom event marker that can be checked by the overlay drag events
3105
+ */
3106
+ quasiPreventDefault(e);
3107
+ }
3108
+ }, true));
3109
+ }
3110
+ isCancelled(_event) {
3111
+ if (this.group.api.isFloating && !_event.shiftKey) {
3112
+ return true;
3113
+ }
3114
+ return false;
3032
3115
  }
3033
3116
  getData(dataTransfer) {
3034
3117
  this.panelTransfer.setData([new PanelTransfer(this.accessorId, this.group.id, null)], PanelTransfer.prototype);
@@ -3119,17 +3202,30 @@
3119
3202
  hide() {
3120
3203
  this._element.style.display = 'none';
3121
3204
  }
3122
- setActionElement(element) {
3123
- if (this.actions === element) {
3205
+ setRightActionsElement(element) {
3206
+ if (this.rightActions === element) {
3207
+ return;
3208
+ }
3209
+ if (this.rightActions) {
3210
+ this.rightActions.remove();
3211
+ this.rightActions = undefined;
3212
+ }
3213
+ if (element) {
3214
+ this.rightActionsContainer.appendChild(element);
3215
+ this.rightActions = element;
3216
+ }
3217
+ }
3218
+ setLeftActionsElement(element) {
3219
+ if (this.leftActions === element) {
3124
3220
  return;
3125
3221
  }
3126
- if (this.actions) {
3127
- this.actions.remove();
3128
- this.actions = undefined;
3222
+ if (this.leftActions) {
3223
+ this.leftActions.remove();
3224
+ this.leftActions = undefined;
3129
3225
  }
3130
3226
  if (element) {
3131
- this.actionContainer.appendChild(element);
3132
- this.actions = element;
3227
+ this.leftActionsContainer.appendChild(element);
3228
+ this.leftActions = element;
3133
3229
  }
3134
3230
  }
3135
3231
  get element() {
@@ -3164,19 +3260,35 @@
3164
3260
  toggleClass(this._element, 'dv-single-tab', this.size === 1);
3165
3261
  }
3166
3262
  }));
3167
- this.actionContainer = document.createElement('div');
3168
- this.actionContainer.className = 'action-container';
3263
+ this.rightActionsContainer = document.createElement('div');
3264
+ this.rightActionsContainer.className = 'right-actions-container';
3265
+ this.leftActionsContainer = document.createElement('div');
3266
+ this.leftActionsContainer.className = 'left-actions-container';
3169
3267
  this.tabContainer = document.createElement('div');
3170
3268
  this.tabContainer.className = 'tabs-container';
3171
3269
  this.voidContainer = new VoidContainer(this.accessor, this.group);
3172
3270
  this._element.appendChild(this.tabContainer);
3271
+ this._element.appendChild(this.leftActionsContainer);
3173
3272
  this._element.appendChild(this.voidContainer.element);
3174
- this._element.appendChild(this.actionContainer);
3273
+ this._element.appendChild(this.rightActionsContainer);
3175
3274
  this.addDisposables(this.voidContainer, this.voidContainer.onDrop((event) => {
3176
3275
  this._onDrop.fire({
3177
3276
  event: event.nativeEvent,
3178
3277
  index: this.tabs.length,
3179
3278
  });
3279
+ }), addDisposableListener(this.voidContainer.element, 'mousedown', (event) => {
3280
+ const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3281
+ if (isFloatingGroupsEnabled &&
3282
+ event.shiftKey &&
3283
+ !this.group.api.isFloating) {
3284
+ event.preventDefault();
3285
+ const { top, left } = this.element.getBoundingClientRect();
3286
+ const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
3287
+ this.accessor.addFloatingGroup(this.group, {
3288
+ x: left - rootLeft + 20,
3289
+ y: top - rootTop + 20,
3290
+ }, { inDragMode: true });
3291
+ }
3180
3292
  }), addDisposableListener(this.tabContainer, 'mousedown', (event) => {
3181
3293
  if (event.defaultPrevented) {
3182
3294
  return;
@@ -3230,6 +3342,21 @@
3230
3342
  tabToAdd.setContent(panel.view.tab);
3231
3343
  const disposable = CompositeDisposable.from(tabToAdd.onChanged((event) => {
3232
3344
  var _a;
3345
+ const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3346
+ const isFloatingWithOnePanel = this.group.api.isFloating && this.size === 1;
3347
+ if (isFloatingGroupsEnabled &&
3348
+ !isFloatingWithOnePanel &&
3349
+ event.shiftKey) {
3350
+ event.preventDefault();
3351
+ const panel = this.accessor.getGroupPanel(tabToAdd.panelId);
3352
+ const { top, left } = tabToAdd.element.getBoundingClientRect();
3353
+ const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
3354
+ this.accessor.addFloatingGroup(panel, {
3355
+ x: left - rootLeft,
3356
+ y: top - rootTop,
3357
+ }, { inDragMode: true });
3358
+ return;
3359
+ }
3233
3360
  const alreadyFocused = panel.id === ((_a = this.group.model.activePanel) === null || _a === void 0 ? void 0 : _a.id) &&
3234
3361
  this.group.model.isContentFocused;
3235
3362
  const isLeftClick = event.button === 0;
@@ -3299,6 +3426,17 @@
3299
3426
  }
3300
3427
  return isAncestor(document.activeElement, this.contentContainer.element);
3301
3428
  }
3429
+ get isFloating() {
3430
+ return this._isFloating;
3431
+ }
3432
+ set isFloating(value) {
3433
+ this._isFloating = value;
3434
+ this.dropTarget.setTargetZones(value ? ['center'] : ['top', 'bottom', 'left', 'right', 'center']);
3435
+ toggleClass(this.container, 'dv-groupview-floating', value);
3436
+ this.groupPanel.api._onDidFloatingStateChange.fire({
3437
+ isFloating: this.isFloating,
3438
+ });
3439
+ }
3302
3440
  constructor(container, accessor, id, options, groupPanel) {
3303
3441
  super();
3304
3442
  this.container = container;
@@ -3308,6 +3446,7 @@
3308
3446
  this.groupPanel = groupPanel;
3309
3447
  this._isGroupActive = false;
3310
3448
  this._locked = false;
3449
+ this._isFloating = false;
3311
3450
  this.mostRecentlyUsed = [];
3312
3451
  this._onDidChange = new Emitter();
3313
3452
  this.onDidChange = this._onDidChange.event;
@@ -3324,7 +3463,7 @@
3324
3463
  this.onDidRemovePanel = this._onDidRemovePanel.event;
3325
3464
  this._onDidActivePanelChange = new Emitter();
3326
3465
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
3327
- this.container.classList.add('groupview');
3466
+ toggleClass(this.container, 'groupview', true);
3328
3467
  this.tabsContainer = new TabsContainer(this.accessor, this.groupPanel);
3329
3468
  this.contentContainer = new ContentContainer();
3330
3469
  this.dropTarget = new Droptarget(this.contentContainer.element, {
@@ -3334,6 +3473,9 @@
3334
3473
  return false;
3335
3474
  }
3336
3475
  const data = getPanelData();
3476
+ if (!data && event.shiftKey && !this.isFloating) {
3477
+ return false;
3478
+ }
3337
3479
  if (data && data.viewId === this.accessor.id) {
3338
3480
  if (data.groupId === this.id) {
3339
3481
  if (position === 'center') {
@@ -3378,14 +3520,25 @@
3378
3520
  // correctly initialized
3379
3521
  this.setActive(this.isActive, true, true);
3380
3522
  this.updateContainer();
3381
- if (this.accessor.options.createGroupControlElement) {
3382
- this._control = this.accessor.options.createGroupControlElement(this.groupPanel);
3383
- this.addDisposables(this._control);
3384
- this._control.init({
3523
+ if (this.accessor.options.createRightHeaderActionsElement) {
3524
+ this._rightHeaderActions =
3525
+ this.accessor.options.createRightHeaderActionsElement(this.groupPanel);
3526
+ this.addDisposables(this._rightHeaderActions);
3527
+ this._rightHeaderActions.init({
3528
+ containerApi: new DockviewApi(this.accessor),
3529
+ api: this.groupPanel.api,
3530
+ });
3531
+ this.tabsContainer.setRightActionsElement(this._rightHeaderActions.element);
3532
+ }
3533
+ if (this.accessor.options.createLeftHeaderActionsElement) {
3534
+ this._leftHeaderActions =
3535
+ this.accessor.options.createLeftHeaderActionsElement(this.groupPanel);
3536
+ this.addDisposables(this._leftHeaderActions);
3537
+ this._leftHeaderActions.init({
3385
3538
  containerApi: new DockviewApi(this.accessor),
3386
3539
  api: this.groupPanel.api,
3387
3540
  });
3388
- this.tabsContainer.setActionElement(this._control.element);
3541
+ this.tabsContainer.setLeftActionsElement(this._leftHeaderActions.element);
3389
3542
  }
3390
3543
  }
3391
3544
  indexOf(panel) {
@@ -3518,7 +3671,7 @@
3518
3671
  return this._activePanel === panel;
3519
3672
  }
3520
3673
  updateActions(element) {
3521
- this.tabsContainer.setActionElement(element);
3674
+ this.tabsContainer.setRightActionsElement(element);
3522
3675
  }
3523
3676
  setActive(isGroupActive, skipFocus = false, force = false) {
3524
3677
  var _a, _b, _c, _d;
@@ -3690,9 +3843,10 @@
3690
3843
  }
3691
3844
  }
3692
3845
  dispose() {
3693
- var _a, _b;
3846
+ var _a, _b, _c;
3694
3847
  super.dispose();
3695
- (_b = (_a = this.watermark) === null || _a === void 0 ? void 0 : _a.dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
3848
+ (_a = this.watermark) === null || _a === void 0 ? void 0 : _a.element.remove();
3849
+ (_c = (_b = this.watermark) === null || _b === void 0 ? void 0 : _b.dispose) === null || _c === void 0 ? void 0 : _c.call(_b);
3696
3850
  for (const panel of this.panels) {
3697
3851
  panel.dispose();
3698
3852
  }
@@ -4486,8 +4640,8 @@
4486
4640
  get isActive() {
4487
4641
  return this.api.isActive;
4488
4642
  }
4489
- constructor(id, component, options) {
4490
- super(id, component, new GridviewPanelApiImpl(id));
4643
+ constructor(id, component, options, api) {
4644
+ super(id, component, api !== null && api !== void 0 ? api : new GridviewPanelApiImpl(id));
4491
4645
  this._evaluatedMinimumWidth = 0;
4492
4646
  this._evaluatedMaximumWidth = Number.MAX_SAFE_INTEGER;
4493
4647
  this._evaluatedMinimumHeight = 0;
@@ -4585,6 +4739,32 @@
4585
4739
  }
4586
4740
  }
4587
4741
 
4742
+ class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
4743
+ get isFloating() {
4744
+ if (!this._group) {
4745
+ throw new Error(`DockviewGroupPanelApiImpl not initialized`);
4746
+ }
4747
+ return this._group.model.isFloating;
4748
+ }
4749
+ constructor(id, accessor) {
4750
+ super(id);
4751
+ this.accessor = accessor;
4752
+ this._onDidFloatingStateChange = new Emitter();
4753
+ this.onDidFloatingStateChange = this._onDidFloatingStateChange.event;
4754
+ this.addDisposables(this._onDidFloatingStateChange);
4755
+ }
4756
+ moveTo(options) {
4757
+ var _a;
4758
+ if (!this._group) {
4759
+ throw new Error(`DockviewGroupPanelApiImpl not initialized`);
4760
+ }
4761
+ this.accessor.moveGroupOrPanel(options.group, this._group.id, undefined, (_a = options.position) !== null && _a !== void 0 ? _a : 'center');
4762
+ }
4763
+ initialize(group) {
4764
+ this._group = group;
4765
+ }
4766
+ }
4767
+
4588
4768
  class DockviewGroupPanel extends GridviewPanel {
4589
4769
  get panels() {
4590
4770
  return this._model.panels;
@@ -4611,7 +4791,8 @@
4611
4791
  super(id, 'groupview_default', {
4612
4792
  minimumHeight: 100,
4613
4793
  minimumWidth: 100,
4614
- });
4794
+ }, new DockviewGroupPanelApiImpl(id, accessor));
4795
+ this.api.initialize(this); // cannot use 'this' after after 'super' call
4615
4796
  this._model = new DockviewGroupPanelModel(this.element, accessor, id, options, this);
4616
4797
  }
4617
4798
  initialize() {
@@ -4629,7 +4810,6 @@
4629
4810
  return this._model;
4630
4811
  }
4631
4812
  toJSON() {
4632
- // TODO fix typing
4633
4813
  return this.model.toJSON();
4634
4814
  }
4635
4815
  }
@@ -4683,9 +4863,10 @@
4683
4863
  get group() {
4684
4864
  return this._group;
4685
4865
  }
4686
- constructor(panel, group) {
4866
+ constructor(panel, group, accessor) {
4687
4867
  super(panel.id);
4688
4868
  this.panel = panel;
4869
+ this.accessor = accessor;
4689
4870
  this._onDidTitleChange = new Emitter();
4690
4871
  this.onDidTitleChange = this._onDidTitleChange.event;
4691
4872
  this._onDidActiveGroupChange = new Emitter();
@@ -4697,6 +4878,10 @@
4697
4878
  this._group = group;
4698
4879
  this.addDisposables(this.disposable, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange);
4699
4880
  }
4881
+ moveTo(options) {
4882
+ var _a;
4883
+ this.accessor.moveGroupOrPanel(options.group, this._group.id, this.panel.id, (_a = options.position) !== null && _a !== void 0 ? _a : 'center', options.index);
4884
+ }
4700
4885
  setTitle(title) {
4701
4886
  this.panel.setTitle(title);
4702
4887
  }
@@ -4721,7 +4906,7 @@
4721
4906
  this.containerApi = containerApi;
4722
4907
  this.view = view;
4723
4908
  this._group = group;
4724
- this.api = new DockviewPanelApiImpl(this, this._group);
4909
+ this.api = new DockviewPanelApiImpl(this, this._group, accessor);
4725
4910
  this.addDisposables(this.api.onActiveChange(() => {
4726
4911
  accessor.setActivePanel(this);
4727
4912
  }), this.api.onDidSizeChange((event) => {
@@ -5062,6 +5247,296 @@
5062
5247
  }
5063
5248
  }
5064
5249
 
5250
+ const bringElementToFront = (() => {
5251
+ let previous = null;
5252
+ function pushToTop(element) {
5253
+ if (previous !== element && previous !== null) {
5254
+ toggleClass(previous, 'dv-bring-to-front', false);
5255
+ }
5256
+ toggleClass(element, 'dv-bring-to-front', true);
5257
+ previous = element;
5258
+ }
5259
+ return pushToTop;
5260
+ })();
5261
+ class Overlay extends CompositeDisposable {
5262
+ constructor(options) {
5263
+ super();
5264
+ this.options = options;
5265
+ this._element = document.createElement('div');
5266
+ this._onDidChange = new Emitter();
5267
+ this.onDidChange = this._onDidChange.event;
5268
+ this._onDidChangeEnd = new Emitter();
5269
+ this.onDidChangeEnd = this._onDidChangeEnd.event;
5270
+ this.addDisposables(this._onDidChange, this._onDidChangeEnd);
5271
+ this._element.className = 'dv-resize-container';
5272
+ this.setupResize('top');
5273
+ this.setupResize('bottom');
5274
+ this.setupResize('left');
5275
+ this.setupResize('right');
5276
+ this.setupResize('topleft');
5277
+ this.setupResize('topright');
5278
+ this.setupResize('bottomleft');
5279
+ this.setupResize('bottomright');
5280
+ this._element.appendChild(this.options.content);
5281
+ this.options.container.appendChild(this._element);
5282
+ // if input bad resize within acceptable boundaries
5283
+ this.setBounds({
5284
+ height: this.options.height,
5285
+ width: this.options.width,
5286
+ top: this.options.top,
5287
+ left: this.options.left,
5288
+ });
5289
+ }
5290
+ setBounds(bounds = {}) {
5291
+ if (typeof bounds.height === 'number') {
5292
+ this._element.style.height = `${bounds.height}px`;
5293
+ }
5294
+ if (typeof bounds.width === 'number') {
5295
+ this._element.style.width = `${bounds.width}px`;
5296
+ }
5297
+ if (typeof bounds.top === 'number') {
5298
+ this._element.style.top = `${bounds.top}px`;
5299
+ }
5300
+ if (typeof bounds.left === 'number') {
5301
+ this._element.style.left = `${bounds.left}px`;
5302
+ }
5303
+ const containerRect = this.options.container.getBoundingClientRect();
5304
+ const overlayRect = this._element.getBoundingClientRect();
5305
+ // region: ensure bounds within allowable limits
5306
+ // a minimum width of minimumViewportWidth must be inside the viewport
5307
+ const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5308
+ // a minimum height of minimumViewportHeight must be inside the viewport
5309
+ const yOffset = Math.max(0, overlayRect.height - this.options.minimumInViewportHeight);
5310
+ const left = clamp(overlayRect.left - containerRect.left, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5311
+ const top = clamp(overlayRect.top - containerRect.top, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5312
+ this._element.style.left = `${left}px`;
5313
+ this._element.style.top = `${top}px`;
5314
+ this._onDidChange.fire();
5315
+ }
5316
+ toJSON() {
5317
+ const container = this.options.container.getBoundingClientRect();
5318
+ const element = this._element.getBoundingClientRect();
5319
+ return {
5320
+ top: element.top - container.top,
5321
+ left: element.left - container.left,
5322
+ width: element.width,
5323
+ height: element.height,
5324
+ };
5325
+ }
5326
+ setupDrag(dragTarget, options = { inDragMode: false }) {
5327
+ const move = new MutableDisposable();
5328
+ const track = () => {
5329
+ let offset = null;
5330
+ const iframes = [
5331
+ ...getElementsByTagName('iframe'),
5332
+ ...getElementsByTagName('webview'),
5333
+ ];
5334
+ for (const iframe of iframes) {
5335
+ iframe.style.pointerEvents = 'none';
5336
+ }
5337
+ move.value = new CompositeDisposable({
5338
+ dispose: () => {
5339
+ for (const iframe of iframes) {
5340
+ iframe.style.pointerEvents = 'auto';
5341
+ }
5342
+ },
5343
+ }, addDisposableWindowListener(window, 'mousemove', (e) => {
5344
+ const containerRect = this.options.container.getBoundingClientRect();
5345
+ const x = e.clientX - containerRect.left;
5346
+ const y = e.clientY - containerRect.top;
5347
+ toggleClass(this._element, 'dv-resize-container-dragging', true);
5348
+ const overlayRect = this._element.getBoundingClientRect();
5349
+ if (offset === null) {
5350
+ offset = {
5351
+ x: e.clientX - overlayRect.left,
5352
+ y: e.clientY - overlayRect.top,
5353
+ };
5354
+ }
5355
+ const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5356
+ const yOffset = Math.max(0, overlayRect.height -
5357
+ this.options.minimumInViewportHeight);
5358
+ const left = clamp(x - offset.x, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5359
+ const top = clamp(y - offset.y, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5360
+ this.setBounds({ top, left });
5361
+ }), addDisposableWindowListener(window, 'mouseup', () => {
5362
+ toggleClass(this._element, 'dv-resize-container-dragging', false);
5363
+ move.dispose();
5364
+ this._onDidChangeEnd.fire();
5365
+ }));
5366
+ };
5367
+ this.addDisposables(move, addDisposableListener(dragTarget, 'mousedown', (event) => {
5368
+ if (event.defaultPrevented) {
5369
+ event.preventDefault();
5370
+ return;
5371
+ }
5372
+ // if somebody has marked this event then treat as a defaultPrevented
5373
+ // without actually calling event.preventDefault()
5374
+ if (quasiDefaultPrevented(event)) {
5375
+ return;
5376
+ }
5377
+ track();
5378
+ }), addDisposableListener(this.options.content, 'mousedown', (event) => {
5379
+ if (event.defaultPrevented) {
5380
+ return;
5381
+ }
5382
+ // if somebody has marked this event then treat as a defaultPrevented
5383
+ // without actually calling event.preventDefault()
5384
+ if (quasiDefaultPrevented(event)) {
5385
+ return;
5386
+ }
5387
+ if (event.shiftKey) {
5388
+ track();
5389
+ }
5390
+ }), addDisposableListener(this.options.content, 'mousedown', () => {
5391
+ bringElementToFront(this._element);
5392
+ }, true));
5393
+ bringElementToFront(this._element);
5394
+ if (options.inDragMode) {
5395
+ track();
5396
+ }
5397
+ }
5398
+ setupResize(direction) {
5399
+ const resizeHandleElement = document.createElement('div');
5400
+ resizeHandleElement.className = `dv-resize-handle-${direction}`;
5401
+ this._element.appendChild(resizeHandleElement);
5402
+ const move = new MutableDisposable();
5403
+ this.addDisposables(move, addDisposableListener(resizeHandleElement, 'mousedown', (e) => {
5404
+ e.preventDefault();
5405
+ let startPosition = null;
5406
+ const iframes = [
5407
+ ...getElementsByTagName('iframe'),
5408
+ ...getElementsByTagName('webview'),
5409
+ ];
5410
+ for (const iframe of iframes) {
5411
+ iframe.style.pointerEvents = 'none';
5412
+ }
5413
+ move.value = new CompositeDisposable(addDisposableWindowListener(window, 'mousemove', (e) => {
5414
+ const containerRect = this.options.container.getBoundingClientRect();
5415
+ const overlayRect = this._element.getBoundingClientRect();
5416
+ const y = e.clientY - containerRect.top;
5417
+ const x = e.clientX - containerRect.left;
5418
+ if (startPosition === null) {
5419
+ // record the initial dimensions since as all subsequence moves are relative to this
5420
+ startPosition = {
5421
+ originalY: y,
5422
+ originalHeight: overlayRect.height,
5423
+ originalX: x,
5424
+ originalWidth: overlayRect.width,
5425
+ };
5426
+ }
5427
+ let top = undefined;
5428
+ let height = undefined;
5429
+ let left = undefined;
5430
+ let width = undefined;
5431
+ const minimumInViewportHeight = this.options.minimumInViewportHeight;
5432
+ const minimumInViewportWidth = this.options.minimumInViewportWidth;
5433
+ function moveTop() {
5434
+ top = clamp(y, -Number.MAX_VALUE, startPosition.originalY +
5435
+ startPosition.originalHeight >
5436
+ containerRect.height
5437
+ ? containerRect.height -
5438
+ minimumInViewportHeight
5439
+ : Math.max(0, startPosition.originalY +
5440
+ startPosition.originalHeight -
5441
+ Overlay.MINIMUM_HEIGHT));
5442
+ height =
5443
+ startPosition.originalY +
5444
+ startPosition.originalHeight -
5445
+ top;
5446
+ }
5447
+ function moveBottom() {
5448
+ top =
5449
+ startPosition.originalY -
5450
+ startPosition.originalHeight;
5451
+ height = clamp(y - top, top < 0
5452
+ ? -top + minimumInViewportHeight
5453
+ : Overlay.MINIMUM_HEIGHT, Number.MAX_VALUE);
5454
+ }
5455
+ function moveLeft() {
5456
+ left = clamp(x, -Number.MAX_VALUE, startPosition.originalX +
5457
+ startPosition.originalWidth >
5458
+ containerRect.width
5459
+ ? containerRect.width -
5460
+ minimumInViewportWidth
5461
+ : Math.max(0, startPosition.originalX +
5462
+ startPosition.originalWidth -
5463
+ Overlay.MINIMUM_WIDTH));
5464
+ width =
5465
+ startPosition.originalX +
5466
+ startPosition.originalWidth -
5467
+ left;
5468
+ }
5469
+ function moveRight() {
5470
+ left =
5471
+ startPosition.originalX -
5472
+ startPosition.originalWidth;
5473
+ width = clamp(x - left, left < 0
5474
+ ? -left + minimumInViewportWidth
5475
+ : Overlay.MINIMUM_WIDTH, Number.MAX_VALUE);
5476
+ }
5477
+ switch (direction) {
5478
+ case 'top':
5479
+ moveTop();
5480
+ break;
5481
+ case 'bottom':
5482
+ moveBottom();
5483
+ break;
5484
+ case 'left':
5485
+ moveLeft();
5486
+ break;
5487
+ case 'right':
5488
+ moveRight();
5489
+ break;
5490
+ case 'topleft':
5491
+ moveTop();
5492
+ moveLeft();
5493
+ break;
5494
+ case 'topright':
5495
+ moveTop();
5496
+ moveRight();
5497
+ break;
5498
+ case 'bottomleft':
5499
+ moveBottom();
5500
+ moveLeft();
5501
+ break;
5502
+ case 'bottomright':
5503
+ moveBottom();
5504
+ moveRight();
5505
+ break;
5506
+ }
5507
+ this.setBounds({ height, width, top, left });
5508
+ }), {
5509
+ dispose: () => {
5510
+ for (const iframe of iframes) {
5511
+ iframe.style.pointerEvents = 'auto';
5512
+ }
5513
+ },
5514
+ }, addDisposableWindowListener(window, 'mouseup', () => {
5515
+ move.dispose();
5516
+ this._onDidChangeEnd.fire();
5517
+ }));
5518
+ }));
5519
+ }
5520
+ dispose() {
5521
+ this._element.remove();
5522
+ super.dispose();
5523
+ }
5524
+ }
5525
+ Overlay.MINIMUM_HEIGHT = 20;
5526
+ Overlay.MINIMUM_WIDTH = 20;
5527
+
5528
+ class DockviewFloatingGroupPanel extends CompositeDisposable {
5529
+ constructor(group, overlay) {
5530
+ super();
5531
+ this.group = group;
5532
+ this.overlay = overlay;
5533
+ this.addDisposables(overlay);
5534
+ }
5535
+ position(bounds) {
5536
+ this.overlay.setBounds(bounds);
5537
+ }
5538
+ }
5539
+
5065
5540
  class DockviewComponent extends BaseGrid {
5066
5541
  get orientation() {
5067
5542
  return this.gridview.orientation;
@@ -5102,7 +5577,8 @@
5102
5577
  this.onDidLayoutFromJSON = this._onDidLayoutFromJSON.event;
5103
5578
  this._onDidActivePanelChange = new Emitter();
5104
5579
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
5105
- this.element.classList.add('dv-dockview');
5580
+ this.floatingGroups = [];
5581
+ toggleClass(this.gridview.element, 'dv-dockview', true);
5106
5582
  this.addDisposables(this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
5107
5583
  this.updateWatermark();
5108
5584
  }), exports.DockviewEvent.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => {
@@ -5132,6 +5608,11 @@
5132
5608
  if (data.viewId !== this.id) {
5133
5609
  return false;
5134
5610
  }
5611
+ if (position === 'center') {
5612
+ // center drop target is only allowed if there are no panels in the grid
5613
+ // floating panels are allowed
5614
+ return this.gridview.length === 0;
5615
+ }
5135
5616
  return true;
5136
5617
  }
5137
5618
  if (this.options.showDndOverlay) {
@@ -5144,7 +5625,7 @@
5144
5625
  }
5145
5626
  return false;
5146
5627
  },
5147
- acceptedTargetZones: ['top', 'bottom', 'left', 'right'],
5628
+ acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
5148
5629
  overlayModel: {
5149
5630
  activationSize: { type: 'pixels', value: 10 },
5150
5631
  size: { type: 'pixels', value: 20 },
@@ -5162,6 +5643,75 @@
5162
5643
  this._api = new DockviewApi(this);
5163
5644
  this.updateWatermark();
5164
5645
  }
5646
+ addFloatingGroup(item, coord, options) {
5647
+ var _a, _b;
5648
+ let group;
5649
+ if (item instanceof DockviewPanel) {
5650
+ group = this.createGroup();
5651
+ this.removePanel(item, {
5652
+ removeEmptyGroup: true,
5653
+ skipDispose: true,
5654
+ });
5655
+ group.model.openPanel(item);
5656
+ }
5657
+ else {
5658
+ group = item;
5659
+ const skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' &&
5660
+ options.skipRemoveGroup;
5661
+ if (!skip) {
5662
+ this.doRemoveGroup(item, { skipDispose: true });
5663
+ }
5664
+ }
5665
+ group.model.isFloating = true;
5666
+ const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number' ? Math.max(coord.x, 0) : 100;
5667
+ const overlayTop = typeof (coord === null || coord === void 0 ? void 0 : coord.y) === 'number' ? Math.max(coord.y, 0) : 100;
5668
+ const overlay = new Overlay({
5669
+ container: this.gridview.element,
5670
+ content: group.element,
5671
+ height: (_a = coord === null || coord === void 0 ? void 0 : coord.height) !== null && _a !== void 0 ? _a : 300,
5672
+ width: (_b = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _b !== void 0 ? _b : 300,
5673
+ left: overlayLeft,
5674
+ top: overlayTop,
5675
+ minimumInViewportWidth: 100,
5676
+ minimumInViewportHeight: 100,
5677
+ });
5678
+ const el = group.element.querySelector('.void-container');
5679
+ if (!el) {
5680
+ throw new Error('failed to find drag handle');
5681
+ }
5682
+ overlay.setupDrag(el, {
5683
+ inDragMode: typeof (options === null || options === void 0 ? void 0 : options.inDragMode) === 'boolean'
5684
+ ? options.inDragMode
5685
+ : false,
5686
+ });
5687
+ const floatingGroupPanel = new DockviewFloatingGroupPanel(group, overlay);
5688
+ const disposable = watchElementResize(group.element, (entry) => {
5689
+ const { width, height } = entry.contentRect;
5690
+ group.layout(width, height); // let the group know it's size is changing so it can fire events to the panel
5691
+ });
5692
+ floatingGroupPanel.addDisposables(overlay.onDidChange(() => {
5693
+ // this is either a resize or a move
5694
+ // to inform the panels .layout(...) the group with it's current size
5695
+ // don't care about resize since the above watcher handles that
5696
+ group.layout(group.height, group.width);
5697
+ }), overlay.onDidChangeEnd(() => {
5698
+ this._bufferOnDidLayoutChange.fire();
5699
+ }), group.onDidChange((event) => {
5700
+ overlay.setBounds({
5701
+ height: event === null || event === void 0 ? void 0 : event.height,
5702
+ width: event === null || event === void 0 ? void 0 : event.width,
5703
+ });
5704
+ }), {
5705
+ dispose: () => {
5706
+ disposable.dispose();
5707
+ group.model.isFloating = false;
5708
+ remove(this.floatingGroups, floatingGroupPanel);
5709
+ this.updateWatermark();
5710
+ },
5711
+ });
5712
+ this.floatingGroups.push(floatingGroupPanel);
5713
+ this.updateWatermark();
5714
+ }
5165
5715
  orthogonalize(position) {
5166
5716
  switch (position) {
5167
5717
  case 'top':
@@ -5184,6 +5734,7 @@
5184
5734
  switch (position) {
5185
5735
  case 'top':
5186
5736
  case 'left':
5737
+ case 'center':
5187
5738
  return this.createGroupAtLocation([0]); // insert into first position
5188
5739
  case 'bottom':
5189
5740
  case 'right':
@@ -5201,6 +5752,15 @@
5201
5752
  }
5202
5753
  this.layout(this.gridview.width, this.gridview.height, true);
5203
5754
  }
5755
+ layout(width, height, forceResize) {
5756
+ super.layout(width, height, forceResize);
5757
+ if (this.floatingGroups) {
5758
+ for (const floating of this.floatingGroups) {
5759
+ // ensure floting groups stay within visible boundaries
5760
+ floating.overlay.setBounds();
5761
+ }
5762
+ }
5763
+ }
5204
5764
  focus() {
5205
5765
  var _a;
5206
5766
  (_a = this.activeGroup) === null || _a === void 0 ? void 0 : _a.focus();
@@ -5263,51 +5823,81 @@
5263
5823
  collection[panel.id] = panel.toJSON();
5264
5824
  return collection;
5265
5825
  }, {});
5266
- return {
5826
+ const floats = this.floatingGroups.map((floatingGroup) => {
5827
+ return {
5828
+ data: floatingGroup.group.toJSON(),
5829
+ position: floatingGroup.overlay.toJSON(),
5830
+ };
5831
+ });
5832
+ const result = {
5267
5833
  grid: data,
5268
5834
  panels,
5269
5835
  activeGroup: (_a = this.activeGroup) === null || _a === void 0 ? void 0 : _a.id,
5270
5836
  };
5837
+ if (floats.length > 0) {
5838
+ result.floatingGroups = floats;
5839
+ }
5840
+ return result;
5271
5841
  }
5272
5842
  fromJSON(data) {
5843
+ var _a;
5273
5844
  this.clear();
5274
5845
  const { grid, panels, activeGroup } = data;
5275
5846
  if (grid.root.type !== 'branch' || !Array.isArray(grid.root.data)) {
5276
5847
  throw new Error('root must be of type branch');
5277
5848
  }
5849
+ // take note of the existing dimensions
5850
+ const width = this.width;
5851
+ const height = this.height;
5852
+ const createGroupFromSerializedState = (data) => {
5853
+ const { id, locked, hideHeader, views, activeView } = data;
5854
+ const group = this.createGroup({
5855
+ id,
5856
+ locked: !!locked,
5857
+ hideHeader: !!hideHeader,
5858
+ });
5859
+ this._onDidAddGroup.fire(group);
5860
+ for (const child of views) {
5861
+ const panel = this._deserializer.fromJSON(panels[child], group);
5862
+ const isActive = typeof activeView === 'string' && activeView === panel.id;
5863
+ group.model.openPanel(panel, {
5864
+ skipSetPanelActive: !isActive,
5865
+ skipSetGroupActive: true,
5866
+ });
5867
+ }
5868
+ if (!group.activePanel && group.panels.length > 0) {
5869
+ group.model.openPanel(group.panels[group.panels.length - 1], {
5870
+ skipSetGroupActive: true,
5871
+ });
5872
+ }
5873
+ return group;
5874
+ };
5278
5875
  this.gridview.deserialize(grid, {
5279
5876
  fromJSON: (node) => {
5280
- const { id, locked, hideHeader, views, activeView } = node.data;
5281
- const group = this.createGroup({
5282
- id,
5283
- locked: !!locked,
5284
- hideHeader: !!hideHeader,
5285
- });
5286
- this._onDidAddGroup.fire(group);
5287
- for (const child of views) {
5288
- const panel = this._deserializer.fromJSON(panels[child], group);
5289
- const isActive = typeof activeView === 'string' &&
5290
- activeView === panel.id;
5291
- group.model.openPanel(panel, {
5292
- skipSetPanelActive: !isActive,
5293
- skipSetGroupActive: true,
5294
- });
5295
- }
5296
- if (!group.activePanel && group.panels.length > 0) {
5297
- group.model.openPanel(group.panels[group.panels.length - 1], {
5298
- skipSetGroupActive: true,
5299
- });
5300
- }
5301
- return group;
5877
+ return createGroupFromSerializedState(node.data);
5302
5878
  },
5303
5879
  });
5880
+ this.layout(width, height, true);
5881
+ const serializedFloatingGroups = (_a = data.floatingGroups) !== null && _a !== void 0 ? _a : [];
5882
+ for (const serializedFloatingGroup of serializedFloatingGroups) {
5883
+ const { data, position } = serializedFloatingGroup;
5884
+ const group = createGroupFromSerializedState(data);
5885
+ this.addFloatingGroup(group, {
5886
+ x: position.left,
5887
+ y: position.top,
5888
+ height: position.height,
5889
+ width: position.width,
5890
+ }, { skipRemoveGroup: true, inDragMode: false });
5891
+ }
5892
+ for (const floatingGroup of this.floatingGroups) {
5893
+ floatingGroup.overlay.setBounds();
5894
+ }
5304
5895
  if (typeof activeGroup === 'string') {
5305
5896
  const panel = this.getPanel(activeGroup);
5306
5897
  if (panel) {
5307
5898
  this.doSetGroupActive(panel);
5308
5899
  }
5309
5900
  }
5310
- this.gridview.layout(this.width, this.height);
5311
5901
  this._onDidLayoutFromJSON.fire();
5312
5902
  }
5313
5903
  clear() {
@@ -5316,7 +5906,7 @@
5316
5906
  const hasActivePanel = !!this.activePanel;
5317
5907
  for (const group of groups) {
5318
5908
  // remove the group will automatically remove the panels
5319
- this.removeGroup(group, true);
5909
+ this.removeGroup(group, { skipActive: true });
5320
5910
  }
5321
5911
  if (hasActiveGroup) {
5322
5912
  this.doSetGroupActive(undefined);
@@ -5338,6 +5928,9 @@
5338
5928
  throw new Error(`panel with id ${options.id} already exists`);
5339
5929
  }
5340
5930
  let referenceGroup;
5931
+ if (options.position && options.floating) {
5932
+ throw new Error('you can only provide one of: position, floating as arguments to .addPanel(...)');
5933
+ }
5341
5934
  if (options.position) {
5342
5935
  if (isPanelOptionsWithPanel(options.position)) {
5343
5936
  const referencePanel = typeof options.position.referencePanel === 'string'
@@ -5370,7 +5963,20 @@
5370
5963
  let panel;
5371
5964
  if (referenceGroup) {
5372
5965
  const target = toTarget(((_b = options.position) === null || _b === void 0 ? void 0 : _b.direction) || 'within');
5373
- if (target === 'center') {
5966
+ if (options.floating) {
5967
+ const group = this.createGroup();
5968
+ panel = this.createPanel(options, group);
5969
+ group.model.openPanel(panel);
5970
+ const o = typeof options.floating === 'object' &&
5971
+ options.floating !== null
5972
+ ? options.floating
5973
+ : {};
5974
+ this.addFloatingGroup(group, o, {
5975
+ inDragMode: false,
5976
+ skipRemoveGroup: true,
5977
+ });
5978
+ }
5979
+ else if (referenceGroup.api.isFloating || target === 'center') {
5374
5980
  panel = this.createPanel(options, referenceGroup);
5375
5981
  referenceGroup.model.openPanel(panel);
5376
5982
  }
@@ -5382,6 +5988,19 @@
5382
5988
  group.model.openPanel(panel);
5383
5989
  }
5384
5990
  }
5991
+ else if (options.floating) {
5992
+ const group = this.createGroup();
5993
+ panel = this.createPanel(options, group);
5994
+ group.model.openPanel(panel);
5995
+ const o = typeof options.floating === 'object' &&
5996
+ options.floating !== null
5997
+ ? options.floating
5998
+ : {};
5999
+ this.addFloatingGroup(group, o, {
6000
+ inDragMode: false,
6001
+ skipRemoveGroup: true,
6002
+ });
6003
+ }
5385
6004
  else {
5386
6005
  const group = this.createGroupAtLocation();
5387
6006
  panel = this.createPanel(options, group);
@@ -5398,7 +6017,9 @@
5398
6017
  throw new Error(`cannot remove panel ${panel.id}. it's missing a group.`);
5399
6018
  }
5400
6019
  group.model.removePanel(panel);
5401
- panel.dispose();
6020
+ if (!options.skipDispose) {
6021
+ panel.dispose();
6022
+ }
5402
6023
  if (group.size === 0 && options.removeEmptyGroup) {
5403
6024
  this.removeGroup(group);
5404
6025
  }
@@ -5413,7 +6034,7 @@
5413
6034
  }
5414
6035
  updateWatermark() {
5415
6036
  var _a, _b;
5416
- if (this.groups.length === 0) {
6037
+ if (this.groups.filter((x) => !x.api.isFloating).length === 0) {
5417
6038
  if (!this.watermark) {
5418
6039
  this.watermark = this.createWatermarkComponent();
5419
6040
  this.watermark.init({
@@ -5422,7 +6043,7 @@
5422
6043
  const watermarkContainer = document.createElement('div');
5423
6044
  watermarkContainer.className = 'dv-watermark-container';
5424
6045
  watermarkContainer.appendChild(this.watermark.element);
5425
- this.element.appendChild(watermarkContainer);
6046
+ this.gridview.element.appendChild(watermarkContainer);
5426
6047
  }
5427
6048
  }
5428
6049
  else if (this.watermark) {
@@ -5472,15 +6093,28 @@
5472
6093
  return group;
5473
6094
  }
5474
6095
  }
5475
- removeGroup(group, skipActive = false) {
6096
+ removeGroup(group, options) {
6097
+ var _a;
5476
6098
  const panels = [...group.panels]; // reassign since group panels will mutate
5477
6099
  for (const panel of panels) {
5478
6100
  this.removePanel(panel, {
5479
6101
  removeEmptyGroup: false,
5480
- skipDispose: false,
6102
+ skipDispose: (_a = options === null || options === void 0 ? void 0 : options.skipDispose) !== null && _a !== void 0 ? _a : false,
5481
6103
  });
5482
6104
  }
5483
- super.doRemoveGroup(group, { skipActive });
6105
+ this.doRemoveGroup(group, options);
6106
+ }
6107
+ doRemoveGroup(group, options) {
6108
+ const floatingGroup = this.floatingGroups.find((_) => _.group === group);
6109
+ if (floatingGroup) {
6110
+ if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
6111
+ floatingGroup.group.dispose();
6112
+ this._groups.delete(group.id);
6113
+ }
6114
+ floatingGroup.dispose();
6115
+ return floatingGroup.group;
6116
+ }
6117
+ return super.doRemoveGroup(group, options);
5484
6118
  }
5485
6119
  moveGroupOrPanel(destinationGroup, sourceGroupId, sourceItemId, destinationTarget, destinationIndex) {
5486
6120
  var _a;
@@ -5511,25 +6145,26 @@
5511
6145
  const targetLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
5512
6146
  if (sourceGroup && sourceGroup.size < 2) {
5513
6147
  const [targetParentLocation, to] = tail(targetLocation);
5514
- const sourceLocation = getGridLocation(sourceGroup.element);
5515
- const [sourceParentLocation, from] = tail(sourceLocation);
5516
- if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
5517
- // special case when 'swapping' two views within same grid location
5518
- // if a group has one tab - we are essentially moving the 'group'
5519
- // which is equivalent to swapping two views in this case
5520
- this.gridview.moveView(sourceParentLocation, from, to);
5521
- }
5522
- else {
5523
- // source group will become empty so delete the group
5524
- const targetGroup = this.doRemoveGroup(sourceGroup, {
5525
- skipActive: true,
5526
- skipDispose: true,
5527
- });
5528
- // after deleting the group we need to re-evaulate the ref location
5529
- const updatedReferenceLocation = getGridLocation(destinationGroup.element);
5530
- const location = getRelativeLocation(this.gridview.orientation, updatedReferenceLocation, destinationTarget);
5531
- this.doAddGroup(targetGroup, location);
6148
+ const isFloating = this.floatingGroups.find((x) => x.group === sourceGroup);
6149
+ if (!isFloating) {
6150
+ const sourceLocation = getGridLocation(sourceGroup.element);
6151
+ const [sourceParentLocation, from] = tail(sourceLocation);
6152
+ if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
6153
+ // special case when 'swapping' two views within same grid location
6154
+ // if a group has one tab - we are essentially moving the 'group'
6155
+ // which is equivalent to swapping two views in this case
6156
+ this.gridview.moveView(sourceParentLocation, from, to);
6157
+ }
5532
6158
  }
6159
+ // source group will become empty so delete the group
6160
+ const targetGroup = this.doRemoveGroup(sourceGroup, {
6161
+ skipActive: true,
6162
+ skipDispose: true,
6163
+ });
6164
+ // after deleting the group we need to re-evaulate the ref location
6165
+ const updatedReferenceLocation = getGridLocation(destinationGroup.element);
6166
+ const location = getRelativeLocation(this.gridview.orientation, updatedReferenceLocation, destinationTarget);
6167
+ this.doAddGroup(targetGroup, location);
5533
6168
  }
5534
6169
  else {
5535
6170
  const groupItem = (sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.removePanel(sourceItemId)) ||
@@ -5558,7 +6193,13 @@
5558
6193
  }
5559
6194
  }
5560
6195
  else {
5561
- this.gridview.removeView(getGridLocation(sourceGroup.element));
6196
+ const floatingGroup = this.floatingGroups.find((x) => x.group === sourceGroup);
6197
+ if (floatingGroup) {
6198
+ floatingGroup.dispose();
6199
+ }
6200
+ else {
6201
+ this.gridview.removeView(getGridLocation(sourceGroup.element));
6202
+ }
5562
6203
  const referenceLocation = getGridLocation(referenceGroup.element);
5563
6204
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, target);
5564
6205
  this.gridview.addView(sourceGroup, exports.Sizing.Distribute, dropLocation);
@@ -5713,6 +6354,9 @@
5713
6354
  this.clear();
5714
6355
  const { grid, activePanel } = serializedGridview;
5715
6356
  const queue = [];
6357
+ // take note of the existing dimensions
6358
+ const width = this.width;
6359
+ const height = this.height;
5716
6360
  this.gridview.deserialize(grid, {
5717
6361
  fromJSON: (node) => {
5718
6362
  const { data } = node;
@@ -5738,7 +6382,7 @@
5738
6382
  return view;
5739
6383
  },
5740
6384
  });
5741
- this.layout(this.width, this.height, true);
6385
+ this.layout(width, height, true);
5742
6386
  queue.forEach((f) => f());
5743
6387
  if (typeof activePanel === 'string') {
5744
6388
  const panel = this.getPanel(activePanel);
@@ -6052,6 +6696,9 @@
6052
6696
  this.clear();
6053
6697
  const { views, orientation, size, activeView } = serializedSplitview;
6054
6698
  const queue = [];
6699
+ // take note of the existing dimensions
6700
+ const width = this.width;
6701
+ const height = this.height;
6055
6702
  this.splitview = new Splitview(this.element, {
6056
6703
  orientation,
6057
6704
  proportionalLayout: this.options.proportionalLayout,
@@ -6088,7 +6735,7 @@
6088
6735
  }),
6089
6736
  },
6090
6737
  });
6091
- this.layout(this.width, this.height);
6738
+ this.layout(width, height);
6092
6739
  queue.forEach((f) => f());
6093
6740
  if (typeof activeView === 'string') {
6094
6741
  const panel = this.getPanel(activeView);
@@ -6355,6 +7002,9 @@
6355
7002
  this.clear();
6356
7003
  const { views, size } = serializedPaneview;
6357
7004
  const queue = [];
7005
+ // take note of the existing dimensions
7006
+ const width = this.width;
7007
+ const height = this.height;
6358
7008
  this.paneview = new Paneview(this.element, {
6359
7009
  orientation: exports.Orientation.VERTICAL,
6360
7010
  descriptor: {
@@ -6410,7 +7060,7 @@
6410
7060
  }),
6411
7061
  },
6412
7062
  });
6413
- this.layout(this.width, this.height);
7063
+ this.layout(width, height);
6414
7064
  queue.forEach((f) => f());
6415
7065
  this._onDidLayoutfromJSON.fire();
6416
7066
  }
@@ -6793,7 +7443,7 @@
6793
7443
  }
6794
7444
  }
6795
7445
 
6796
- class ReactGroupControlsRendererPart {
7446
+ class ReactHeaderActionsRendererPart {
6797
7447
  get element() {
6798
7448
  return this._element;
6799
7449
  }
@@ -6830,6 +7480,7 @@
6830
7480
  panels: this._group.model.panels,
6831
7481
  activePanel: this._group.model.activePanel,
6832
7482
  isGroupActive: this._group.api.isActive,
7483
+ group: this._group,
6833
7484
  });
6834
7485
  }
6835
7486
  update(event) {
@@ -6863,7 +7514,7 @@
6863
7514
  function createGroupControlElement(component, store) {
6864
7515
  return component
6865
7516
  ? (groupPanel) => {
6866
- return new ReactGroupControlsRendererPart(component, store, groupPanel);
7517
+ return new ReactHeaderActionsRendererPart(component, store, groupPanel);
6867
7518
  }
6868
7519
  : undefined;
6869
7520
  }
@@ -6920,8 +7571,10 @@
6920
7571
  ? { separatorBorder: 'transparent' }
6921
7572
  : undefined,
6922
7573
  showDndOverlay: props.showDndOverlay,
6923
- createGroupControlElement: createGroupControlElement(props.groupControlComponent, { addPortal }),
7574
+ createLeftHeaderActionsElement: createGroupControlElement(props.leftHeaderActionsComponent, { addPortal }),
7575
+ createRightHeaderActionsElement: createGroupControlElement(props.rightHeaderActionsComponent, { addPortal }),
6924
7576
  singleTabMode: props.singleTabMode,
7577
+ disableFloatingGroups: props.disableFloatingGroups,
6925
7578
  });
6926
7579
  const { clientWidth, clientHeight } = domRef.current;
6927
7580
  dockview.layout(clientWidth, clientHeight);
@@ -6980,6 +7633,14 @@
6980
7633
  frameworkTabComponents: props.tabComponents,
6981
7634
  });
6982
7635
  }, [props.tabComponents]);
7636
+ React__namespace.useEffect(() => {
7637
+ if (!dockviewRef.current) {
7638
+ return;
7639
+ }
7640
+ dockviewRef.current.updateOptions({
7641
+ disableFloatingGroups: props.disableFloatingGroups,
7642
+ });
7643
+ }, [props.disableFloatingGroups]);
6983
7644
  React__namespace.useEffect(() => {
6984
7645
  if (!dockviewRef.current) {
6985
7646
  return;
@@ -7001,9 +7662,17 @@
7001
7662
  return;
7002
7663
  }
7003
7664
  dockviewRef.current.updateOptions({
7004
- createGroupControlElement: createGroupControlElement(props.groupControlComponent, { addPortal }),
7665
+ createRightHeaderActionsElement: createGroupControlElement(props.rightHeaderActionsComponent, { addPortal }),
7666
+ });
7667
+ }, [props.rightHeaderActionsComponent]);
7668
+ React__namespace.useEffect(() => {
7669
+ if (!dockviewRef.current) {
7670
+ return;
7671
+ }
7672
+ dockviewRef.current.updateOptions({
7673
+ createLeftHeaderActionsElement: createGroupControlElement(props.leftHeaderActionsComponent, { addPortal }),
7005
7674
  });
7006
- }, [props.groupControlComponent]);
7675
+ }, [props.leftHeaderActionsComponent]);
7007
7676
  return (React__namespace.createElement("div", { className: props.className, style: { height: '100%', width: '100%' }, ref: domRef }, portals));
7008
7677
  });
7009
7678
  DockviewReact.displayName = 'DockviewComponent';
@@ -7022,6 +7691,8 @@
7022
7691
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
7023
7692
  PERFORMANCE OF THIS SOFTWARE.
7024
7693
  ***************************************************************************** */
7694
+ /* global Reflect, Promise, SuppressedError, Symbol */
7695
+
7025
7696
 
7026
7697
  function __rest(s, e) {
7027
7698
  var t = {};
@@ -7033,7 +7704,12 @@
7033
7704
  t[p[i]] = s[p[i]];
7034
7705
  }
7035
7706
  return t;
7036
- }
7707
+ }
7708
+
7709
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
7710
+ var e = new Error(message);
7711
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
7712
+ };
7037
7713
 
7038
7714
  const CloseButton = () => (React__namespace.createElement("svg", { height: "11", width: "11", viewBox: "0 0 28 28", "aria-hidden": 'false', focusable: false, className: "dockview-svg" },
7039
7715
  React__namespace.createElement("path", { d: "M2.1 27.3L0 25.2L11.55 13.65L0 2.1L2.1 0L13.65 11.55L25.2 0L27.3 2.1L15.75 13.65L27.3 25.2L25.2 27.3L13.65 15.75L2.1 27.3Z" })));
@@ -7361,6 +8037,6 @@
7361
8037
  exports.positionToDirection = positionToDirection;
7362
8038
  exports.toTarget = toTarget;
7363
8039
  exports.usePortalsLifecycle = usePortalsLifecycle;
7364
- exports.watchElementResize = watchElementResize;
7365
8040
 
7366
8041
  }));
8042
+ //# sourceMappingURL=dockview.js.map