dockview-react 3.2.0 → 4.0.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.
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * dockview-react
3
- * @version 3.2.0
3
+ * @version 4.0.0
4
4
  * @link https://github.com/mathuo/dockview
5
5
  * @license MIT
6
6
  */
@@ -335,6 +335,20 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
335
335
  }
336
336
  }
337
337
 
338
+ class OverflowObserver extends CompositeDisposable {
339
+ constructor(el) {
340
+ super();
341
+ this._onDidChange = new Emitter();
342
+ this.onDidChange = this._onDidChange.event;
343
+ this._value = null;
344
+ this.addDisposables(this._onDidChange, watchElementResize(el, (entry) => {
345
+ const hasScrollX = entry.target.scrollWidth > entry.target.clientWidth;
346
+ const hasScrollY = entry.target.scrollHeight > entry.target.clientHeight;
347
+ this._value = { hasScrollX, hasScrollY };
348
+ this._onDidChange.fire(this._value);
349
+ }));
350
+ }
351
+ }
338
352
  function watchElementResize(element, cb) {
339
353
  const observer = new ResizeObserver((entires) => {
340
354
  /**
@@ -573,6 +587,19 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
573
587
  }
574
588
  }
575
589
  }
590
+ function isChildEntirelyVisibleWithinParent(child, parent) {
591
+ //
592
+ const childPosition = getDomNodePagePosition(child);
593
+ const parentPosition = getDomNodePagePosition(parent);
594
+ if (childPosition.left < parentPosition.left) {
595
+ return false;
596
+ }
597
+ if (childPosition.left + childPosition.width >
598
+ parentPosition.left + parentPosition.width) {
599
+ return false;
600
+ }
601
+ return true;
602
+ }
576
603
 
577
604
  function tail(arr) {
578
605
  if (arr.length === 0) {
@@ -580,9 +607,6 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
580
607
  }
581
608
  return [arr.slice(0, arr.length - 1), arr[arr.length - 1]];
582
609
  }
583
- function last(arr) {
584
- return arr.length > 0 ? arr[arr.length - 1] : undefined;
585
- }
586
610
  function sequenceEquals(arr1, arr2) {
587
611
  if (arr1.length !== arr2.length) {
588
612
  return false;
@@ -848,6 +872,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
848
872
  }
849
873
  set margin(value) {
850
874
  this._margin = value;
875
+ toggleClass(this.element, 'dv-splitview-has-margin', value !== 0);
851
876
  }
852
877
  constructor(container, options) {
853
878
  var _a, _b;
@@ -3419,9 +3444,6 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3419
3444
  get totalPanels() {
3420
3445
  return this.component.totalPanels;
3421
3446
  }
3422
- get gap() {
3423
- return this.component.gap;
3424
- }
3425
3447
  /**
3426
3448
  * Invoked when the active group changes. May be undefined if no group is active.
3427
3449
  */
@@ -3652,9 +3674,6 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3652
3674
  addPopoutGroup(item, options) {
3653
3675
  return this.component.addPopoutGroup(item, options);
3654
3676
  }
3655
- setGap(gap) {
3656
- this.component.updateOptions({ gap });
3657
- }
3658
3677
  updateOptions(options) {
3659
3678
  this.component.updateOptions(options);
3660
3679
  }
@@ -3707,14 +3726,16 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3707
3726
  * For example: in react-dnd if dataTransfer.types is not set then the dragStart event will be cancelled
3708
3727
  * through .preventDefault(). Since this is applied globally to all drag events this would break dockviews
3709
3728
  * dnd logic. You can see the code at
3710
- * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
3729
+ P * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
3711
3730
  */
3712
3731
  event.dataTransfer.setData('text/plain', '');
3713
3732
  }
3714
3733
  }
3715
3734
  }), addDisposableListener(this.el, 'dragend', () => {
3716
3735
  this.pointerEventsDisposable.dispose();
3717
- this.dataDisposable.dispose();
3736
+ setTimeout(() => {
3737
+ this.dataDisposable.dispose(); // allow the data to be read by other handlers before disposing
3738
+ }, 0);
3718
3739
  }));
3719
3740
  }
3720
3741
  }
@@ -3824,6 +3845,12 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3824
3845
  const SMALL_WIDTH_BOUNDARY = 100;
3825
3846
  const SMALL_HEIGHT_BOUNDARY = 100;
3826
3847
  class Droptarget extends CompositeDisposable {
3848
+ get disabled() {
3849
+ return this._disabled;
3850
+ }
3851
+ set disabled(value) {
3852
+ this._disabled = value;
3853
+ }
3827
3854
  get state() {
3828
3855
  return this._state;
3829
3856
  }
@@ -3835,23 +3862,34 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3835
3862
  this.onDrop = this._onDrop.event;
3836
3863
  this._onWillShowOverlay = new Emitter();
3837
3864
  this.onWillShowOverlay = this._onWillShowOverlay.event;
3865
+ this._disabled = false;
3838
3866
  // use a set to take advantage of #<set>.has
3839
3867
  this._acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
3840
3868
  this.dnd = new DragAndDropObserver(this.element, {
3841
- onDragEnter: () => undefined,
3869
+ onDragEnter: () => {
3870
+ var _a, _b, _c;
3871
+ (_c = (_b = (_a = this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a)) === null || _c === void 0 ? void 0 : _c.getElements();
3872
+ },
3842
3873
  onDragOver: (e) => {
3874
+ var _a, _b, _c, _d, _e, _f, _g;
3875
+ Droptarget.ACTUAL_TARGET = this;
3876
+ const overrideTraget = (_b = (_a = this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a);
3843
3877
  if (this._acceptedTargetZonesSet.size === 0) {
3878
+ if (overrideTraget) {
3879
+ return;
3880
+ }
3844
3881
  this.removeDropTarget();
3845
3882
  return;
3846
3883
  }
3847
- const width = this.element.clientWidth;
3848
- const height = this.element.clientHeight;
3884
+ const target = (_e = (_d = (_c = this.options).getOverlayOutline) === null || _d === void 0 ? void 0 : _d.call(_c)) !== null && _e !== void 0 ? _e : this.element;
3885
+ const width = target.offsetWidth;
3886
+ const height = target.offsetHeight;
3849
3887
  if (width === 0 || height === 0) {
3850
3888
  return; // avoid div!0
3851
3889
  }
3852
3890
  const rect = e.currentTarget.getBoundingClientRect();
3853
- const x = e.clientX - rect.left;
3854
- const y = e.clientY - rect.top;
3891
+ const x = ((_f = e.clientX) !== null && _f !== void 0 ? _f : 0) - rect.left;
3892
+ const y = ((_g = e.clientY) !== null && _g !== void 0 ? _g : 0) - rect.top;
3855
3893
  const quadrant = this.calculateQuadrant(this._acceptedTargetZonesSet, x, y, width, height);
3856
3894
  /**
3857
3895
  * If the event has already been used by another DropTarget instance
@@ -3864,6 +3902,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3864
3902
  return;
3865
3903
  }
3866
3904
  if (!this.options.canDisplayOverlay(e, quadrant)) {
3905
+ if (overrideTraget) {
3906
+ return;
3907
+ }
3867
3908
  this.removeDropTarget();
3868
3909
  return;
3869
3910
  }
@@ -3881,29 +3922,57 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3881
3922
  return;
3882
3923
  }
3883
3924
  this.markAsUsed(e);
3884
- if (!this.targetElement) {
3925
+ if (overrideTraget) ;
3926
+ else if (!this.targetElement) {
3885
3927
  this.targetElement = document.createElement('div');
3886
3928
  this.targetElement.className = 'dv-drop-target-dropzone';
3887
3929
  this.overlayElement = document.createElement('div');
3888
3930
  this.overlayElement.className = 'dv-drop-target-selection';
3889
3931
  this._state = 'center';
3890
3932
  this.targetElement.appendChild(this.overlayElement);
3891
- this.element.classList.add('dv-drop-target');
3892
- this.element.append(this.targetElement);
3933
+ target.classList.add('dv-drop-target');
3934
+ target.append(this.targetElement);
3935
+ // this.overlayElement.style.opacity = '0';
3936
+ // requestAnimationFrame(() => {
3937
+ // if (this.overlayElement) {
3938
+ // this.overlayElement.style.opacity = '';
3939
+ // }
3940
+ // });
3893
3941
  }
3894
3942
  this.toggleClasses(quadrant, width, height);
3895
3943
  this._state = quadrant;
3896
3944
  },
3897
3945
  onDragLeave: () => {
3946
+ var _a, _b;
3947
+ const target = (_b = (_a = this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a);
3948
+ if (target) {
3949
+ return;
3950
+ }
3898
3951
  this.removeDropTarget();
3899
3952
  },
3900
- onDragEnd: () => {
3953
+ onDragEnd: (e) => {
3954
+ var _a, _b;
3955
+ const target = (_b = (_a = this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a);
3956
+ if (target && Droptarget.ACTUAL_TARGET === this) {
3957
+ if (this._state) {
3958
+ // only stop the propagation of the event if we are dealing with it
3959
+ // which is only when the target has state
3960
+ e.stopPropagation();
3961
+ this._onDrop.fire({
3962
+ position: this._state,
3963
+ nativeEvent: e,
3964
+ });
3965
+ }
3966
+ }
3901
3967
  this.removeDropTarget();
3968
+ target === null || target === void 0 ? void 0 : target.clear();
3902
3969
  },
3903
3970
  onDrop: (e) => {
3971
+ var _a, _b, _c;
3904
3972
  e.preventDefault();
3905
3973
  const state = this._state;
3906
3974
  this.removeDropTarget();
3975
+ (_c = (_b = (_a = this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a)) === null || _c === void 0 ? void 0 : _c.clear();
3907
3976
  if (state) {
3908
3977
  // only stop the propagation of the event if we are dealing with it
3909
3978
  // which is only when the target has state
@@ -3938,8 +4007,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3938
4007
  return typeof value === 'boolean' && value;
3939
4008
  }
3940
4009
  toggleClasses(quadrant, width, height) {
3941
- var _a, _b;
3942
- if (!this.overlayElement) {
4010
+ var _a, _b, _c, _d, _e, _f, _g;
4011
+ const target = (_b = (_a = this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a);
4012
+ if (!target && !this.overlayElement) {
3943
4013
  return;
3944
4014
  }
3945
4015
  const isSmallX = width < SMALL_WIDTH_BOUNDARY;
@@ -3953,7 +4023,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3953
4023
  const topClass = !isSmallY && isTop;
3954
4024
  const bottomClass = !isSmallY && isBottom;
3955
4025
  let size = 1;
3956
- const sizeOptions = (_b = (_a = this.options.overlayModel) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : DEFAULT_SIZE;
4026
+ const sizeOptions = (_d = (_c = this.options.overlayModel) === null || _c === void 0 ? void 0 : _c.size) !== null && _d !== void 0 ? _d : DEFAULT_SIZE;
3957
4027
  if (sizeOptions.type === 'percentage') {
3958
4028
  size = clamp(sizeOptions.value, 0, 100) / 100;
3959
4029
  }
@@ -3965,6 +4035,74 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3965
4035
  size = clamp(0, sizeOptions.value, height) / height;
3966
4036
  }
3967
4037
  }
4038
+ if (target) {
4039
+ const outlineEl = (_g = (_f = (_e = this.options).getOverlayOutline) === null || _f === void 0 ? void 0 : _f.call(_e)) !== null && _g !== void 0 ? _g : this.element;
4040
+ const elBox = outlineEl.getBoundingClientRect();
4041
+ const ta = target.getElements(undefined, outlineEl);
4042
+ const el = ta.root;
4043
+ const overlay = ta.overlay;
4044
+ const bigbox = el.getBoundingClientRect();
4045
+ const rootTop = elBox.top - bigbox.top;
4046
+ const rootLeft = elBox.left - bigbox.left;
4047
+ const box = {
4048
+ top: rootTop,
4049
+ left: rootLeft,
4050
+ width: width,
4051
+ height: height,
4052
+ };
4053
+ if (rightClass) {
4054
+ box.left = rootLeft + width * (1 - size);
4055
+ box.width = width * size;
4056
+ }
4057
+ else if (leftClass) {
4058
+ box.width = width * size;
4059
+ }
4060
+ else if (topClass) {
4061
+ box.height = height * size;
4062
+ }
4063
+ else if (bottomClass) {
4064
+ box.top = rootTop + height * (1 - size);
4065
+ box.height = height * size;
4066
+ }
4067
+ if (isSmallX && isLeft) {
4068
+ box.width = 4;
4069
+ }
4070
+ if (isSmallX && isRight) {
4071
+ box.left = rootLeft + width - 4;
4072
+ box.width = 4;
4073
+ }
4074
+ const topPx = `${Math.round(box.top)}px`;
4075
+ const leftPx = `${Math.round(box.left)}px`;
4076
+ const widthPx = `${Math.round(box.width)}px`;
4077
+ const heightPx = `${Math.round(box.height)}px`;
4078
+ if (overlay.style.top === topPx &&
4079
+ overlay.style.left === leftPx &&
4080
+ overlay.style.width === widthPx &&
4081
+ overlay.style.height === heightPx) {
4082
+ return;
4083
+ }
4084
+ overlay.style.top = topPx;
4085
+ overlay.style.left = leftPx;
4086
+ overlay.style.width = widthPx;
4087
+ overlay.style.height = heightPx;
4088
+ overlay.style.visibility = 'visible';
4089
+ overlay.className = `dv-drop-target-anchor${this.options.className ? ` ${this.options.className}` : ''}`;
4090
+ toggleClass(overlay, 'dv-drop-target-left', isLeft);
4091
+ toggleClass(overlay, 'dv-drop-target-right', isRight);
4092
+ toggleClass(overlay, 'dv-drop-target-top', isTop);
4093
+ toggleClass(overlay, 'dv-drop-target-bottom', isBottom);
4094
+ toggleClass(overlay, 'dv-drop-target-center', quadrant === 'center');
4095
+ if (ta.changed) {
4096
+ toggleClass(overlay, 'dv-drop-target-anchor-container-changed', true);
4097
+ setTimeout(() => {
4098
+ toggleClass(overlay, 'dv-drop-target-anchor-container-changed', false);
4099
+ }, 10);
4100
+ }
4101
+ return;
4102
+ }
4103
+ if (!this.overlayElement) {
4104
+ return;
4105
+ }
3968
4106
  const box = { top: '0px', left: '0px', width: '100%', height: '100%' };
3969
4107
  /**
3970
4108
  * You can also achieve the overlay placement using the transform CSS property
@@ -4021,12 +4159,13 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
4021
4159
  return calculateQuadrantAsPixels(overlayType, x, y, width, height, activationSizeOptions.value);
4022
4160
  }
4023
4161
  removeDropTarget() {
4162
+ var _a;
4024
4163
  if (this.targetElement) {
4025
4164
  this._state = undefined;
4026
- this.element.removeChild(this.targetElement);
4165
+ (_a = this.targetElement.parentElement) === null || _a === void 0 ? void 0 : _a.classList.remove('dv-drop-target');
4166
+ this.targetElement.remove();
4027
4167
  this.targetElement = undefined;
4028
4168
  this.overlayElement = undefined;
4029
- this.element.classList.remove('dv-drop-target');
4030
4169
  }
4031
4170
  }
4032
4171
  }
@@ -4611,7 +4750,15 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
4611
4750
  this._element.className = 'dv-content-container';
4612
4751
  this._element.tabIndex = -1;
4613
4752
  this.addDisposables(this._onDidFocus, this._onDidBlur);
4753
+ const target = group.dropTargetContainer;
4614
4754
  this.dropTarget = new Droptarget(this.element, {
4755
+ getOverlayOutline: () => {
4756
+ var _a;
4757
+ return ((_a = accessor.options.theme) === null || _a === void 0 ? void 0 : _a.dndPanelOverlay) === 'group'
4758
+ ? this.element.parentElement
4759
+ : null;
4760
+ },
4761
+ className: 'dv-drop-target-content',
4615
4762
  acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
4616
4763
  canDisplayOverlay: (event, position) => {
4617
4764
  if (this.group.locked === 'no-drop-target' ||
@@ -4625,22 +4772,11 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
4625
4772
  return false;
4626
4773
  }
4627
4774
  if (data && data.viewId === this.accessor.id) {
4628
- if (data.groupId === this.group.id) {
4629
- if (position === 'center') {
4630
- // don't allow to drop on self for center position
4631
- return false;
4632
- }
4633
- if (data.panelId === null) {
4634
- // don't allow group move to drop anywhere on self
4635
- return false;
4636
- }
4637
- }
4638
- const groupHasOnePanelAndIsActiveDragElement = this.group.panels.length === 1 &&
4639
- data.groupId === this.group.id;
4640
- return !groupHasOnePanelAndIsActiveDragElement;
4775
+ return true;
4641
4776
  }
4642
4777
  return this.group.canDisplayOverlay(event, position, 'content');
4643
4778
  },
4779
+ getOverrideTarget: target ? () => target.model : undefined,
4644
4780
  });
4645
4781
  this.addDisposables(this.dropTarget);
4646
4782
  }
@@ -4715,6 +4851,18 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
4715
4851
  }
4716
4852
  }
4717
4853
 
4854
+ function addGhostImage(dataTransfer, ghostElement, options) {
4855
+ var _a, _b;
4856
+ // class dockview provides to force ghost image to be drawn on a different layer and prevent weird rendering issues
4857
+ addClasses(ghostElement, 'dv-dragged');
4858
+ document.body.appendChild(ghostElement);
4859
+ dataTransfer.setDragImage(ghostElement, (_a = options === null || options === void 0 ? void 0 : options.x) !== null && _a !== void 0 ? _a : 0, (_b = options === null || options === void 0 ? void 0 : options.y) !== null && _b !== void 0 ? _b : 0);
4860
+ setTimeout(() => {
4861
+ removeClasses(ghostElement, 'dv-dragged');
4862
+ ghostElement.remove();
4863
+ }, 0);
4864
+ }
4865
+
4718
4866
  class TabDragHandler extends DragHandler {
4719
4867
  constructor(element, accessor, group, panel) {
4720
4868
  super(element);
@@ -4755,25 +4903,32 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
4755
4903
  toggleClass(this.element, 'dv-inactive-tab', true);
4756
4904
  const dragHandler = new TabDragHandler(this._element, this.accessor, this.group, this.panel);
4757
4905
  this.dropTarget = new Droptarget(this._element, {
4758
- acceptedTargetZones: ['center'],
4906
+ acceptedTargetZones: ['left', 'right'],
4907
+ overlayModel: { activationSize: { value: 50, type: 'percentage' } },
4759
4908
  canDisplayOverlay: (event, position) => {
4760
4909
  if (this.group.locked) {
4761
4910
  return false;
4762
4911
  }
4763
4912
  const data = getPanelData();
4764
4913
  if (data && this.accessor.id === data.viewId) {
4765
- if (data.panelId === null &&
4766
- data.groupId === this.group.id) {
4767
- // don't allow group move to drop on self
4768
- return false;
4769
- }
4770
- return this.panel.id !== data.panelId;
4914
+ return true;
4771
4915
  }
4772
4916
  return this.group.model.canDisplayOverlay(event, position, 'tab');
4773
4917
  },
4918
+ getOverrideTarget: () => { var _a; return (_a = group.model.dropTargetContainer) === null || _a === void 0 ? void 0 : _a.model; },
4774
4919
  });
4775
4920
  this.onWillShowOverlay = this.dropTarget.onWillShowOverlay;
4776
4921
  this.addDisposables(this._onPointDown, this._onDropped, this._onDragStart, dragHandler.onDragStart((event) => {
4922
+ if (event.dataTransfer) {
4923
+ const style = getComputedStyle(this.element);
4924
+ const newNode = this.element.cloneNode(true);
4925
+ Array.from(style).forEach((key) => newNode.style.setProperty(key, style.getPropertyValue(key), style.getPropertyPriority(key)));
4926
+ newNode.style.position = 'absolute';
4927
+ addGhostImage(event.dataTransfer, newNode, {
4928
+ y: -10,
4929
+ x: 30,
4930
+ });
4931
+ }
4777
4932
  this._onDragStart.fire(event);
4778
4933
  }), dragHandler, addDisposableListener(this._element, 'pointerdown', (event) => {
4779
4934
  this._onPointDown.fire(event);
@@ -4797,17 +4952,6 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
4797
4952
  }
4798
4953
  }
4799
4954
 
4800
- function addGhostImage(dataTransfer, ghostElement) {
4801
- // class dockview provides to force ghost image to be drawn on a different layer and prevent weird rendering issues
4802
- addClasses(ghostElement, 'dv-dragged');
4803
- document.body.appendChild(ghostElement);
4804
- dataTransfer.setDragImage(ghostElement, 0, 0);
4805
- setTimeout(() => {
4806
- removeClasses(ghostElement, 'dv-dragged');
4807
- ghostElement.remove();
4808
- }, 0);
4809
- }
4810
-
4811
4955
  class GroupDragHandler extends DragHandler {
4812
4956
  constructor(element, accessor, group) {
4813
4957
  super(element);
@@ -4847,8 +4991,10 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
4847
4991
  ghostElement.style.lineHeight = '20px';
4848
4992
  ghostElement.style.borderRadius = '12px';
4849
4993
  ghostElement.style.position = 'absolute';
4994
+ ghostElement.style.pointerEvents = 'none';
4995
+ ghostElement.style.top = '-9999px';
4850
4996
  ghostElement.textContent = `Multiple Panels (${this.group.size})`;
4851
- addGhostImage(dataTransfer, ghostElement);
4997
+ addGhostImage(dataTransfer, ghostElement, { y: -10, x: 30 });
4852
4998
  }
4853
4999
  return {
4854
5000
  dispose: () => {
@@ -4880,19 +5026,13 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
4880
5026
  this.dropTraget = new Droptarget(this._element, {
4881
5027
  acceptedTargetZones: ['center'],
4882
5028
  canDisplayOverlay: (event, position) => {
4883
- var _a;
4884
5029
  const data = getPanelData();
4885
5030
  if (data && this.accessor.id === data.viewId) {
4886
- if (data.panelId === null &&
4887
- data.groupId === this.group.id) {
4888
- // don't allow group move to drop on self
4889
- return false;
4890
- }
4891
- // don't show the overlay if the tab being dragged is the last panel of this group
4892
- return ((_a = last(this.group.panels)) === null || _a === void 0 ? void 0 : _a.id) !== data.panelId;
5031
+ return true;
4893
5032
  }
4894
5033
  return group.model.canDisplayOverlay(event, position, 'header_space');
4895
5034
  },
5035
+ getOverrideTarget: () => { var _a; return (_a = group.model.dropTargetContainer) === null || _a === void 0 ? void 0 : _a.model; },
4896
5036
  });
4897
5037
  this.onWillShowOverlay = this.dropTraget.onWillShowOverlay;
4898
5038
  this.addDisposables(handler, handler.onDragStart((event) => {
@@ -4903,88 +5043,338 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
4903
5043
  }
4904
5044
  }
4905
5045
 
4906
- class TabsContainer extends CompositeDisposable {
4907
- get panels() {
4908
- return this.tabs.map((_) => _.value.panel.id);
4909
- }
4910
- get size() {
4911
- return this.tabs.length;
4912
- }
4913
- get hidden() {
4914
- return this._hidden;
5046
+ class Scrollbar extends CompositeDisposable {
5047
+ get element() {
5048
+ return this._element;
4915
5049
  }
4916
- set hidden(value) {
4917
- this._hidden = value;
4918
- this.element.style.display = value ? 'none' : '';
5050
+ constructor(scrollableElement) {
5051
+ super();
5052
+ this.scrollableElement = scrollableElement;
5053
+ this._scrollLeft = 0;
5054
+ this._element = document.createElement('div');
5055
+ this._element.className = 'dv-scrollable';
5056
+ this._horizontalScrollbar = document.createElement('div');
5057
+ this._horizontalScrollbar.className = 'dv-scrollbar-horizontal';
5058
+ this.element.appendChild(scrollableElement);
5059
+ this.element.appendChild(this._horizontalScrollbar);
5060
+ this.addDisposables(addDisposableListener(this.element, 'wheel', (event) => {
5061
+ this._scrollLeft += event.deltaY * Scrollbar.MouseWheelSpeed;
5062
+ this.calculateScrollbarStyles();
5063
+ }), addDisposableListener(this._horizontalScrollbar, 'pointerdown', (event) => {
5064
+ event.preventDefault();
5065
+ toggleClass(this.element, 'dv-scrollable-scrolling', true);
5066
+ const originalClientX = event.clientX;
5067
+ const originalScrollLeft = this._scrollLeft;
5068
+ const onPointerMove = (event) => {
5069
+ const deltaX = event.clientX - originalClientX;
5070
+ const { clientWidth } = this.element;
5071
+ const { scrollWidth } = this.scrollableElement;
5072
+ const p = clientWidth / scrollWidth;
5073
+ this._scrollLeft = originalScrollLeft + deltaX / p;
5074
+ this.calculateScrollbarStyles();
5075
+ };
5076
+ const onEnd = () => {
5077
+ toggleClass(this.element, 'dv-scrollable-scrolling', false);
5078
+ document.removeEventListener('pointermove', onPointerMove);
5079
+ document.removeEventListener('pointerup', onEnd);
5080
+ document.removeEventListener('pointercancel', onEnd);
5081
+ };
5082
+ document.addEventListener('pointermove', onPointerMove);
5083
+ document.addEventListener('pointerup', onEnd);
5084
+ document.addEventListener('pointercancel', onEnd);
5085
+ }), addDisposableListener(this.element, 'scroll', () => {
5086
+ this.calculateScrollbarStyles();
5087
+ }), addDisposableListener(this.scrollableElement, 'scroll', () => {
5088
+ this._scrollLeft = this.scrollableElement.scrollLeft;
5089
+ this.calculateScrollbarStyles();
5090
+ }), watchElementResize(this.element, () => {
5091
+ toggleClass(this.element, 'dv-scrollable-resizing', true);
5092
+ if (this._animationTimer) {
5093
+ clearTimeout(this._animationTimer);
5094
+ }
5095
+ this._animationTimer = setTimeout(() => {
5096
+ clearTimeout(this._animationTimer);
5097
+ toggleClass(this.element, 'dv-scrollable-resizing', false);
5098
+ }, 500);
5099
+ this.calculateScrollbarStyles();
5100
+ }));
4919
5101
  }
4920
- show() {
4921
- if (!this.hidden) {
4922
- this.element.style.display = '';
5102
+ calculateScrollbarStyles() {
5103
+ const { clientWidth } = this.element;
5104
+ const { scrollWidth } = this.scrollableElement;
5105
+ const hasScrollbar = scrollWidth > clientWidth;
5106
+ if (hasScrollbar) {
5107
+ const px = clientWidth * (clientWidth / scrollWidth);
5108
+ this._horizontalScrollbar.style.width = `${px}px`;
5109
+ this._scrollLeft = clamp(this._scrollLeft, 0, this.scrollableElement.scrollWidth - clientWidth);
5110
+ this.scrollableElement.scrollLeft = this._scrollLeft;
5111
+ const percentageComplete = this._scrollLeft / (scrollWidth - clientWidth);
5112
+ this._horizontalScrollbar.style.left = `${(clientWidth - px) * percentageComplete}px`;
5113
+ }
5114
+ else {
5115
+ this._horizontalScrollbar.style.width = `0px`;
5116
+ this._horizontalScrollbar.style.left = `0px`;
5117
+ this._scrollLeft = 0;
4923
5118
  }
4924
5119
  }
4925
- hide() {
4926
- this._element.style.display = 'none';
5120
+ }
5121
+ Scrollbar.MouseWheelSpeed = 1;
5122
+
5123
+ class Tabs extends CompositeDisposable {
5124
+ get showTabsOverflowControl() {
5125
+ return this._showTabsOverflowControl;
4927
5126
  }
4928
- setRightActionsElement(element) {
4929
- if (this.rightActions === element) {
5127
+ set showTabsOverflowControl(value) {
5128
+ if (this._showTabsOverflowControl == value) {
4930
5129
  return;
4931
5130
  }
4932
- if (this.rightActions) {
4933
- this.rightActions.remove();
4934
- this.rightActions = undefined;
4935
- }
4936
- if (element) {
4937
- this.rightActionsContainer.appendChild(element);
4938
- this.rightActions = element;
5131
+ this._showTabsOverflowControl = value;
5132
+ if (value) {
5133
+ const observer = new OverflowObserver(this._tabsList);
5134
+ this._observerDisposable.value = new CompositeDisposable(observer, observer.onDidChange((event) => {
5135
+ const hasOverflow = event.hasScrollX || event.hasScrollY;
5136
+ this.toggleDropdown({ reset: !hasOverflow });
5137
+ }), addDisposableListener(this._tabsList, 'scroll', () => {
5138
+ this.toggleDropdown({ reset: false });
5139
+ }));
4939
5140
  }
4940
5141
  }
4941
- setLeftActionsElement(element) {
4942
- if (this.leftActions === element) {
4943
- return;
4944
- }
4945
- if (this.leftActions) {
4946
- this.leftActions.remove();
4947
- this.leftActions = undefined;
4948
- }
4949
- if (element) {
4950
- this.leftActionsContainer.appendChild(element);
4951
- this.leftActions = element;
5142
+ get element() {
5143
+ return this._element;
5144
+ }
5145
+ get panels() {
5146
+ return this._tabs.map((_) => _.value.panel.id);
5147
+ }
5148
+ get size() {
5149
+ return this._tabs.length;
5150
+ }
5151
+ get tabs() {
5152
+ return this._tabs.map((_) => _.value);
5153
+ }
5154
+ constructor(group, accessor, options) {
5155
+ super();
5156
+ this.group = group;
5157
+ this.accessor = accessor;
5158
+ this._observerDisposable = new MutableDisposable();
5159
+ this._tabs = [];
5160
+ this.selectedIndex = -1;
5161
+ this._showTabsOverflowControl = false;
5162
+ this._onTabDragStart = new Emitter();
5163
+ this.onTabDragStart = this._onTabDragStart.event;
5164
+ this._onDrop = new Emitter();
5165
+ this.onDrop = this._onDrop.event;
5166
+ this._onWillShowOverlay = new Emitter();
5167
+ this.onWillShowOverlay = this._onWillShowOverlay.event;
5168
+ this._onOverflowTabsChange = new Emitter();
5169
+ this.onOverflowTabsChange = this._onOverflowTabsChange.event;
5170
+ this._tabsList = document.createElement('div');
5171
+ this._tabsList.className = 'dv-tabs-container dv-horizontal';
5172
+ this.showTabsOverflowControl = options.showTabsOverflowControl;
5173
+ const scrollbar = new Scrollbar(this._tabsList);
5174
+ this._element = scrollbar.element;
5175
+ this.addDisposables(this._onOverflowTabsChange, this._observerDisposable, scrollbar, this._onWillShowOverlay, this._onDrop, this._onTabDragStart, addDisposableListener(this.element, 'pointerdown', (event) => {
5176
+ if (event.defaultPrevented) {
5177
+ return;
5178
+ }
5179
+ const isLeftClick = event.button === 0;
5180
+ if (isLeftClick) {
5181
+ this.accessor.doSetGroupActive(this.group);
5182
+ }
5183
+ }), exports.DockviewDisposable.from(() => {
5184
+ for (const { value, disposable } of this._tabs) {
5185
+ disposable.dispose();
5186
+ value.dispose();
5187
+ }
5188
+ this._tabs = [];
5189
+ }));
5190
+ }
5191
+ indexOf(id) {
5192
+ return this._tabs.findIndex((tab) => tab.value.panel.id === id);
5193
+ }
5194
+ isActive(tab) {
5195
+ return (this.selectedIndex > -1 &&
5196
+ this._tabs[this.selectedIndex].value === tab);
5197
+ }
5198
+ setActivePanel(panel) {
5199
+ let runningWidth = 0;
5200
+ for (const tab of this._tabs) {
5201
+ const isActivePanel = panel.id === tab.value.panel.id;
5202
+ tab.value.setActive(isActivePanel);
5203
+ if (isActivePanel) {
5204
+ const element = tab.value.element;
5205
+ const parentElement = element.parentElement;
5206
+ if (runningWidth < parentElement.scrollLeft ||
5207
+ runningWidth + element.clientWidth >
5208
+ parentElement.scrollLeft + parentElement.clientWidth) {
5209
+ parentElement.scrollLeft = runningWidth;
5210
+ }
5211
+ }
5212
+ runningWidth += tab.value.element.clientWidth;
4952
5213
  }
4953
5214
  }
4954
- setPrefixActionsElement(element) {
4955
- if (this.preActions === element) {
5215
+ openPanel(panel, index = this._tabs.length) {
5216
+ if (this._tabs.find((tab) => tab.value.panel.id === panel.id)) {
4956
5217
  return;
4957
5218
  }
4958
- if (this.preActions) {
4959
- this.preActions.remove();
4960
- this.preActions = undefined;
5219
+ const tab = new Tab(panel, this.accessor, this.group);
5220
+ tab.setContent(panel.view.tab);
5221
+ const disposable = new CompositeDisposable(tab.onDragStart((event) => {
5222
+ this._onTabDragStart.fire({ nativeEvent: event, panel });
5223
+ }), tab.onPointerDown((event) => {
5224
+ if (event.defaultPrevented) {
5225
+ return;
5226
+ }
5227
+ const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
5228
+ const isFloatingWithOnePanel = this.group.api.location.type === 'floating' &&
5229
+ this.size === 1;
5230
+ if (isFloatingGroupsEnabled &&
5231
+ !isFloatingWithOnePanel &&
5232
+ event.shiftKey) {
5233
+ event.preventDefault();
5234
+ const panel = this.accessor.getGroupPanel(tab.panel.id);
5235
+ const { top, left } = tab.element.getBoundingClientRect();
5236
+ const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
5237
+ this.accessor.addFloatingGroup(panel, {
5238
+ x: left - rootLeft,
5239
+ y: top - rootTop,
5240
+ inDragMode: true,
5241
+ });
5242
+ return;
5243
+ }
5244
+ switch (event.button) {
5245
+ case 0: // left click or touch
5246
+ if (this.group.activePanel !== panel) {
5247
+ this.group.model.openPanel(panel);
5248
+ }
5249
+ break;
5250
+ }
5251
+ }), tab.onDrop((event) => {
5252
+ this._onDrop.fire({
5253
+ event: event.nativeEvent,
5254
+ index: this._tabs.findIndex((x) => x.value === tab),
5255
+ });
5256
+ }), tab.onWillShowOverlay((event) => {
5257
+ this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
5258
+ kind: 'tab',
5259
+ panel: this.group.activePanel,
5260
+ api: this.accessor.api,
5261
+ group: this.group,
5262
+ getData: getPanelData,
5263
+ }));
5264
+ }));
5265
+ const value = { value: tab, disposable };
5266
+ this.addTab(value, index);
5267
+ }
5268
+ delete(id) {
5269
+ const index = this.indexOf(id);
5270
+ const tabToRemove = this._tabs.splice(index, 1)[0];
5271
+ const { value, disposable } = tabToRemove;
5272
+ disposable.dispose();
5273
+ value.dispose();
5274
+ value.element.remove();
5275
+ }
5276
+ addTab(tab, index = this._tabs.length) {
5277
+ if (index < 0 || index > this._tabs.length) {
5278
+ throw new Error('invalid location');
4961
5279
  }
4962
- if (element) {
4963
- this.preActionsContainer.appendChild(element);
4964
- this.preActions = element;
5280
+ this._tabsList.insertBefore(tab.value.element, this._tabsList.children[index]);
5281
+ this._tabs = [
5282
+ ...this._tabs.slice(0, index),
5283
+ tab,
5284
+ ...this._tabs.slice(index),
5285
+ ];
5286
+ if (this.selectedIndex < 0) {
5287
+ this.selectedIndex = index;
4965
5288
  }
4966
5289
  }
4967
- get element() {
4968
- return this._element;
5290
+ toggleDropdown(options) {
5291
+ const tabs = options.reset
5292
+ ? []
5293
+ : this._tabs
5294
+ .filter((tab) => !isChildEntirelyVisibleWithinParent(tab.value.element, this._tabsList))
5295
+ .map((x) => x.value.panel.id);
5296
+ this._onOverflowTabsChange.fire({ tabs, reset: options.reset });
4969
5297
  }
4970
- isActive(tab) {
4971
- return (this.selectedIndex > -1 &&
4972
- this.tabs[this.selectedIndex].value === tab);
5298
+ }
5299
+
5300
+ const createSvgElementFromPath = (params) => {
5301
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
5302
+ svg.setAttributeNS(null, 'height', params.height);
5303
+ svg.setAttributeNS(null, 'width', params.width);
5304
+ svg.setAttributeNS(null, 'viewBox', params.viewbox);
5305
+ svg.setAttributeNS(null, 'aria-hidden', 'false');
5306
+ svg.setAttributeNS(null, 'focusable', 'false');
5307
+ svg.classList.add('dv-svg');
5308
+ const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
5309
+ path.setAttributeNS(null, 'd', params.path);
5310
+ svg.appendChild(path);
5311
+ return svg;
5312
+ };
5313
+ const createCloseButton = () => createSvgElementFromPath({
5314
+ width: '11',
5315
+ height: '11',
5316
+ viewbox: '0 0 28 28',
5317
+ path: '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',
5318
+ });
5319
+ const createExpandMoreButton = () => createSvgElementFromPath({
5320
+ width: '11',
5321
+ height: '11',
5322
+ viewbox: '0 0 24 15',
5323
+ path: 'M12 14.15L0 2.15L2.15 0L12 9.9L21.85 0.0499992L24 2.2L12 14.15Z',
5324
+ });
5325
+ const createChevronRightButton = () => createSvgElementFromPath({
5326
+ width: '11',
5327
+ height: '11',
5328
+ viewbox: '0 0 15 25',
5329
+ path: 'M2.15 24.1L0 21.95L9.9 12.05L0 2.15L2.15 0L14.2 12.05L2.15 24.1Z',
5330
+ });
5331
+
5332
+ function createDropdownElementHandle() {
5333
+ const el = document.createElement('div');
5334
+ el.className = 'dv-tabs-overflow-dropdown-default';
5335
+ const text = document.createElement('span');
5336
+ text.textContent = ``;
5337
+ const icon = createChevronRightButton();
5338
+ el.appendChild(icon);
5339
+ el.appendChild(text);
5340
+ return {
5341
+ element: el,
5342
+ update: (params) => {
5343
+ text.textContent = `${params.tabs}`;
5344
+ },
5345
+ };
5346
+ }
5347
+
5348
+ class TabsContainer extends CompositeDisposable {
5349
+ get onTabDragStart() {
5350
+ return this.tabs.onTabDragStart;
4973
5351
  }
4974
- indexOf(id) {
4975
- return this.tabs.findIndex((tab) => tab.value.panel.id === id);
5352
+ get panels() {
5353
+ return this.tabs.panels;
5354
+ }
5355
+ get size() {
5356
+ return this.tabs.size;
5357
+ }
5358
+ get hidden() {
5359
+ return this._hidden;
5360
+ }
5361
+ set hidden(value) {
5362
+ this._hidden = value;
5363
+ this.element.style.display = value ? 'none' : '';
5364
+ }
5365
+ get element() {
5366
+ return this._element;
4976
5367
  }
4977
5368
  constructor(accessor, group) {
4978
5369
  super();
4979
5370
  this.accessor = accessor;
4980
5371
  this.group = group;
4981
- this.tabs = [];
4982
- this.selectedIndex = -1;
4983
5372
  this._hidden = false;
5373
+ this.dropdownPart = null;
5374
+ this._overflowTabs = [];
5375
+ this._dropdownDisposable = new MutableDisposable();
4984
5376
  this._onDrop = new Emitter();
4985
5377
  this.onDrop = this._onDrop.event;
4986
- this._onTabDragStart = new Emitter();
4987
- this.onTabDragStart = this._onTabDragStart.event;
4988
5378
  this._onGroupDragStart = new Emitter();
4989
5379
  this.onGroupDragStart = this._onGroupDragStart.event;
4990
5380
  this._onWillShowOverlay = new Emitter();
@@ -4998,15 +5388,21 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
4998
5388
  this.leftActionsContainer.className = 'dv-left-actions-container';
4999
5389
  this.preActionsContainer = document.createElement('div');
5000
5390
  this.preActionsContainer.className = 'dv-pre-actions-container';
5001
- this.tabContainer = document.createElement('div');
5002
- this.tabContainer.className = 'dv-tabs-container';
5391
+ this.tabs = new Tabs(group, accessor, {
5392
+ showTabsOverflowControl: !accessor.options.disableTabsOverflowList,
5393
+ });
5003
5394
  this.voidContainer = new VoidContainer(this.accessor, this.group);
5004
5395
  this._element.appendChild(this.preActionsContainer);
5005
- this._element.appendChild(this.tabContainer);
5396
+ this._element.appendChild(this.tabs.element);
5006
5397
  this._element.appendChild(this.leftActionsContainer);
5007
5398
  this._element.appendChild(this.voidContainer.element);
5008
5399
  this._element.appendChild(this.rightActionsContainer);
5009
- this.addDisposables(this._onWillShowOverlay, this._onDrop, this._onTabDragStart, this._onGroupDragStart, this.voidContainer, this.voidContainer.onDragStart((event) => {
5400
+ this.addDisposables(accessor.onDidOptionsChange(() => {
5401
+ this.tabs.showTabsOverflowControl =
5402
+ !accessor.options.disableTabsOverflowList;
5403
+ }), this.tabs.onOverflowTabsChange((event) => {
5404
+ this.toggleDropdown(event);
5405
+ }), this.tabs, this._onWillShowOverlay, this._onDrop, this._onGroupDragStart, this.voidContainer, this.voidContainer.onDragStart((event) => {
5010
5406
  this._onGroupDragStart.fire({
5011
5407
  nativeEvent: event,
5012
5408
  group: this.group,
@@ -5014,7 +5410,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5014
5410
  }), this.voidContainer.onDrop((event) => {
5015
5411
  this._onDrop.fire({
5016
5412
  event: event.nativeEvent,
5017
- index: this.tabs.length,
5413
+ index: this.tabs.size,
5018
5414
  });
5019
5415
  }), this.voidContainer.onWillShowOverlay((event) => {
5020
5416
  this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
@@ -5024,133 +5420,149 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5024
5420
  group: this.group,
5025
5421
  getData: getPanelData,
5026
5422
  }));
5027
- }), addDisposableListener(this.voidContainer.element, 'pointerdown', (event) => {
5028
- const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
5029
- if (isFloatingGroupsEnabled &&
5030
- event.shiftKey &&
5031
- this.group.api.location.type !== 'floating') {
5032
- event.preventDefault();
5033
- const { top, left } = this.element.getBoundingClientRect();
5034
- const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
5035
- this.accessor.addFloatingGroup(this.group, {
5036
- x: left - rootLeft + 20,
5037
- y: top - rootTop + 20,
5038
- inDragMode: true,
5039
- });
5040
- }
5041
- }), addDisposableListener(this.tabContainer, 'pointerdown', (event) => {
5042
- if (event.defaultPrevented) {
5043
- return;
5044
- }
5045
- const isLeftClick = event.button === 0;
5046
- if (isLeftClick) {
5047
- this.accessor.doSetGroupActive(this.group);
5048
- }
5049
- }));
5050
- }
5051
- setActive(_isGroupActive) {
5052
- // noop
5053
- }
5054
- delete(id) {
5055
- const index = this.tabs.findIndex((tab) => tab.value.panel.id === id);
5056
- const tabToRemove = this.tabs.splice(index, 1)[0];
5057
- if (!tabToRemove) {
5058
- throw new Error(`dockview: Tab not found`);
5059
- }
5060
- const { value, disposable } = tabToRemove;
5061
- disposable.dispose();
5062
- value.dispose();
5063
- value.element.remove();
5064
- this.updateClassnames();
5065
- }
5066
- setActivePanel(panel) {
5067
- this.tabs.forEach((tab) => {
5068
- const isActivePanel = panel.id === tab.value.panel.id;
5069
- tab.value.setActive(isActivePanel);
5070
- });
5071
- }
5072
- openPanel(panel, index = this.tabs.length) {
5073
- if (this.tabs.find((tab) => tab.value.panel.id === panel.id)) {
5074
- return;
5075
- }
5076
- const tab = new Tab(panel, this.accessor, this.group);
5077
- tab.setContent(panel.view.tab);
5078
- const disposable = new CompositeDisposable(tab.onDragStart((event) => {
5079
- this._onTabDragStart.fire({ nativeEvent: event, panel });
5080
- }), tab.onPointerDown((event) => {
5423
+ }), addDisposableListener(this.voidContainer.element, 'pointerdown', (event) => {
5081
5424
  if (event.defaultPrevented) {
5082
5425
  return;
5083
5426
  }
5084
5427
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
5085
- const isFloatingWithOnePanel = this.group.api.location.type === 'floating' &&
5086
- this.size === 1;
5087
5428
  if (isFloatingGroupsEnabled &&
5088
- !isFloatingWithOnePanel &&
5089
- event.shiftKey) {
5429
+ event.shiftKey &&
5430
+ this.group.api.location.type !== 'floating') {
5090
5431
  event.preventDefault();
5091
- const panel = this.accessor.getGroupPanel(tab.panel.id);
5092
- const { top, left } = tab.element.getBoundingClientRect();
5432
+ const { top, left } = this.element.getBoundingClientRect();
5093
5433
  const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
5094
- this.accessor.addFloatingGroup(panel, {
5095
- x: left - rootLeft,
5096
- y: top - rootTop,
5434
+ this.accessor.addFloatingGroup(this.group, {
5435
+ x: left - rootLeft + 20,
5436
+ y: top - rootTop + 20,
5097
5437
  inDragMode: true,
5098
5438
  });
5099
- return;
5100
- }
5101
- switch (event.button) {
5102
- case 0: // left click or touch
5103
- if (this.group.activePanel !== panel) {
5104
- this.group.model.openPanel(panel);
5105
- }
5106
- break;
5107
5439
  }
5108
- }), tab.onDrop((event) => {
5109
- this._onDrop.fire({
5110
- event: event.nativeEvent,
5111
- index: this.tabs.findIndex((x) => x.value === tab),
5112
- });
5113
- }), tab.onWillShowOverlay((event) => {
5114
- this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
5115
- kind: 'tab',
5116
- panel: this.group.activePanel,
5117
- api: this.accessor.api,
5118
- group: this.group,
5119
- getData: getPanelData,
5120
- }));
5121
5440
  }));
5122
- const value = { value: tab, disposable };
5123
- this.addTab(value, index);
5124
5441
  }
5125
- closePanel(panel) {
5126
- this.delete(panel.id);
5442
+ show() {
5443
+ if (!this.hidden) {
5444
+ this.element.style.display = '';
5445
+ }
5127
5446
  }
5128
- dispose() {
5129
- super.dispose();
5130
- for (const { value, disposable } of this.tabs) {
5131
- disposable.dispose();
5132
- value.dispose();
5447
+ hide() {
5448
+ this._element.style.display = 'none';
5449
+ }
5450
+ setRightActionsElement(element) {
5451
+ if (this.rightActions === element) {
5452
+ return;
5453
+ }
5454
+ if (this.rightActions) {
5455
+ this.rightActions.remove();
5456
+ this.rightActions = undefined;
5457
+ }
5458
+ if (element) {
5459
+ this.rightActionsContainer.appendChild(element);
5460
+ this.rightActions = element;
5133
5461
  }
5134
- this.tabs = [];
5135
5462
  }
5136
- addTab(tab, index = this.tabs.length) {
5137
- if (index < 0 || index > this.tabs.length) {
5138
- throw new Error('invalid location');
5463
+ setLeftActionsElement(element) {
5464
+ if (this.leftActions === element) {
5465
+ return;
5139
5466
  }
5140
- this.tabContainer.insertBefore(tab.value.element, this.tabContainer.children[index]);
5141
- this.tabs = [
5142
- ...this.tabs.slice(0, index),
5143
- tab,
5144
- ...this.tabs.slice(index),
5145
- ];
5146
- if (this.selectedIndex < 0) {
5147
- this.selectedIndex = index;
5467
+ if (this.leftActions) {
5468
+ this.leftActions.remove();
5469
+ this.leftActions = undefined;
5470
+ }
5471
+ if (element) {
5472
+ this.leftActionsContainer.appendChild(element);
5473
+ this.leftActions = element;
5474
+ }
5475
+ }
5476
+ setPrefixActionsElement(element) {
5477
+ if (this.preActions === element) {
5478
+ return;
5479
+ }
5480
+ if (this.preActions) {
5481
+ this.preActions.remove();
5482
+ this.preActions = undefined;
5483
+ }
5484
+ if (element) {
5485
+ this.preActionsContainer.appendChild(element);
5486
+ this.preActions = element;
5148
5487
  }
5488
+ }
5489
+ isActive(tab) {
5490
+ return this.tabs.isActive(tab);
5491
+ }
5492
+ indexOf(id) {
5493
+ return this.tabs.indexOf(id);
5494
+ }
5495
+ setActive(_isGroupActive) {
5496
+ // noop
5497
+ }
5498
+ delete(id) {
5499
+ this.tabs.delete(id);
5500
+ this.updateClassnames();
5501
+ }
5502
+ setActivePanel(panel) {
5503
+ this.tabs.setActivePanel(panel);
5504
+ }
5505
+ openPanel(panel, index = this.tabs.size) {
5506
+ this.tabs.openPanel(panel, index);
5149
5507
  this.updateClassnames();
5150
5508
  }
5509
+ closePanel(panel) {
5510
+ this.delete(panel.id);
5511
+ }
5151
5512
  updateClassnames() {
5152
5513
  toggleClass(this._element, 'dv-single-tab', this.size === 1);
5153
5514
  }
5515
+ toggleDropdown(options) {
5516
+ const tabs = options.reset ? [] : options.tabs;
5517
+ this._overflowTabs = tabs;
5518
+ if (this._overflowTabs.length > 0 && this.dropdownPart) {
5519
+ this.dropdownPart.update({ tabs: tabs.length });
5520
+ return;
5521
+ }
5522
+ if (this._overflowTabs.length === 0) {
5523
+ this._dropdownDisposable.dispose();
5524
+ return;
5525
+ }
5526
+ const root = document.createElement('div');
5527
+ root.className = 'dv-tabs-overflow-dropdown-root';
5528
+ const part = createDropdownElementHandle();
5529
+ part.update({ tabs: tabs.length });
5530
+ this.dropdownPart = part;
5531
+ root.appendChild(part.element);
5532
+ this.rightActionsContainer.prepend(root);
5533
+ this._dropdownDisposable.value = new CompositeDisposable(exports.DockviewDisposable.from(() => {
5534
+ var _a, _b;
5535
+ root.remove();
5536
+ (_b = (_a = this.dropdownPart) === null || _a === void 0 ? void 0 : _a.dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
5537
+ this.dropdownPart = null;
5538
+ }), addDisposableListener(root, 'pointerdown', (event) => {
5539
+ event.preventDefault();
5540
+ }, { capture: true }), addDisposableListener(root, 'click', (event) => {
5541
+ const el = document.createElement('div');
5542
+ el.style.overflow = 'auto';
5543
+ el.className = 'dv-tabs-overflow-container';
5544
+ for (const tab of this.tabs.tabs.filter((tab) => this._overflowTabs.includes(tab.panel.id))) {
5545
+ const panelObject = this.group.panels.find((panel) => panel === tab.panel);
5546
+ const tabComponent = panelObject.view.createTabRenderer('headerOverflow');
5547
+ const child = tabComponent.element;
5548
+ const wrapper = document.createElement('div');
5549
+ toggleClass(wrapper, 'dv-tab', true);
5550
+ toggleClass(wrapper, 'dv-active-tab', panelObject.api.isActive);
5551
+ toggleClass(wrapper, 'dv-inactive-tab', !panelObject.api.isActive);
5552
+ wrapper.addEventListener('mousedown', () => {
5553
+ this.accessor.popupService.close();
5554
+ tab.element.scrollIntoView();
5555
+ tab.panel.api.setActive();
5556
+ });
5557
+ wrapper.appendChild(child);
5558
+ el.appendChild(wrapper);
5559
+ }
5560
+ this.accessor.popupService.openPopover(el, {
5561
+ x: event.clientX,
5562
+ y: event.clientY,
5563
+ });
5564
+ }));
5565
+ }
5154
5566
  }
5155
5567
 
5156
5568
  class DockviewUnhandledDragOverEvent extends AcceptableEvent {
@@ -5180,9 +5592,11 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5180
5592
  rootOverlayModel: undefined,
5181
5593
  locked: undefined,
5182
5594
  disableDnd: undefined,
5183
- gap: undefined,
5184
5595
  className: undefined,
5185
5596
  noPanelsOverlay: undefined,
5597
+ dndEdges: undefined,
5598
+ theme: undefined,
5599
+ disableTabsOverflowList: undefined,
5186
5600
  };
5187
5601
  return Object.keys(properties);
5188
5602
  })();
@@ -5361,6 +5775,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5361
5775
  this._location = { type: 'grid' };
5362
5776
  this.mostRecentlyUsed = [];
5363
5777
  this._overwriteRenderContainer = null;
5778
+ this._overwriteDropTargetContainer = null;
5364
5779
  this._onDidChange = new Emitter();
5365
5780
  this.onDidChange = this._onDidChange.event;
5366
5781
  this._width = 0;
@@ -5438,6 +5853,13 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5438
5853
  var _a;
5439
5854
  return ((_a = this._overwriteRenderContainer) !== null && _a !== void 0 ? _a : this.accessor.overlayRenderContainer);
5440
5855
  }
5856
+ set dropTargetContainer(value) {
5857
+ this._overwriteDropTargetContainer = value;
5858
+ }
5859
+ get dropTargetContainer() {
5860
+ var _a;
5861
+ return ((_a = this._overwriteDropTargetContainer) !== null && _a !== void 0 ? _a : this.accessor.rootDropTargetContainer);
5862
+ }
5441
5863
  initialize() {
5442
5864
  if (this.options.panels) {
5443
5865
  this.options.panels.forEach((panel) => {
@@ -5786,6 +6208,25 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5786
6208
  }
5787
6209
  const data = getPanelData();
5788
6210
  if (data && data.viewId === this.accessor.id) {
6211
+ if (type === 'content') {
6212
+ if (data.groupId === this.id) {
6213
+ // don't allow to drop on self for center position
6214
+ if (position === 'center') {
6215
+ return;
6216
+ }
6217
+ if (data.panelId === null) {
6218
+ // don't allow group move to drop anywhere on self
6219
+ return;
6220
+ }
6221
+ }
6222
+ }
6223
+ if (type === 'header') {
6224
+ if (data.groupId === this.id) {
6225
+ if (data.panelId === null) {
6226
+ return;
6227
+ }
6228
+ }
6229
+ }
5789
6230
  if (data.panelId === null) {
5790
6231
  // this is a group move dnd event
5791
6232
  const { groupId } = data;
@@ -6214,6 +6655,46 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6214
6655
  }
6215
6656
  }
6216
6657
 
6658
+ const themeDark = {
6659
+ name: 'dark',
6660
+ className: 'dockview-theme-dark',
6661
+ };
6662
+ const themeLight = {
6663
+ name: 'light',
6664
+ className: 'dockview-theme-light',
6665
+ };
6666
+ const themeVisualStudio = {
6667
+ name: 'visualStudio',
6668
+ className: 'dockview-theme-vs',
6669
+ };
6670
+ const themeAbyss = {
6671
+ name: 'abyss',
6672
+ className: 'dockview-theme-abyss',
6673
+ };
6674
+ const themeDracula = {
6675
+ name: 'dracula',
6676
+ className: 'dockview-theme-dracula',
6677
+ };
6678
+ const themeReplit = {
6679
+ name: 'replit',
6680
+ className: 'dockview-theme-replit',
6681
+ gap: 10,
6682
+ };
6683
+ const themeAbyssSpaced = {
6684
+ name: 'abyssSpaced',
6685
+ className: 'dockview-theme-abyss-spaced',
6686
+ gap: 10,
6687
+ dndOverlayMounting: 'absolute',
6688
+ dndPanelOverlay: 'group',
6689
+ };
6690
+ const themeLightSpaced = {
6691
+ name: 'lightSpaced',
6692
+ className: 'dockview-theme-light-spaced',
6693
+ gap: 10,
6694
+ dndOverlayMounting: 'absolute',
6695
+ dndPanelOverlay: 'group',
6696
+ };
6697
+
6217
6698
  class DockviewPanelApiImpl extends GridviewPanelApiImpl {
6218
6699
  get location() {
6219
6700
  return this.group.api.location;
@@ -6488,38 +6969,6 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6488
6969
  }
6489
6970
  }
6490
6971
 
6491
- const createSvgElementFromPath = (params) => {
6492
- const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
6493
- svg.setAttributeNS(null, 'height', params.height);
6494
- svg.setAttributeNS(null, 'width', params.width);
6495
- svg.setAttributeNS(null, 'viewBox', params.viewbox);
6496
- svg.setAttributeNS(null, 'aria-hidden', 'false');
6497
- svg.setAttributeNS(null, 'focusable', 'false');
6498
- svg.classList.add('dv-svg');
6499
- const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
6500
- path.setAttributeNS(null, 'd', params.path);
6501
- svg.appendChild(path);
6502
- return svg;
6503
- };
6504
- const createCloseButton = () => createSvgElementFromPath({
6505
- width: '11',
6506
- height: '11',
6507
- viewbox: '0 0 28 28',
6508
- path: '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',
6509
- });
6510
- const createExpandMoreButton = () => createSvgElementFromPath({
6511
- width: '11',
6512
- height: '11',
6513
- viewbox: '0 0 24 15',
6514
- path: 'M12 14.15L0 2.15L2.15 0L12 9.9L21.85 0.0499992L24 2.2L12 14.15Z',
6515
- });
6516
- const createChevronRightButton = () => createSvgElementFromPath({
6517
- width: '11',
6518
- height: '11',
6519
- viewbox: '0 0 15 25',
6520
- path: 'M2.15 24.1L0 21.95L9.9 12.05L0 2.15L2.15 0L14.2 12.05L2.15 24.1Z',
6521
- });
6522
-
6523
6972
  class DefaultTab extends CompositeDisposable {
6524
6973
  get element() {
6525
6974
  return this._element;
@@ -6576,12 +7025,21 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6576
7025
  this._content = this.createContentComponent(this.id, contentComponent);
6577
7026
  this._tab = this.createTabComponent(this.id, tabComponent);
6578
7027
  }
7028
+ createTabRenderer(tabLocation) {
7029
+ var _a;
7030
+ const cmp = this.createTabComponent(this.id, this.tabComponent);
7031
+ if (this._params) {
7032
+ cmp.init(Object.assign(Object.assign({}, this._params), { tabLocation }));
7033
+ }
7034
+ if (this._updateEvent) {
7035
+ (_a = cmp.update) === null || _a === void 0 ? void 0 : _a.call(cmp, this._updateEvent);
7036
+ }
7037
+ return cmp;
7038
+ }
6579
7039
  init(params) {
7040
+ this._params = params;
6580
7041
  this.content.init(params);
6581
- this.tab.init(params);
6582
- }
6583
- updateParentGroup(_group, _isPanelVisible) {
6584
- // noop
7042
+ this.tab.init(Object.assign(Object.assign({}, params), { tabLocation: 'header' }));
6585
7043
  }
6586
7044
  layout(width, height) {
6587
7045
  var _a, _b;
@@ -6589,6 +7047,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6589
7047
  }
6590
7048
  update(event) {
6591
7049
  var _a, _b, _c, _d;
7050
+ this._updateEvent = event;
6592
7051
  (_b = (_a = this.content).update) === null || _b === void 0 ? void 0 : _b.call(_a, event);
6593
7052
  (_d = (_c = this.tab).update) === null || _d === void 0 ? void 0 : _d.call(_c, event);
6594
7053
  }
@@ -7426,6 +7885,132 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
7426
7885
  }
7427
7886
  }
7428
7887
 
7888
+ class PopupService extends CompositeDisposable {
7889
+ constructor(root) {
7890
+ super();
7891
+ this.root = root;
7892
+ this._active = null;
7893
+ this._activeDisposable = new MutableDisposable();
7894
+ this._element = document.createElement('div');
7895
+ this._element.className = 'dv-popover-anchor';
7896
+ this._element.style.position = 'relative';
7897
+ this.root.prepend(this._element);
7898
+ this.addDisposables(exports.DockviewDisposable.from(() => {
7899
+ this.close();
7900
+ }), this._activeDisposable);
7901
+ }
7902
+ openPopover(element, position) {
7903
+ this.close();
7904
+ const wrapper = document.createElement('div');
7905
+ wrapper.style.position = 'absolute';
7906
+ wrapper.style.zIndex = '99';
7907
+ wrapper.appendChild(element);
7908
+ const anchorBox = this._element.getBoundingClientRect();
7909
+ const offsetX = anchorBox.left;
7910
+ const offsetY = anchorBox.top;
7911
+ wrapper.style.top = `${position.y - offsetY}px`;
7912
+ wrapper.style.left = `${position.x - offsetX}px`;
7913
+ this._element.appendChild(wrapper);
7914
+ this._active = wrapper;
7915
+ this._activeDisposable.value = new CompositeDisposable(addDisposableWindowListener(window, 'pointerdown', (event) => {
7916
+ var _a;
7917
+ const target = event.target;
7918
+ if (!(target instanceof HTMLElement)) {
7919
+ return;
7920
+ }
7921
+ let el = target;
7922
+ while (el && el !== wrapper) {
7923
+ el = (_a = el === null || el === void 0 ? void 0 : el.parentElement) !== null && _a !== void 0 ? _a : null;
7924
+ }
7925
+ if (el) {
7926
+ return; // clicked within popover
7927
+ }
7928
+ this.close();
7929
+ }));
7930
+ }
7931
+ close() {
7932
+ if (this._active) {
7933
+ this._active.remove();
7934
+ this._activeDisposable.dispose();
7935
+ this._active = null;
7936
+ }
7937
+ }
7938
+ }
7939
+
7940
+ class DropTargetAnchorContainer extends CompositeDisposable {
7941
+ get disabled() {
7942
+ return this._disabled;
7943
+ }
7944
+ set disabled(value) {
7945
+ var _a;
7946
+ if (this.disabled === value) {
7947
+ return;
7948
+ }
7949
+ this._disabled = value;
7950
+ if (value) {
7951
+ (_a = this.model) === null || _a === void 0 ? void 0 : _a.clear();
7952
+ }
7953
+ }
7954
+ get model() {
7955
+ if (this.disabled) {
7956
+ return undefined;
7957
+ }
7958
+ return {
7959
+ clear: () => {
7960
+ var _a;
7961
+ if (this._model) {
7962
+ (_a = this._model.root.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(this._model.root);
7963
+ }
7964
+ this._model = undefined;
7965
+ },
7966
+ exists: () => {
7967
+ return !!this._model;
7968
+ },
7969
+ getElements: (event, outline) => {
7970
+ const changed = this._outline !== outline;
7971
+ this._outline = outline;
7972
+ if (this._model) {
7973
+ this._model.changed = changed;
7974
+ return this._model;
7975
+ }
7976
+ const container = this.createContainer();
7977
+ const anchor = this.createAnchor();
7978
+ this._model = { root: container, overlay: anchor, changed };
7979
+ container.appendChild(anchor);
7980
+ this.element.appendChild(container);
7981
+ if ((event === null || event === void 0 ? void 0 : event.target) instanceof HTMLElement) {
7982
+ const targetBox = event.target.getBoundingClientRect();
7983
+ const box = this.element.getBoundingClientRect();
7984
+ anchor.style.left = `${targetBox.left - box.left}px`;
7985
+ anchor.style.top = `${targetBox.top - box.top}px`;
7986
+ }
7987
+ return this._model;
7988
+ },
7989
+ };
7990
+ }
7991
+ constructor(element, options) {
7992
+ super();
7993
+ this.element = element;
7994
+ this._disabled = false;
7995
+ this._disabled = options.disabled;
7996
+ this.addDisposables(exports.DockviewDisposable.from(() => {
7997
+ var _a;
7998
+ (_a = this.model) === null || _a === void 0 ? void 0 : _a.clear();
7999
+ }));
8000
+ }
8001
+ createContainer() {
8002
+ const el = document.createElement('div');
8003
+ el.className = 'dv-drop-target-container';
8004
+ return el;
8005
+ }
8006
+ createAnchor() {
8007
+ const el = document.createElement('div');
8008
+ el.className = 'dv-drop-target-anchor';
8009
+ el.style.visibility = 'hidden';
8010
+ return el;
8011
+ }
8012
+ }
8013
+
7429
8014
  const DEFAULT_ROOT_OVERLAY_MODEL = {
7430
8015
  activationSize: { type: 'pixels', value: 10 },
7431
8016
  size: { type: 'pixels', value: 20 },
@@ -7471,14 +8056,11 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
7471
8056
  get api() {
7472
8057
  return this._api;
7473
8058
  }
7474
- get gap() {
7475
- return this.gridview.margin;
7476
- }
7477
8059
  get floatingGroups() {
7478
8060
  return this._floatingGroups;
7479
8061
  }
7480
8062
  constructor(container, options) {
7481
- var _a;
8063
+ var _a, _b, _c;
7482
8064
  super(container, {
7483
8065
  proportionalLayout: true,
7484
8066
  orientation: exports.Orientation.HORIZONTAL,
@@ -7487,12 +8069,12 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
7487
8069
  : undefined,
7488
8070
  disableAutoResizing: options.disableAutoResizing,
7489
8071
  locked: options.locked,
7490
- margin: options.gap,
8072
+ margin: (_b = (_a = options.theme) === null || _a === void 0 ? void 0 : _a.gap) !== null && _b !== void 0 ? _b : 0,
7491
8073
  className: options.className,
7492
8074
  });
7493
8075
  this.nextGroupId = sequentialNumberGenerator();
7494
8076
  this._deserializer = new DefaultDockviewDeserialzier(this);
7495
- this.watermark = null;
8077
+ this._watermark = null;
7496
8078
  this._onWillDragPanel = new Emitter();
7497
8079
  this.onWillDragPanel = this._onWillDragPanel.event;
7498
8080
  this._onWillDragGroup = new Emitter();
@@ -7523,16 +8105,22 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
7523
8105
  this.onDidRemoveGroup = this._onDidRemoveGroup.event;
7524
8106
  this._onDidAddGroup = new Emitter();
7525
8107
  this.onDidAddGroup = this._onDidAddGroup.event;
8108
+ this._onDidOptionsChange = new Emitter();
8109
+ this.onDidOptionsChange = this._onDidOptionsChange.event;
7526
8110
  this._onDidActiveGroupChange = new Emitter();
7527
8111
  this.onDidActiveGroupChange = this._onDidActiveGroupChange.event;
7528
8112
  this._moving = false;
8113
+ this.popupService = new PopupService(this.element);
8114
+ this.updateDropTargetModel(options);
8115
+ this._themeClassnames = new Classnames(this.element);
8116
+ this.rootDropTargetContainer = new DropTargetAnchorContainer(this.element, { disabled: true });
7529
8117
  this.overlayRenderContainer = new OverlayRenderContainer(this.gridview.element, this);
7530
8118
  toggleClass(this.gridview.element, 'dv-dockview', true);
7531
8119
  toggleClass(this.element, 'dv-debug', !!options.debug);
7532
8120
  if (options.debug) {
7533
8121
  this.addDisposables(new StrictEventsSequencing(this));
7534
8122
  }
7535
- this.addDisposables(this.overlayRenderContainer, this._onWillDragPanel, this._onWillDragGroup, this._onWillShowOverlay, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, this._onWillDrop, this._onDidMovePanel, this._onDidAddGroup, this._onDidRemoveGroup, this._onDidActiveGroupChange, this._onUnhandledDragOverEvent, this._onDidMaximizedGroupChange, this.onDidViewVisibilityChangeMicroTaskQueue(() => {
8123
+ this.addDisposables(this.rootDropTargetContainer, this.overlayRenderContainer, this._onWillDragPanel, this._onWillDragGroup, this._onWillShowOverlay, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, this._onWillDrop, this._onDidMovePanel, this._onDidAddGroup, this._onDidRemoveGroup, this._onDidActiveGroupChange, this._onUnhandledDragOverEvent, this._onDidMaximizedGroupChange, this._onDidOptionsChange, this.onDidViewVisibilityChangeMicroTaskQueue(() => {
7536
8124
  this.updateWatermark();
7537
8125
  }), this.onDidAdd((event) => {
7538
8126
  if (!this._moving) {
@@ -7566,7 +8154,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
7566
8154
  }
7567
8155
  }));
7568
8156
  this._options = options;
8157
+ this.updateTheme();
7569
8158
  this._rootDropTarget = new Droptarget(this.element, {
8159
+ className: 'dv-drop-target-edge',
7570
8160
  canDisplayOverlay: (event, position) => {
7571
8161
  const data = getPanelData();
7572
8162
  if (data) {
@@ -7593,7 +8183,8 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
7593
8183
  return firedEvent.isAccepted;
7594
8184
  },
7595
8185
  acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
7596
- overlayModel: (_a = this.options.rootOverlayModel) !== null && _a !== void 0 ? _a : DEFAULT_ROOT_OVERLAY_MODEL,
8186
+ overlayModel: (_c = this.options.rootOverlayModel) !== null && _c !== void 0 ? _c : DEFAULT_ROOT_OVERLAY_MODEL,
8187
+ getOverrideTarget: () => { var _a; return (_a = this.rootDropTargetContainer) === null || _a === void 0 ? void 0 : _a.model; },
7597
8188
  });
7598
8189
  this.addDisposables(this._rootDropTarget, this._rootDropTarget.onWillShowOverlay((event) => {
7599
8190
  if (this.gridview.length > 0 && event.position === 'center') {
@@ -7771,6 +8362,10 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
7771
8362
  popoutContainer.style.overflow = 'hidden';
7772
8363
  popoutContainer.appendChild(gready);
7773
8364
  popoutContainer.appendChild(group.element);
8365
+ const anchor = document.createElement('div');
8366
+ const dropTargetContainer = new DropTargetAnchorContainer(anchor, { disabled: this.rootDropTargetContainer.disabled });
8367
+ popoutContainer.appendChild(anchor);
8368
+ group.model.dropTargetContainer = dropTargetContainer;
7774
8369
  group.model.location = {
7775
8370
  type: 'popout',
7776
8371
  getWindow: () => _window.window,
@@ -7837,6 +8432,8 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
7837
8432
  else if (this.getPanel(group.id)) {
7838
8433
  group.model.renderContainer =
7839
8434
  this.overlayRenderContainer;
8435
+ group.model.dropTargetContainer =
8436
+ this.rootDropTargetContainer;
7840
8437
  returnedGroup = group;
7841
8438
  const alreadyRemoved = !this._popoutGroups.find((p) => p.popoutGroup === group);
7842
8439
  if (alreadyRemoved) {
@@ -8057,7 +8654,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
8057
8654
  }
8058
8655
  }
8059
8656
  updateOptions(options) {
8060
- var _a, _b, _c, _d;
8657
+ var _a, _b;
8061
8658
  super.updateOptions(options);
8062
8659
  if ('floatingGroupBounds' in options) {
8063
8660
  for (const group of this._floatingGroups) {
@@ -8081,13 +8678,11 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
8081
8678
  group.overlay.setBounds();
8082
8679
  }
8083
8680
  }
8084
- if ('rootOverlayModel' in options) {
8085
- this._rootDropTarget.setOverlayModel((_c = options.rootOverlayModel) !== null && _c !== void 0 ? _c : DEFAULT_ROOT_OVERLAY_MODEL);
8086
- }
8087
- if ('gap' in options) {
8088
- this.gridview.margin = (_d = options.gap) !== null && _d !== void 0 ? _d : 0;
8089
- }
8681
+ this.updateDropTargetModel(options);
8090
8682
  this._options = Object.assign(Object.assign({}, this.options), options);
8683
+ if ('theme' in options) {
8684
+ this.updateTheme();
8685
+ }
8091
8686
  this.layout(this.gridview.width, this.gridview.height, true);
8092
8687
  }
8093
8688
  layout(width, height, forceResize) {
@@ -8505,22 +9100,22 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
8505
9100
  updateWatermark() {
8506
9101
  var _a, _b;
8507
9102
  if (this.groups.filter((x) => x.api.location.type === 'grid' && x.api.isVisible).length === 0) {
8508
- if (!this.watermark) {
8509
- this.watermark = this.createWatermarkComponent();
8510
- this.watermark.init({
9103
+ if (!this._watermark) {
9104
+ this._watermark = this.createWatermarkComponent();
9105
+ this._watermark.init({
8511
9106
  containerApi: new DockviewApi(this),
8512
9107
  });
8513
9108
  const watermarkContainer = document.createElement('div');
8514
9109
  watermarkContainer.className = 'dv-watermark-container';
8515
9110
  addTestId(watermarkContainer, 'watermark-component');
8516
- watermarkContainer.appendChild(this.watermark.element);
9111
+ watermarkContainer.appendChild(this._watermark.element);
8517
9112
  this.gridview.element.appendChild(watermarkContainer);
8518
9113
  }
8519
9114
  }
8520
- else if (this.watermark) {
8521
- this.watermark.element.parentElement.remove();
8522
- (_b = (_a = this.watermark).dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
8523
- this.watermark = null;
9115
+ else if (this._watermark) {
9116
+ this._watermark.element.parentElement.remove();
9117
+ (_b = (_a = this._watermark).dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
9118
+ this._watermark = null;
8524
9119
  }
8525
9120
  }
8526
9121
  addGroup(options) {
@@ -9006,6 +9601,38 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9006
9601
  ? rootOrientation
9007
9602
  : orthogonal(rootOrientation);
9008
9603
  }
9604
+ updateDropTargetModel(options) {
9605
+ if ('dndEdges' in options) {
9606
+ this._rootDropTarget.disabled =
9607
+ typeof options.dndEdges === 'boolean' &&
9608
+ options.dndEdges === false;
9609
+ if (typeof options.dndEdges === 'object' &&
9610
+ options.dndEdges !== null) {
9611
+ this._rootDropTarget.setOverlayModel(options.dndEdges);
9612
+ }
9613
+ else {
9614
+ this._rootDropTarget.setOverlayModel(DEFAULT_ROOT_OVERLAY_MODEL);
9615
+ }
9616
+ }
9617
+ if ('rootOverlayModel' in options) {
9618
+ this.updateDropTargetModel({ dndEdges: options.dndEdges });
9619
+ }
9620
+ }
9621
+ updateTheme() {
9622
+ var _a, _b;
9623
+ const theme = (_a = this._options.theme) !== null && _a !== void 0 ? _a : themeAbyss;
9624
+ this._themeClassnames.setClassNames(theme.className);
9625
+ this.gridview.margin = (_b = theme.gap) !== null && _b !== void 0 ? _b : 0;
9626
+ switch (theme.dndOverlayMounting) {
9627
+ case 'absolute':
9628
+ this.rootDropTargetContainer.disabled = false;
9629
+ break;
9630
+ case 'relative':
9631
+ default:
9632
+ this.rootDropTargetContainer.disabled = true;
9633
+ break;
9634
+ }
9635
+ }
9009
9636
  }
9010
9637
 
9011
9638
  class GridviewComponent extends BaseGrid {
@@ -9529,6 +10156,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9529
10156
  for (const view of views) {
9530
10157
  view.dispose();
9531
10158
  }
10159
+ this.element.remove();
9532
10160
  super.dispose();
9533
10161
  }
9534
10162
  }
@@ -9869,6 +10497,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
9869
10497
  value.dispose();
9870
10498
  }
9871
10499
  this._viewDisposables.clear();
10500
+ this.element.remove();
9872
10501
  this.paneview.dispose();
9873
10502
  }
9874
10503
  }
@@ -10186,6 +10815,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
10186
10815
  params: parameters.params,
10187
10816
  api: parameters.api,
10188
10817
  containerApi: parameters.containerApi,
10818
+ tabLocation: parameters.tabLocation,
10189
10819
  });
10190
10820
  }
10191
10821
  update(event) {
@@ -10491,7 +11121,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
10491
11121
  });
10492
11122
  DockviewReact.displayName = 'DockviewComponent';
10493
11123
 
10494
- const CloseButton = () => (React.createElement("svg", { height: "11", width: "11", viewBox: "0 0 28 28", "aria-hidden": 'false', focusable: false, className: "dockview-svg" },
11124
+ const CloseButton = () => (React.createElement("svg", { height: "11", width: "11", viewBox: "0 0 28 28", "aria-hidden": 'false', focusable: false, className: "dv-svg" },
10495
11125
  React.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" })));
10496
11126
 
10497
11127
  var __rest = (undefined && undefined.__rest) || function (s, e) {
@@ -10518,7 +11148,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
10518
11148
  return title;
10519
11149
  }
10520
11150
  const DockviewDefaultTab = (_a) => {
10521
- var { api, containerApi: _containerApi, params: _params, hideClose, closeActionOverride, onPointerDown, onPointerUp, onPointerLeave } = _a, rest = __rest(_a, ["api", "containerApi", "params", "hideClose", "closeActionOverride", "onPointerDown", "onPointerUp", "onPointerLeave"]);
11151
+ var { api, containerApi: _containerApi, params: _params, hideClose, closeActionOverride, onPointerDown, onPointerUp, onPointerLeave, tabLocation } = _a, rest = __rest(_a, ["api", "containerApi", "params", "hideClose", "closeActionOverride", "onPointerDown", "onPointerUp", "onPointerLeave", "tabLocation"]);
10522
11152
  const title = useTitle(api);
10523
11153
  const isMiddleMouseButton = React.useRef(false);
10524
11154
  const onClose = React.useCallback((event) => {
@@ -10550,7 +11180,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
10550
11180
  }, [onPointerLeave]);
10551
11181
  return (React.createElement("div", Object.assign({ "data-testid": "dockview-dv-default-tab" }, rest, { onPointerDown: _onPointerDown, onPointerUp: _onPointerUp, onPointerLeave: _onPointerLeave, className: "dv-default-tab" }),
10552
11182
  React.createElement("span", { className: "dv-default-tab-content" }, title),
10553
- !hideClose && (React.createElement("div", { className: "dv-default-tab-action", onPointerDown: onBtnPointerDown, onClick: onClose },
11183
+ !hideClose && tabLocation !== 'headerOverflow' && (React.createElement("div", { className: "dv-default-tab-action", onPointerDown: onBtnPointerDown, onClick: onClose },
10554
11184
  React.createElement(CloseButton, null)))));
10555
11185
  };
10556
11186
 
@@ -10915,6 +11545,14 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
10915
11545
  exports.isReactComponent = isReactComponent;
10916
11546
  exports.orthogonal = orthogonal;
10917
11547
  exports.positionToDirection = positionToDirection;
11548
+ exports.themeAbyss = themeAbyss;
11549
+ exports.themeAbyssSpaced = themeAbyssSpaced;
11550
+ exports.themeDark = themeDark;
11551
+ exports.themeDracula = themeDracula;
11552
+ exports.themeLight = themeLight;
11553
+ exports.themeLightSpaced = themeLightSpaced;
11554
+ exports.themeReplit = themeReplit;
11555
+ exports.themeVisualStudio = themeVisualStudio;
10918
11556
  exports.toTarget = toTarget;
10919
11557
  exports.usePortalsLifecycle = usePortalsLifecycle;
10920
11558