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
  */
@@ -339,6 +339,20 @@
339
339
  }
340
340
  }
341
341
 
342
+ class OverflowObserver extends CompositeDisposable {
343
+ constructor(el) {
344
+ super();
345
+ this._onDidChange = new Emitter();
346
+ this.onDidChange = this._onDidChange.event;
347
+ this._value = null;
348
+ this.addDisposables(this._onDidChange, watchElementResize(el, (entry) => {
349
+ const hasScrollX = entry.target.scrollWidth > entry.target.clientWidth;
350
+ const hasScrollY = entry.target.scrollHeight > entry.target.clientHeight;
351
+ this._value = { hasScrollX, hasScrollY };
352
+ this._onDidChange.fire(this._value);
353
+ }));
354
+ }
355
+ }
342
356
  function watchElementResize(element, cb) {
343
357
  const observer = new ResizeObserver((entires) => {
344
358
  /**
@@ -577,6 +591,19 @@
577
591
  }
578
592
  }
579
593
  }
594
+ function isChildEntirelyVisibleWithinParent(child, parent) {
595
+ //
596
+ const childPosition = getDomNodePagePosition(child);
597
+ const parentPosition = getDomNodePagePosition(parent);
598
+ if (childPosition.left < parentPosition.left) {
599
+ return false;
600
+ }
601
+ if (childPosition.left + childPosition.width >
602
+ parentPosition.left + parentPosition.width) {
603
+ return false;
604
+ }
605
+ return true;
606
+ }
580
607
 
581
608
  function tail(arr) {
582
609
  if (arr.length === 0) {
@@ -584,9 +611,6 @@
584
611
  }
585
612
  return [arr.slice(0, arr.length - 1), arr[arr.length - 1]];
586
613
  }
587
- function last(arr) {
588
- return arr.length > 0 ? arr[arr.length - 1] : undefined;
589
- }
590
614
  function sequenceEquals(arr1, arr2) {
591
615
  if (arr1.length !== arr2.length) {
592
616
  return false;
@@ -852,6 +876,7 @@
852
876
  }
853
877
  set margin(value) {
854
878
  this._margin = value;
879
+ toggleClass(this.element, 'dv-splitview-has-margin', value !== 0);
855
880
  }
856
881
  constructor(container, options) {
857
882
  var _a, _b;
@@ -3423,9 +3448,6 @@
3423
3448
  get totalPanels() {
3424
3449
  return this.component.totalPanels;
3425
3450
  }
3426
- get gap() {
3427
- return this.component.gap;
3428
- }
3429
3451
  /**
3430
3452
  * Invoked when the active group changes. May be undefined if no group is active.
3431
3453
  */
@@ -3656,9 +3678,6 @@
3656
3678
  addPopoutGroup(item, options) {
3657
3679
  return this.component.addPopoutGroup(item, options);
3658
3680
  }
3659
- setGap(gap) {
3660
- this.component.updateOptions({ gap });
3661
- }
3662
3681
  updateOptions(options) {
3663
3682
  this.component.updateOptions(options);
3664
3683
  }
@@ -3711,14 +3730,16 @@
3711
3730
  * For example: in react-dnd if dataTransfer.types is not set then the dragStart event will be cancelled
3712
3731
  * through .preventDefault(). Since this is applied globally to all drag events this would break dockviews
3713
3732
  * dnd logic. You can see the code at
3714
- * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
3733
+ P * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
3715
3734
  */
3716
3735
  event.dataTransfer.setData('text/plain', '');
3717
3736
  }
3718
3737
  }
3719
3738
  }), addDisposableListener(this.el, 'dragend', () => {
3720
3739
  this.pointerEventsDisposable.dispose();
3721
- this.dataDisposable.dispose();
3740
+ setTimeout(() => {
3741
+ this.dataDisposable.dispose(); // allow the data to be read by other handlers before disposing
3742
+ }, 0);
3722
3743
  }));
3723
3744
  }
3724
3745
  }
@@ -3828,6 +3849,12 @@
3828
3849
  const SMALL_WIDTH_BOUNDARY = 100;
3829
3850
  const SMALL_HEIGHT_BOUNDARY = 100;
3830
3851
  class Droptarget extends CompositeDisposable {
3852
+ get disabled() {
3853
+ return this._disabled;
3854
+ }
3855
+ set disabled(value) {
3856
+ this._disabled = value;
3857
+ }
3831
3858
  get state() {
3832
3859
  return this._state;
3833
3860
  }
@@ -3839,23 +3866,34 @@
3839
3866
  this.onDrop = this._onDrop.event;
3840
3867
  this._onWillShowOverlay = new Emitter();
3841
3868
  this.onWillShowOverlay = this._onWillShowOverlay.event;
3869
+ this._disabled = false;
3842
3870
  // use a set to take advantage of #<set>.has
3843
3871
  this._acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
3844
3872
  this.dnd = new DragAndDropObserver(this.element, {
3845
- onDragEnter: () => undefined,
3873
+ onDragEnter: () => {
3874
+ var _a, _b, _c;
3875
+ (_c = (_b = (_a = this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a)) === null || _c === void 0 ? void 0 : _c.getElements();
3876
+ },
3846
3877
  onDragOver: (e) => {
3878
+ var _a, _b, _c, _d, _e, _f, _g;
3879
+ Droptarget.ACTUAL_TARGET = this;
3880
+ const overrideTraget = (_b = (_a = this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a);
3847
3881
  if (this._acceptedTargetZonesSet.size === 0) {
3882
+ if (overrideTraget) {
3883
+ return;
3884
+ }
3848
3885
  this.removeDropTarget();
3849
3886
  return;
3850
3887
  }
3851
- const width = this.element.clientWidth;
3852
- const height = this.element.clientHeight;
3888
+ const target = (_e = (_d = (_c = this.options).getOverlayOutline) === null || _d === void 0 ? void 0 : _d.call(_c)) !== null && _e !== void 0 ? _e : this.element;
3889
+ const width = target.offsetWidth;
3890
+ const height = target.offsetHeight;
3853
3891
  if (width === 0 || height === 0) {
3854
3892
  return; // avoid div!0
3855
3893
  }
3856
3894
  const rect = e.currentTarget.getBoundingClientRect();
3857
- const x = e.clientX - rect.left;
3858
- const y = e.clientY - rect.top;
3895
+ const x = ((_f = e.clientX) !== null && _f !== void 0 ? _f : 0) - rect.left;
3896
+ const y = ((_g = e.clientY) !== null && _g !== void 0 ? _g : 0) - rect.top;
3859
3897
  const quadrant = this.calculateQuadrant(this._acceptedTargetZonesSet, x, y, width, height);
3860
3898
  /**
3861
3899
  * If the event has already been used by another DropTarget instance
@@ -3868,6 +3906,9 @@
3868
3906
  return;
3869
3907
  }
3870
3908
  if (!this.options.canDisplayOverlay(e, quadrant)) {
3909
+ if (overrideTraget) {
3910
+ return;
3911
+ }
3871
3912
  this.removeDropTarget();
3872
3913
  return;
3873
3914
  }
@@ -3885,29 +3926,57 @@
3885
3926
  return;
3886
3927
  }
3887
3928
  this.markAsUsed(e);
3888
- if (!this.targetElement) {
3929
+ if (overrideTraget) ;
3930
+ else if (!this.targetElement) {
3889
3931
  this.targetElement = document.createElement('div');
3890
3932
  this.targetElement.className = 'dv-drop-target-dropzone';
3891
3933
  this.overlayElement = document.createElement('div');
3892
3934
  this.overlayElement.className = 'dv-drop-target-selection';
3893
3935
  this._state = 'center';
3894
3936
  this.targetElement.appendChild(this.overlayElement);
3895
- this.element.classList.add('dv-drop-target');
3896
- this.element.append(this.targetElement);
3937
+ target.classList.add('dv-drop-target');
3938
+ target.append(this.targetElement);
3939
+ // this.overlayElement.style.opacity = '0';
3940
+ // requestAnimationFrame(() => {
3941
+ // if (this.overlayElement) {
3942
+ // this.overlayElement.style.opacity = '';
3943
+ // }
3944
+ // });
3897
3945
  }
3898
3946
  this.toggleClasses(quadrant, width, height);
3899
3947
  this._state = quadrant;
3900
3948
  },
3901
3949
  onDragLeave: () => {
3950
+ var _a, _b;
3951
+ const target = (_b = (_a = this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a);
3952
+ if (target) {
3953
+ return;
3954
+ }
3902
3955
  this.removeDropTarget();
3903
3956
  },
3904
- onDragEnd: () => {
3957
+ onDragEnd: (e) => {
3958
+ var _a, _b;
3959
+ const target = (_b = (_a = this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a);
3960
+ if (target && Droptarget.ACTUAL_TARGET === this) {
3961
+ if (this._state) {
3962
+ // only stop the propagation of the event if we are dealing with it
3963
+ // which is only when the target has state
3964
+ e.stopPropagation();
3965
+ this._onDrop.fire({
3966
+ position: this._state,
3967
+ nativeEvent: e,
3968
+ });
3969
+ }
3970
+ }
3905
3971
  this.removeDropTarget();
3972
+ target === null || target === void 0 ? void 0 : target.clear();
3906
3973
  },
3907
3974
  onDrop: (e) => {
3975
+ var _a, _b, _c;
3908
3976
  e.preventDefault();
3909
3977
  const state = this._state;
3910
3978
  this.removeDropTarget();
3979
+ (_c = (_b = (_a = this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a)) === null || _c === void 0 ? void 0 : _c.clear();
3911
3980
  if (state) {
3912
3981
  // only stop the propagation of the event if we are dealing with it
3913
3982
  // which is only when the target has state
@@ -3942,8 +4011,9 @@
3942
4011
  return typeof value === 'boolean' && value;
3943
4012
  }
3944
4013
  toggleClasses(quadrant, width, height) {
3945
- var _a, _b;
3946
- if (!this.overlayElement) {
4014
+ var _a, _b, _c, _d, _e, _f, _g;
4015
+ const target = (_b = (_a = this.options).getOverrideTarget) === null || _b === void 0 ? void 0 : _b.call(_a);
4016
+ if (!target && !this.overlayElement) {
3947
4017
  return;
3948
4018
  }
3949
4019
  const isSmallX = width < SMALL_WIDTH_BOUNDARY;
@@ -3957,7 +4027,7 @@
3957
4027
  const topClass = !isSmallY && isTop;
3958
4028
  const bottomClass = !isSmallY && isBottom;
3959
4029
  let size = 1;
3960
- const sizeOptions = (_b = (_a = this.options.overlayModel) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : DEFAULT_SIZE;
4030
+ const sizeOptions = (_d = (_c = this.options.overlayModel) === null || _c === void 0 ? void 0 : _c.size) !== null && _d !== void 0 ? _d : DEFAULT_SIZE;
3961
4031
  if (sizeOptions.type === 'percentage') {
3962
4032
  size = clamp(sizeOptions.value, 0, 100) / 100;
3963
4033
  }
@@ -3969,6 +4039,74 @@
3969
4039
  size = clamp(0, sizeOptions.value, height) / height;
3970
4040
  }
3971
4041
  }
4042
+ if (target) {
4043
+ const outlineEl = (_g = (_f = (_e = this.options).getOverlayOutline) === null || _f === void 0 ? void 0 : _f.call(_e)) !== null && _g !== void 0 ? _g : this.element;
4044
+ const elBox = outlineEl.getBoundingClientRect();
4045
+ const ta = target.getElements(undefined, outlineEl);
4046
+ const el = ta.root;
4047
+ const overlay = ta.overlay;
4048
+ const bigbox = el.getBoundingClientRect();
4049
+ const rootTop = elBox.top - bigbox.top;
4050
+ const rootLeft = elBox.left - bigbox.left;
4051
+ const box = {
4052
+ top: rootTop,
4053
+ left: rootLeft,
4054
+ width: width,
4055
+ height: height,
4056
+ };
4057
+ if (rightClass) {
4058
+ box.left = rootLeft + width * (1 - size);
4059
+ box.width = width * size;
4060
+ }
4061
+ else if (leftClass) {
4062
+ box.width = width * size;
4063
+ }
4064
+ else if (topClass) {
4065
+ box.height = height * size;
4066
+ }
4067
+ else if (bottomClass) {
4068
+ box.top = rootTop + height * (1 - size);
4069
+ box.height = height * size;
4070
+ }
4071
+ if (isSmallX && isLeft) {
4072
+ box.width = 4;
4073
+ }
4074
+ if (isSmallX && isRight) {
4075
+ box.left = rootLeft + width - 4;
4076
+ box.width = 4;
4077
+ }
4078
+ const topPx = `${Math.round(box.top)}px`;
4079
+ const leftPx = `${Math.round(box.left)}px`;
4080
+ const widthPx = `${Math.round(box.width)}px`;
4081
+ const heightPx = `${Math.round(box.height)}px`;
4082
+ if (overlay.style.top === topPx &&
4083
+ overlay.style.left === leftPx &&
4084
+ overlay.style.width === widthPx &&
4085
+ overlay.style.height === heightPx) {
4086
+ return;
4087
+ }
4088
+ overlay.style.top = topPx;
4089
+ overlay.style.left = leftPx;
4090
+ overlay.style.width = widthPx;
4091
+ overlay.style.height = heightPx;
4092
+ overlay.style.visibility = 'visible';
4093
+ overlay.className = `dv-drop-target-anchor${this.options.className ? ` ${this.options.className}` : ''}`;
4094
+ toggleClass(overlay, 'dv-drop-target-left', isLeft);
4095
+ toggleClass(overlay, 'dv-drop-target-right', isRight);
4096
+ toggleClass(overlay, 'dv-drop-target-top', isTop);
4097
+ toggleClass(overlay, 'dv-drop-target-bottom', isBottom);
4098
+ toggleClass(overlay, 'dv-drop-target-center', quadrant === 'center');
4099
+ if (ta.changed) {
4100
+ toggleClass(overlay, 'dv-drop-target-anchor-container-changed', true);
4101
+ setTimeout(() => {
4102
+ toggleClass(overlay, 'dv-drop-target-anchor-container-changed', false);
4103
+ }, 10);
4104
+ }
4105
+ return;
4106
+ }
4107
+ if (!this.overlayElement) {
4108
+ return;
4109
+ }
3972
4110
  const box = { top: '0px', left: '0px', width: '100%', height: '100%' };
3973
4111
  /**
3974
4112
  * You can also achieve the overlay placement using the transform CSS property
@@ -4025,12 +4163,13 @@
4025
4163
  return calculateQuadrantAsPixels(overlayType, x, y, width, height, activationSizeOptions.value);
4026
4164
  }
4027
4165
  removeDropTarget() {
4166
+ var _a;
4028
4167
  if (this.targetElement) {
4029
4168
  this._state = undefined;
4030
- this.element.removeChild(this.targetElement);
4169
+ (_a = this.targetElement.parentElement) === null || _a === void 0 ? void 0 : _a.classList.remove('dv-drop-target');
4170
+ this.targetElement.remove();
4031
4171
  this.targetElement = undefined;
4032
4172
  this.overlayElement = undefined;
4033
- this.element.classList.remove('dv-drop-target');
4034
4173
  }
4035
4174
  }
4036
4175
  }
@@ -4615,7 +4754,15 @@
4615
4754
  this._element.className = 'dv-content-container';
4616
4755
  this._element.tabIndex = -1;
4617
4756
  this.addDisposables(this._onDidFocus, this._onDidBlur);
4757
+ const target = group.dropTargetContainer;
4618
4758
  this.dropTarget = new Droptarget(this.element, {
4759
+ getOverlayOutline: () => {
4760
+ var _a;
4761
+ return ((_a = accessor.options.theme) === null || _a === void 0 ? void 0 : _a.dndPanelOverlay) === 'group'
4762
+ ? this.element.parentElement
4763
+ : null;
4764
+ },
4765
+ className: 'dv-drop-target-content',
4619
4766
  acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
4620
4767
  canDisplayOverlay: (event, position) => {
4621
4768
  if (this.group.locked === 'no-drop-target' ||
@@ -4629,22 +4776,11 @@
4629
4776
  return false;
4630
4777
  }
4631
4778
  if (data && data.viewId === this.accessor.id) {
4632
- if (data.groupId === this.group.id) {
4633
- if (position === 'center') {
4634
- // don't allow to drop on self for center position
4635
- return false;
4636
- }
4637
- if (data.panelId === null) {
4638
- // don't allow group move to drop anywhere on self
4639
- return false;
4640
- }
4641
- }
4642
- const groupHasOnePanelAndIsActiveDragElement = this.group.panels.length === 1 &&
4643
- data.groupId === this.group.id;
4644
- return !groupHasOnePanelAndIsActiveDragElement;
4779
+ return true;
4645
4780
  }
4646
4781
  return this.group.canDisplayOverlay(event, position, 'content');
4647
4782
  },
4783
+ getOverrideTarget: target ? () => target.model : undefined,
4648
4784
  });
4649
4785
  this.addDisposables(this.dropTarget);
4650
4786
  }
@@ -4719,6 +4855,18 @@
4719
4855
  }
4720
4856
  }
4721
4857
 
4858
+ function addGhostImage(dataTransfer, ghostElement, options) {
4859
+ var _a, _b;
4860
+ // class dockview provides to force ghost image to be drawn on a different layer and prevent weird rendering issues
4861
+ addClasses(ghostElement, 'dv-dragged');
4862
+ document.body.appendChild(ghostElement);
4863
+ 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);
4864
+ setTimeout(() => {
4865
+ removeClasses(ghostElement, 'dv-dragged');
4866
+ ghostElement.remove();
4867
+ }, 0);
4868
+ }
4869
+
4722
4870
  class TabDragHandler extends DragHandler {
4723
4871
  constructor(element, accessor, group, panel) {
4724
4872
  super(element);
@@ -4759,25 +4907,32 @@
4759
4907
  toggleClass(this.element, 'dv-inactive-tab', true);
4760
4908
  const dragHandler = new TabDragHandler(this._element, this.accessor, this.group, this.panel);
4761
4909
  this.dropTarget = new Droptarget(this._element, {
4762
- acceptedTargetZones: ['center'],
4910
+ acceptedTargetZones: ['left', 'right'],
4911
+ overlayModel: { activationSize: { value: 50, type: 'percentage' } },
4763
4912
  canDisplayOverlay: (event, position) => {
4764
4913
  if (this.group.locked) {
4765
4914
  return false;
4766
4915
  }
4767
4916
  const data = getPanelData();
4768
4917
  if (data && this.accessor.id === data.viewId) {
4769
- if (data.panelId === null &&
4770
- data.groupId === this.group.id) {
4771
- // don't allow group move to drop on self
4772
- return false;
4773
- }
4774
- return this.panel.id !== data.panelId;
4918
+ return true;
4775
4919
  }
4776
4920
  return this.group.model.canDisplayOverlay(event, position, 'tab');
4777
4921
  },
4922
+ getOverrideTarget: () => { var _a; return (_a = group.model.dropTargetContainer) === null || _a === void 0 ? void 0 : _a.model; },
4778
4923
  });
4779
4924
  this.onWillShowOverlay = this.dropTarget.onWillShowOverlay;
4780
4925
  this.addDisposables(this._onPointDown, this._onDropped, this._onDragStart, dragHandler.onDragStart((event) => {
4926
+ if (event.dataTransfer) {
4927
+ const style = getComputedStyle(this.element);
4928
+ const newNode = this.element.cloneNode(true);
4929
+ Array.from(style).forEach((key) => newNode.style.setProperty(key, style.getPropertyValue(key), style.getPropertyPriority(key)));
4930
+ newNode.style.position = 'absolute';
4931
+ addGhostImage(event.dataTransfer, newNode, {
4932
+ y: -10,
4933
+ x: 30,
4934
+ });
4935
+ }
4781
4936
  this._onDragStart.fire(event);
4782
4937
  }), dragHandler, addDisposableListener(this._element, 'pointerdown', (event) => {
4783
4938
  this._onPointDown.fire(event);
@@ -4801,17 +4956,6 @@
4801
4956
  }
4802
4957
  }
4803
4958
 
4804
- function addGhostImage(dataTransfer, ghostElement) {
4805
- // class dockview provides to force ghost image to be drawn on a different layer and prevent weird rendering issues
4806
- addClasses(ghostElement, 'dv-dragged');
4807
- document.body.appendChild(ghostElement);
4808
- dataTransfer.setDragImage(ghostElement, 0, 0);
4809
- setTimeout(() => {
4810
- removeClasses(ghostElement, 'dv-dragged');
4811
- ghostElement.remove();
4812
- }, 0);
4813
- }
4814
-
4815
4959
  class GroupDragHandler extends DragHandler {
4816
4960
  constructor(element, accessor, group) {
4817
4961
  super(element);
@@ -4851,8 +4995,10 @@
4851
4995
  ghostElement.style.lineHeight = '20px';
4852
4996
  ghostElement.style.borderRadius = '12px';
4853
4997
  ghostElement.style.position = 'absolute';
4998
+ ghostElement.style.pointerEvents = 'none';
4999
+ ghostElement.style.top = '-9999px';
4854
5000
  ghostElement.textContent = `Multiple Panels (${this.group.size})`;
4855
- addGhostImage(dataTransfer, ghostElement);
5001
+ addGhostImage(dataTransfer, ghostElement, { y: -10, x: 30 });
4856
5002
  }
4857
5003
  return {
4858
5004
  dispose: () => {
@@ -4884,19 +5030,13 @@
4884
5030
  this.dropTraget = new Droptarget(this._element, {
4885
5031
  acceptedTargetZones: ['center'],
4886
5032
  canDisplayOverlay: (event, position) => {
4887
- var _a;
4888
5033
  const data = getPanelData();
4889
5034
  if (data && this.accessor.id === data.viewId) {
4890
- if (data.panelId === null &&
4891
- data.groupId === this.group.id) {
4892
- // don't allow group move to drop on self
4893
- return false;
4894
- }
4895
- // don't show the overlay if the tab being dragged is the last panel of this group
4896
- return ((_a = last(this.group.panels)) === null || _a === void 0 ? void 0 : _a.id) !== data.panelId;
5035
+ return true;
4897
5036
  }
4898
5037
  return group.model.canDisplayOverlay(event, position, 'header_space');
4899
5038
  },
5039
+ getOverrideTarget: () => { var _a; return (_a = group.model.dropTargetContainer) === null || _a === void 0 ? void 0 : _a.model; },
4900
5040
  });
4901
5041
  this.onWillShowOverlay = this.dropTraget.onWillShowOverlay;
4902
5042
  this.addDisposables(handler, handler.onDragStart((event) => {
@@ -4907,88 +5047,338 @@
4907
5047
  }
4908
5048
  }
4909
5049
 
4910
- class TabsContainer extends CompositeDisposable {
4911
- get panels() {
4912
- return this.tabs.map((_) => _.value.panel.id);
4913
- }
4914
- get size() {
4915
- return this.tabs.length;
4916
- }
4917
- get hidden() {
4918
- return this._hidden;
5050
+ class Scrollbar extends CompositeDisposable {
5051
+ get element() {
5052
+ return this._element;
4919
5053
  }
4920
- set hidden(value) {
4921
- this._hidden = value;
4922
- this.element.style.display = value ? 'none' : '';
5054
+ constructor(scrollableElement) {
5055
+ super();
5056
+ this.scrollableElement = scrollableElement;
5057
+ this._scrollLeft = 0;
5058
+ this._element = document.createElement('div');
5059
+ this._element.className = 'dv-scrollable';
5060
+ this._horizontalScrollbar = document.createElement('div');
5061
+ this._horizontalScrollbar.className = 'dv-scrollbar-horizontal';
5062
+ this.element.appendChild(scrollableElement);
5063
+ this.element.appendChild(this._horizontalScrollbar);
5064
+ this.addDisposables(addDisposableListener(this.element, 'wheel', (event) => {
5065
+ this._scrollLeft += event.deltaY * Scrollbar.MouseWheelSpeed;
5066
+ this.calculateScrollbarStyles();
5067
+ }), addDisposableListener(this._horizontalScrollbar, 'pointerdown', (event) => {
5068
+ event.preventDefault();
5069
+ toggleClass(this.element, 'dv-scrollable-scrolling', true);
5070
+ const originalClientX = event.clientX;
5071
+ const originalScrollLeft = this._scrollLeft;
5072
+ const onPointerMove = (event) => {
5073
+ const deltaX = event.clientX - originalClientX;
5074
+ const { clientWidth } = this.element;
5075
+ const { scrollWidth } = this.scrollableElement;
5076
+ const p = clientWidth / scrollWidth;
5077
+ this._scrollLeft = originalScrollLeft + deltaX / p;
5078
+ this.calculateScrollbarStyles();
5079
+ };
5080
+ const onEnd = () => {
5081
+ toggleClass(this.element, 'dv-scrollable-scrolling', false);
5082
+ document.removeEventListener('pointermove', onPointerMove);
5083
+ document.removeEventListener('pointerup', onEnd);
5084
+ document.removeEventListener('pointercancel', onEnd);
5085
+ };
5086
+ document.addEventListener('pointermove', onPointerMove);
5087
+ document.addEventListener('pointerup', onEnd);
5088
+ document.addEventListener('pointercancel', onEnd);
5089
+ }), addDisposableListener(this.element, 'scroll', () => {
5090
+ this.calculateScrollbarStyles();
5091
+ }), addDisposableListener(this.scrollableElement, 'scroll', () => {
5092
+ this._scrollLeft = this.scrollableElement.scrollLeft;
5093
+ this.calculateScrollbarStyles();
5094
+ }), watchElementResize(this.element, () => {
5095
+ toggleClass(this.element, 'dv-scrollable-resizing', true);
5096
+ if (this._animationTimer) {
5097
+ clearTimeout(this._animationTimer);
5098
+ }
5099
+ this._animationTimer = setTimeout(() => {
5100
+ clearTimeout(this._animationTimer);
5101
+ toggleClass(this.element, 'dv-scrollable-resizing', false);
5102
+ }, 500);
5103
+ this.calculateScrollbarStyles();
5104
+ }));
4923
5105
  }
4924
- show() {
4925
- if (!this.hidden) {
4926
- this.element.style.display = '';
5106
+ calculateScrollbarStyles() {
5107
+ const { clientWidth } = this.element;
5108
+ const { scrollWidth } = this.scrollableElement;
5109
+ const hasScrollbar = scrollWidth > clientWidth;
5110
+ if (hasScrollbar) {
5111
+ const px = clientWidth * (clientWidth / scrollWidth);
5112
+ this._horizontalScrollbar.style.width = `${px}px`;
5113
+ this._scrollLeft = clamp(this._scrollLeft, 0, this.scrollableElement.scrollWidth - clientWidth);
5114
+ this.scrollableElement.scrollLeft = this._scrollLeft;
5115
+ const percentageComplete = this._scrollLeft / (scrollWidth - clientWidth);
5116
+ this._horizontalScrollbar.style.left = `${(clientWidth - px) * percentageComplete}px`;
5117
+ }
5118
+ else {
5119
+ this._horizontalScrollbar.style.width = `0px`;
5120
+ this._horizontalScrollbar.style.left = `0px`;
5121
+ this._scrollLeft = 0;
4927
5122
  }
4928
5123
  }
4929
- hide() {
4930
- this._element.style.display = 'none';
5124
+ }
5125
+ Scrollbar.MouseWheelSpeed = 1;
5126
+
5127
+ class Tabs extends CompositeDisposable {
5128
+ get showTabsOverflowControl() {
5129
+ return this._showTabsOverflowControl;
4931
5130
  }
4932
- setRightActionsElement(element) {
4933
- if (this.rightActions === element) {
5131
+ set showTabsOverflowControl(value) {
5132
+ if (this._showTabsOverflowControl == value) {
4934
5133
  return;
4935
5134
  }
4936
- if (this.rightActions) {
4937
- this.rightActions.remove();
4938
- this.rightActions = undefined;
4939
- }
4940
- if (element) {
4941
- this.rightActionsContainer.appendChild(element);
4942
- this.rightActions = element;
5135
+ this._showTabsOverflowControl = value;
5136
+ if (value) {
5137
+ const observer = new OverflowObserver(this._tabsList);
5138
+ this._observerDisposable.value = new CompositeDisposable(observer, observer.onDidChange((event) => {
5139
+ const hasOverflow = event.hasScrollX || event.hasScrollY;
5140
+ this.toggleDropdown({ reset: !hasOverflow });
5141
+ }), addDisposableListener(this._tabsList, 'scroll', () => {
5142
+ this.toggleDropdown({ reset: false });
5143
+ }));
4943
5144
  }
4944
5145
  }
4945
- setLeftActionsElement(element) {
4946
- if (this.leftActions === element) {
4947
- return;
4948
- }
4949
- if (this.leftActions) {
4950
- this.leftActions.remove();
4951
- this.leftActions = undefined;
4952
- }
4953
- if (element) {
4954
- this.leftActionsContainer.appendChild(element);
4955
- this.leftActions = element;
5146
+ get element() {
5147
+ return this._element;
5148
+ }
5149
+ get panels() {
5150
+ return this._tabs.map((_) => _.value.panel.id);
5151
+ }
5152
+ get size() {
5153
+ return this._tabs.length;
5154
+ }
5155
+ get tabs() {
5156
+ return this._tabs.map((_) => _.value);
5157
+ }
5158
+ constructor(group, accessor, options) {
5159
+ super();
5160
+ this.group = group;
5161
+ this.accessor = accessor;
5162
+ this._observerDisposable = new MutableDisposable();
5163
+ this._tabs = [];
5164
+ this.selectedIndex = -1;
5165
+ this._showTabsOverflowControl = false;
5166
+ this._onTabDragStart = new Emitter();
5167
+ this.onTabDragStart = this._onTabDragStart.event;
5168
+ this._onDrop = new Emitter();
5169
+ this.onDrop = this._onDrop.event;
5170
+ this._onWillShowOverlay = new Emitter();
5171
+ this.onWillShowOverlay = this._onWillShowOverlay.event;
5172
+ this._onOverflowTabsChange = new Emitter();
5173
+ this.onOverflowTabsChange = this._onOverflowTabsChange.event;
5174
+ this._tabsList = document.createElement('div');
5175
+ this._tabsList.className = 'dv-tabs-container dv-horizontal';
5176
+ this.showTabsOverflowControl = options.showTabsOverflowControl;
5177
+ const scrollbar = new Scrollbar(this._tabsList);
5178
+ this._element = scrollbar.element;
5179
+ this.addDisposables(this._onOverflowTabsChange, this._observerDisposable, scrollbar, this._onWillShowOverlay, this._onDrop, this._onTabDragStart, addDisposableListener(this.element, 'pointerdown', (event) => {
5180
+ if (event.defaultPrevented) {
5181
+ return;
5182
+ }
5183
+ const isLeftClick = event.button === 0;
5184
+ if (isLeftClick) {
5185
+ this.accessor.doSetGroupActive(this.group);
5186
+ }
5187
+ }), exports.DockviewDisposable.from(() => {
5188
+ for (const { value, disposable } of this._tabs) {
5189
+ disposable.dispose();
5190
+ value.dispose();
5191
+ }
5192
+ this._tabs = [];
5193
+ }));
5194
+ }
5195
+ indexOf(id) {
5196
+ return this._tabs.findIndex((tab) => tab.value.panel.id === id);
5197
+ }
5198
+ isActive(tab) {
5199
+ return (this.selectedIndex > -1 &&
5200
+ this._tabs[this.selectedIndex].value === tab);
5201
+ }
5202
+ setActivePanel(panel) {
5203
+ let runningWidth = 0;
5204
+ for (const tab of this._tabs) {
5205
+ const isActivePanel = panel.id === tab.value.panel.id;
5206
+ tab.value.setActive(isActivePanel);
5207
+ if (isActivePanel) {
5208
+ const element = tab.value.element;
5209
+ const parentElement = element.parentElement;
5210
+ if (runningWidth < parentElement.scrollLeft ||
5211
+ runningWidth + element.clientWidth >
5212
+ parentElement.scrollLeft + parentElement.clientWidth) {
5213
+ parentElement.scrollLeft = runningWidth;
5214
+ }
5215
+ }
5216
+ runningWidth += tab.value.element.clientWidth;
4956
5217
  }
4957
5218
  }
4958
- setPrefixActionsElement(element) {
4959
- if (this.preActions === element) {
5219
+ openPanel(panel, index = this._tabs.length) {
5220
+ if (this._tabs.find((tab) => tab.value.panel.id === panel.id)) {
4960
5221
  return;
4961
5222
  }
4962
- if (this.preActions) {
4963
- this.preActions.remove();
4964
- this.preActions = undefined;
5223
+ const tab = new Tab(panel, this.accessor, this.group);
5224
+ tab.setContent(panel.view.tab);
5225
+ const disposable = new CompositeDisposable(tab.onDragStart((event) => {
5226
+ this._onTabDragStart.fire({ nativeEvent: event, panel });
5227
+ }), tab.onPointerDown((event) => {
5228
+ if (event.defaultPrevented) {
5229
+ return;
5230
+ }
5231
+ const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
5232
+ const isFloatingWithOnePanel = this.group.api.location.type === 'floating' &&
5233
+ this.size === 1;
5234
+ if (isFloatingGroupsEnabled &&
5235
+ !isFloatingWithOnePanel &&
5236
+ event.shiftKey) {
5237
+ event.preventDefault();
5238
+ const panel = this.accessor.getGroupPanel(tab.panel.id);
5239
+ const { top, left } = tab.element.getBoundingClientRect();
5240
+ const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
5241
+ this.accessor.addFloatingGroup(panel, {
5242
+ x: left - rootLeft,
5243
+ y: top - rootTop,
5244
+ inDragMode: true,
5245
+ });
5246
+ return;
5247
+ }
5248
+ switch (event.button) {
5249
+ case 0: // left click or touch
5250
+ if (this.group.activePanel !== panel) {
5251
+ this.group.model.openPanel(panel);
5252
+ }
5253
+ break;
5254
+ }
5255
+ }), tab.onDrop((event) => {
5256
+ this._onDrop.fire({
5257
+ event: event.nativeEvent,
5258
+ index: this._tabs.findIndex((x) => x.value === tab),
5259
+ });
5260
+ }), tab.onWillShowOverlay((event) => {
5261
+ this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
5262
+ kind: 'tab',
5263
+ panel: this.group.activePanel,
5264
+ api: this.accessor.api,
5265
+ group: this.group,
5266
+ getData: getPanelData,
5267
+ }));
5268
+ }));
5269
+ const value = { value: tab, disposable };
5270
+ this.addTab(value, index);
5271
+ }
5272
+ delete(id) {
5273
+ const index = this.indexOf(id);
5274
+ const tabToRemove = this._tabs.splice(index, 1)[0];
5275
+ const { value, disposable } = tabToRemove;
5276
+ disposable.dispose();
5277
+ value.dispose();
5278
+ value.element.remove();
5279
+ }
5280
+ addTab(tab, index = this._tabs.length) {
5281
+ if (index < 0 || index > this._tabs.length) {
5282
+ throw new Error('invalid location');
4965
5283
  }
4966
- if (element) {
4967
- this.preActionsContainer.appendChild(element);
4968
- this.preActions = element;
5284
+ this._tabsList.insertBefore(tab.value.element, this._tabsList.children[index]);
5285
+ this._tabs = [
5286
+ ...this._tabs.slice(0, index),
5287
+ tab,
5288
+ ...this._tabs.slice(index),
5289
+ ];
5290
+ if (this.selectedIndex < 0) {
5291
+ this.selectedIndex = index;
4969
5292
  }
4970
5293
  }
4971
- get element() {
4972
- return this._element;
5294
+ toggleDropdown(options) {
5295
+ const tabs = options.reset
5296
+ ? []
5297
+ : this._tabs
5298
+ .filter((tab) => !isChildEntirelyVisibleWithinParent(tab.value.element, this._tabsList))
5299
+ .map((x) => x.value.panel.id);
5300
+ this._onOverflowTabsChange.fire({ tabs, reset: options.reset });
4973
5301
  }
4974
- isActive(tab) {
4975
- return (this.selectedIndex > -1 &&
4976
- this.tabs[this.selectedIndex].value === tab);
5302
+ }
5303
+
5304
+ const createSvgElementFromPath = (params) => {
5305
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
5306
+ svg.setAttributeNS(null, 'height', params.height);
5307
+ svg.setAttributeNS(null, 'width', params.width);
5308
+ svg.setAttributeNS(null, 'viewBox', params.viewbox);
5309
+ svg.setAttributeNS(null, 'aria-hidden', 'false');
5310
+ svg.setAttributeNS(null, 'focusable', 'false');
5311
+ svg.classList.add('dv-svg');
5312
+ const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
5313
+ path.setAttributeNS(null, 'd', params.path);
5314
+ svg.appendChild(path);
5315
+ return svg;
5316
+ };
5317
+ const createCloseButton = () => createSvgElementFromPath({
5318
+ width: '11',
5319
+ height: '11',
5320
+ viewbox: '0 0 28 28',
5321
+ 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',
5322
+ });
5323
+ const createExpandMoreButton = () => createSvgElementFromPath({
5324
+ width: '11',
5325
+ height: '11',
5326
+ viewbox: '0 0 24 15',
5327
+ path: 'M12 14.15L0 2.15L2.15 0L12 9.9L21.85 0.0499992L24 2.2L12 14.15Z',
5328
+ });
5329
+ const createChevronRightButton = () => createSvgElementFromPath({
5330
+ width: '11',
5331
+ height: '11',
5332
+ viewbox: '0 0 15 25',
5333
+ path: 'M2.15 24.1L0 21.95L9.9 12.05L0 2.15L2.15 0L14.2 12.05L2.15 24.1Z',
5334
+ });
5335
+
5336
+ function createDropdownElementHandle() {
5337
+ const el = document.createElement('div');
5338
+ el.className = 'dv-tabs-overflow-dropdown-default';
5339
+ const text = document.createElement('span');
5340
+ text.textContent = ``;
5341
+ const icon = createChevronRightButton();
5342
+ el.appendChild(icon);
5343
+ el.appendChild(text);
5344
+ return {
5345
+ element: el,
5346
+ update: (params) => {
5347
+ text.textContent = `${params.tabs}`;
5348
+ },
5349
+ };
5350
+ }
5351
+
5352
+ class TabsContainer extends CompositeDisposable {
5353
+ get onTabDragStart() {
5354
+ return this.tabs.onTabDragStart;
4977
5355
  }
4978
- indexOf(id) {
4979
- return this.tabs.findIndex((tab) => tab.value.panel.id === id);
5356
+ get panels() {
5357
+ return this.tabs.panels;
5358
+ }
5359
+ get size() {
5360
+ return this.tabs.size;
5361
+ }
5362
+ get hidden() {
5363
+ return this._hidden;
5364
+ }
5365
+ set hidden(value) {
5366
+ this._hidden = value;
5367
+ this.element.style.display = value ? 'none' : '';
5368
+ }
5369
+ get element() {
5370
+ return this._element;
4980
5371
  }
4981
5372
  constructor(accessor, group) {
4982
5373
  super();
4983
5374
  this.accessor = accessor;
4984
5375
  this.group = group;
4985
- this.tabs = [];
4986
- this.selectedIndex = -1;
4987
5376
  this._hidden = false;
5377
+ this.dropdownPart = null;
5378
+ this._overflowTabs = [];
5379
+ this._dropdownDisposable = new MutableDisposable();
4988
5380
  this._onDrop = new Emitter();
4989
5381
  this.onDrop = this._onDrop.event;
4990
- this._onTabDragStart = new Emitter();
4991
- this.onTabDragStart = this._onTabDragStart.event;
4992
5382
  this._onGroupDragStart = new Emitter();
4993
5383
  this.onGroupDragStart = this._onGroupDragStart.event;
4994
5384
  this._onWillShowOverlay = new Emitter();
@@ -5002,15 +5392,21 @@
5002
5392
  this.leftActionsContainer.className = 'dv-left-actions-container';
5003
5393
  this.preActionsContainer = document.createElement('div');
5004
5394
  this.preActionsContainer.className = 'dv-pre-actions-container';
5005
- this.tabContainer = document.createElement('div');
5006
- this.tabContainer.className = 'dv-tabs-container';
5395
+ this.tabs = new Tabs(group, accessor, {
5396
+ showTabsOverflowControl: !accessor.options.disableTabsOverflowList,
5397
+ });
5007
5398
  this.voidContainer = new VoidContainer(this.accessor, this.group);
5008
5399
  this._element.appendChild(this.preActionsContainer);
5009
- this._element.appendChild(this.tabContainer);
5400
+ this._element.appendChild(this.tabs.element);
5010
5401
  this._element.appendChild(this.leftActionsContainer);
5011
5402
  this._element.appendChild(this.voidContainer.element);
5012
5403
  this._element.appendChild(this.rightActionsContainer);
5013
- this.addDisposables(this._onWillShowOverlay, this._onDrop, this._onTabDragStart, this._onGroupDragStart, this.voidContainer, this.voidContainer.onDragStart((event) => {
5404
+ this.addDisposables(accessor.onDidOptionsChange(() => {
5405
+ this.tabs.showTabsOverflowControl =
5406
+ !accessor.options.disableTabsOverflowList;
5407
+ }), this.tabs.onOverflowTabsChange((event) => {
5408
+ this.toggleDropdown(event);
5409
+ }), this.tabs, this._onWillShowOverlay, this._onDrop, this._onGroupDragStart, this.voidContainer, this.voidContainer.onDragStart((event) => {
5014
5410
  this._onGroupDragStart.fire({
5015
5411
  nativeEvent: event,
5016
5412
  group: this.group,
@@ -5018,7 +5414,7 @@
5018
5414
  }), this.voidContainer.onDrop((event) => {
5019
5415
  this._onDrop.fire({
5020
5416
  event: event.nativeEvent,
5021
- index: this.tabs.length,
5417
+ index: this.tabs.size,
5022
5418
  });
5023
5419
  }), this.voidContainer.onWillShowOverlay((event) => {
5024
5420
  this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
@@ -5028,133 +5424,149 @@
5028
5424
  group: this.group,
5029
5425
  getData: getPanelData,
5030
5426
  }));
5031
- }), addDisposableListener(this.voidContainer.element, 'pointerdown', (event) => {
5032
- const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
5033
- if (isFloatingGroupsEnabled &&
5034
- event.shiftKey &&
5035
- this.group.api.location.type !== 'floating') {
5036
- event.preventDefault();
5037
- const { top, left } = this.element.getBoundingClientRect();
5038
- const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
5039
- this.accessor.addFloatingGroup(this.group, {
5040
- x: left - rootLeft + 20,
5041
- y: top - rootTop + 20,
5042
- inDragMode: true,
5043
- });
5044
- }
5045
- }), addDisposableListener(this.tabContainer, 'pointerdown', (event) => {
5046
- if (event.defaultPrevented) {
5047
- return;
5048
- }
5049
- const isLeftClick = event.button === 0;
5050
- if (isLeftClick) {
5051
- this.accessor.doSetGroupActive(this.group);
5052
- }
5053
- }));
5054
- }
5055
- setActive(_isGroupActive) {
5056
- // noop
5057
- }
5058
- delete(id) {
5059
- const index = this.tabs.findIndex((tab) => tab.value.panel.id === id);
5060
- const tabToRemove = this.tabs.splice(index, 1)[0];
5061
- if (!tabToRemove) {
5062
- throw new Error(`dockview: Tab not found`);
5063
- }
5064
- const { value, disposable } = tabToRemove;
5065
- disposable.dispose();
5066
- value.dispose();
5067
- value.element.remove();
5068
- this.updateClassnames();
5069
- }
5070
- setActivePanel(panel) {
5071
- this.tabs.forEach((tab) => {
5072
- const isActivePanel = panel.id === tab.value.panel.id;
5073
- tab.value.setActive(isActivePanel);
5074
- });
5075
- }
5076
- openPanel(panel, index = this.tabs.length) {
5077
- if (this.tabs.find((tab) => tab.value.panel.id === panel.id)) {
5078
- return;
5079
- }
5080
- const tab = new Tab(panel, this.accessor, this.group);
5081
- tab.setContent(panel.view.tab);
5082
- const disposable = new CompositeDisposable(tab.onDragStart((event) => {
5083
- this._onTabDragStart.fire({ nativeEvent: event, panel });
5084
- }), tab.onPointerDown((event) => {
5427
+ }), addDisposableListener(this.voidContainer.element, 'pointerdown', (event) => {
5085
5428
  if (event.defaultPrevented) {
5086
5429
  return;
5087
5430
  }
5088
5431
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
5089
- const isFloatingWithOnePanel = this.group.api.location.type === 'floating' &&
5090
- this.size === 1;
5091
5432
  if (isFloatingGroupsEnabled &&
5092
- !isFloatingWithOnePanel &&
5093
- event.shiftKey) {
5433
+ event.shiftKey &&
5434
+ this.group.api.location.type !== 'floating') {
5094
5435
  event.preventDefault();
5095
- const panel = this.accessor.getGroupPanel(tab.panel.id);
5096
- const { top, left } = tab.element.getBoundingClientRect();
5436
+ const { top, left } = this.element.getBoundingClientRect();
5097
5437
  const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
5098
- this.accessor.addFloatingGroup(panel, {
5099
- x: left - rootLeft,
5100
- y: top - rootTop,
5438
+ this.accessor.addFloatingGroup(this.group, {
5439
+ x: left - rootLeft + 20,
5440
+ y: top - rootTop + 20,
5101
5441
  inDragMode: true,
5102
5442
  });
5103
- return;
5104
- }
5105
- switch (event.button) {
5106
- case 0: // left click or touch
5107
- if (this.group.activePanel !== panel) {
5108
- this.group.model.openPanel(panel);
5109
- }
5110
- break;
5111
5443
  }
5112
- }), tab.onDrop((event) => {
5113
- this._onDrop.fire({
5114
- event: event.nativeEvent,
5115
- index: this.tabs.findIndex((x) => x.value === tab),
5116
- });
5117
- }), tab.onWillShowOverlay((event) => {
5118
- this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
5119
- kind: 'tab',
5120
- panel: this.group.activePanel,
5121
- api: this.accessor.api,
5122
- group: this.group,
5123
- getData: getPanelData,
5124
- }));
5125
5444
  }));
5126
- const value = { value: tab, disposable };
5127
- this.addTab(value, index);
5128
5445
  }
5129
- closePanel(panel) {
5130
- this.delete(panel.id);
5446
+ show() {
5447
+ if (!this.hidden) {
5448
+ this.element.style.display = '';
5449
+ }
5131
5450
  }
5132
- dispose() {
5133
- super.dispose();
5134
- for (const { value, disposable } of this.tabs) {
5135
- disposable.dispose();
5136
- value.dispose();
5451
+ hide() {
5452
+ this._element.style.display = 'none';
5453
+ }
5454
+ setRightActionsElement(element) {
5455
+ if (this.rightActions === element) {
5456
+ return;
5457
+ }
5458
+ if (this.rightActions) {
5459
+ this.rightActions.remove();
5460
+ this.rightActions = undefined;
5461
+ }
5462
+ if (element) {
5463
+ this.rightActionsContainer.appendChild(element);
5464
+ this.rightActions = element;
5137
5465
  }
5138
- this.tabs = [];
5139
5466
  }
5140
- addTab(tab, index = this.tabs.length) {
5141
- if (index < 0 || index > this.tabs.length) {
5142
- throw new Error('invalid location');
5467
+ setLeftActionsElement(element) {
5468
+ if (this.leftActions === element) {
5469
+ return;
5143
5470
  }
5144
- this.tabContainer.insertBefore(tab.value.element, this.tabContainer.children[index]);
5145
- this.tabs = [
5146
- ...this.tabs.slice(0, index),
5147
- tab,
5148
- ...this.tabs.slice(index),
5149
- ];
5150
- if (this.selectedIndex < 0) {
5151
- this.selectedIndex = index;
5471
+ if (this.leftActions) {
5472
+ this.leftActions.remove();
5473
+ this.leftActions = undefined;
5474
+ }
5475
+ if (element) {
5476
+ this.leftActionsContainer.appendChild(element);
5477
+ this.leftActions = element;
5478
+ }
5479
+ }
5480
+ setPrefixActionsElement(element) {
5481
+ if (this.preActions === element) {
5482
+ return;
5483
+ }
5484
+ if (this.preActions) {
5485
+ this.preActions.remove();
5486
+ this.preActions = undefined;
5487
+ }
5488
+ if (element) {
5489
+ this.preActionsContainer.appendChild(element);
5490
+ this.preActions = element;
5152
5491
  }
5492
+ }
5493
+ isActive(tab) {
5494
+ return this.tabs.isActive(tab);
5495
+ }
5496
+ indexOf(id) {
5497
+ return this.tabs.indexOf(id);
5498
+ }
5499
+ setActive(_isGroupActive) {
5500
+ // noop
5501
+ }
5502
+ delete(id) {
5503
+ this.tabs.delete(id);
5504
+ this.updateClassnames();
5505
+ }
5506
+ setActivePanel(panel) {
5507
+ this.tabs.setActivePanel(panel);
5508
+ }
5509
+ openPanel(panel, index = this.tabs.size) {
5510
+ this.tabs.openPanel(panel, index);
5153
5511
  this.updateClassnames();
5154
5512
  }
5513
+ closePanel(panel) {
5514
+ this.delete(panel.id);
5515
+ }
5155
5516
  updateClassnames() {
5156
5517
  toggleClass(this._element, 'dv-single-tab', this.size === 1);
5157
5518
  }
5519
+ toggleDropdown(options) {
5520
+ const tabs = options.reset ? [] : options.tabs;
5521
+ this._overflowTabs = tabs;
5522
+ if (this._overflowTabs.length > 0 && this.dropdownPart) {
5523
+ this.dropdownPart.update({ tabs: tabs.length });
5524
+ return;
5525
+ }
5526
+ if (this._overflowTabs.length === 0) {
5527
+ this._dropdownDisposable.dispose();
5528
+ return;
5529
+ }
5530
+ const root = document.createElement('div');
5531
+ root.className = 'dv-tabs-overflow-dropdown-root';
5532
+ const part = createDropdownElementHandle();
5533
+ part.update({ tabs: tabs.length });
5534
+ this.dropdownPart = part;
5535
+ root.appendChild(part.element);
5536
+ this.rightActionsContainer.prepend(root);
5537
+ this._dropdownDisposable.value = new CompositeDisposable(exports.DockviewDisposable.from(() => {
5538
+ var _a, _b;
5539
+ root.remove();
5540
+ (_b = (_a = this.dropdownPart) === null || _a === void 0 ? void 0 : _a.dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
5541
+ this.dropdownPart = null;
5542
+ }), addDisposableListener(root, 'pointerdown', (event) => {
5543
+ event.preventDefault();
5544
+ }, { capture: true }), addDisposableListener(root, 'click', (event) => {
5545
+ const el = document.createElement('div');
5546
+ el.style.overflow = 'auto';
5547
+ el.className = 'dv-tabs-overflow-container';
5548
+ for (const tab of this.tabs.tabs.filter((tab) => this._overflowTabs.includes(tab.panel.id))) {
5549
+ const panelObject = this.group.panels.find((panel) => panel === tab.panel);
5550
+ const tabComponent = panelObject.view.createTabRenderer('headerOverflow');
5551
+ const child = tabComponent.element;
5552
+ const wrapper = document.createElement('div');
5553
+ toggleClass(wrapper, 'dv-tab', true);
5554
+ toggleClass(wrapper, 'dv-active-tab', panelObject.api.isActive);
5555
+ toggleClass(wrapper, 'dv-inactive-tab', !panelObject.api.isActive);
5556
+ wrapper.addEventListener('mousedown', () => {
5557
+ this.accessor.popupService.close();
5558
+ tab.element.scrollIntoView();
5559
+ tab.panel.api.setActive();
5560
+ });
5561
+ wrapper.appendChild(child);
5562
+ el.appendChild(wrapper);
5563
+ }
5564
+ this.accessor.popupService.openPopover(el, {
5565
+ x: event.clientX,
5566
+ y: event.clientY,
5567
+ });
5568
+ }));
5569
+ }
5158
5570
  }
5159
5571
 
5160
5572
  class DockviewUnhandledDragOverEvent extends AcceptableEvent {
@@ -5184,9 +5596,11 @@
5184
5596
  rootOverlayModel: undefined,
5185
5597
  locked: undefined,
5186
5598
  disableDnd: undefined,
5187
- gap: undefined,
5188
5599
  className: undefined,
5189
5600
  noPanelsOverlay: undefined,
5601
+ dndEdges: undefined,
5602
+ theme: undefined,
5603
+ disableTabsOverflowList: undefined,
5190
5604
  };
5191
5605
  return Object.keys(properties);
5192
5606
  })();
@@ -5365,6 +5779,7 @@
5365
5779
  this._location = { type: 'grid' };
5366
5780
  this.mostRecentlyUsed = [];
5367
5781
  this._overwriteRenderContainer = null;
5782
+ this._overwriteDropTargetContainer = null;
5368
5783
  this._onDidChange = new Emitter();
5369
5784
  this.onDidChange = this._onDidChange.event;
5370
5785
  this._width = 0;
@@ -5442,6 +5857,13 @@
5442
5857
  var _a;
5443
5858
  return ((_a = this._overwriteRenderContainer) !== null && _a !== void 0 ? _a : this.accessor.overlayRenderContainer);
5444
5859
  }
5860
+ set dropTargetContainer(value) {
5861
+ this._overwriteDropTargetContainer = value;
5862
+ }
5863
+ get dropTargetContainer() {
5864
+ var _a;
5865
+ return ((_a = this._overwriteDropTargetContainer) !== null && _a !== void 0 ? _a : this.accessor.rootDropTargetContainer);
5866
+ }
5445
5867
  initialize() {
5446
5868
  if (this.options.panels) {
5447
5869
  this.options.panels.forEach((panel) => {
@@ -5790,6 +6212,25 @@
5790
6212
  }
5791
6213
  const data = getPanelData();
5792
6214
  if (data && data.viewId === this.accessor.id) {
6215
+ if (type === 'content') {
6216
+ if (data.groupId === this.id) {
6217
+ // don't allow to drop on self for center position
6218
+ if (position === 'center') {
6219
+ return;
6220
+ }
6221
+ if (data.panelId === null) {
6222
+ // don't allow group move to drop anywhere on self
6223
+ return;
6224
+ }
6225
+ }
6226
+ }
6227
+ if (type === 'header') {
6228
+ if (data.groupId === this.id) {
6229
+ if (data.panelId === null) {
6230
+ return;
6231
+ }
6232
+ }
6233
+ }
5793
6234
  if (data.panelId === null) {
5794
6235
  // this is a group move dnd event
5795
6236
  const { groupId } = data;
@@ -6218,6 +6659,46 @@
6218
6659
  }
6219
6660
  }
6220
6661
 
6662
+ const themeDark = {
6663
+ name: 'dark',
6664
+ className: 'dockview-theme-dark',
6665
+ };
6666
+ const themeLight = {
6667
+ name: 'light',
6668
+ className: 'dockview-theme-light',
6669
+ };
6670
+ const themeVisualStudio = {
6671
+ name: 'visualStudio',
6672
+ className: 'dockview-theme-vs',
6673
+ };
6674
+ const themeAbyss = {
6675
+ name: 'abyss',
6676
+ className: 'dockview-theme-abyss',
6677
+ };
6678
+ const themeDracula = {
6679
+ name: 'dracula',
6680
+ className: 'dockview-theme-dracula',
6681
+ };
6682
+ const themeReplit = {
6683
+ name: 'replit',
6684
+ className: 'dockview-theme-replit',
6685
+ gap: 10,
6686
+ };
6687
+ const themeAbyssSpaced = {
6688
+ name: 'abyssSpaced',
6689
+ className: 'dockview-theme-abyss-spaced',
6690
+ gap: 10,
6691
+ dndOverlayMounting: 'absolute',
6692
+ dndPanelOverlay: 'group',
6693
+ };
6694
+ const themeLightSpaced = {
6695
+ name: 'lightSpaced',
6696
+ className: 'dockview-theme-light-spaced',
6697
+ gap: 10,
6698
+ dndOverlayMounting: 'absolute',
6699
+ dndPanelOverlay: 'group',
6700
+ };
6701
+
6221
6702
  class DockviewPanelApiImpl extends GridviewPanelApiImpl {
6222
6703
  get location() {
6223
6704
  return this.group.api.location;
@@ -6492,38 +6973,6 @@
6492
6973
  }
6493
6974
  }
6494
6975
 
6495
- const createSvgElementFromPath = (params) => {
6496
- const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
6497
- svg.setAttributeNS(null, 'height', params.height);
6498
- svg.setAttributeNS(null, 'width', params.width);
6499
- svg.setAttributeNS(null, 'viewBox', params.viewbox);
6500
- svg.setAttributeNS(null, 'aria-hidden', 'false');
6501
- svg.setAttributeNS(null, 'focusable', 'false');
6502
- svg.classList.add('dv-svg');
6503
- const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
6504
- path.setAttributeNS(null, 'd', params.path);
6505
- svg.appendChild(path);
6506
- return svg;
6507
- };
6508
- const createCloseButton = () => createSvgElementFromPath({
6509
- width: '11',
6510
- height: '11',
6511
- viewbox: '0 0 28 28',
6512
- 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',
6513
- });
6514
- const createExpandMoreButton = () => createSvgElementFromPath({
6515
- width: '11',
6516
- height: '11',
6517
- viewbox: '0 0 24 15',
6518
- path: 'M12 14.15L0 2.15L2.15 0L12 9.9L21.85 0.0499992L24 2.2L12 14.15Z',
6519
- });
6520
- const createChevronRightButton = () => createSvgElementFromPath({
6521
- width: '11',
6522
- height: '11',
6523
- viewbox: '0 0 15 25',
6524
- path: 'M2.15 24.1L0 21.95L9.9 12.05L0 2.15L2.15 0L14.2 12.05L2.15 24.1Z',
6525
- });
6526
-
6527
6976
  class DefaultTab extends CompositeDisposable {
6528
6977
  get element() {
6529
6978
  return this._element;
@@ -6580,12 +7029,21 @@
6580
7029
  this._content = this.createContentComponent(this.id, contentComponent);
6581
7030
  this._tab = this.createTabComponent(this.id, tabComponent);
6582
7031
  }
7032
+ createTabRenderer(tabLocation) {
7033
+ var _a;
7034
+ const cmp = this.createTabComponent(this.id, this.tabComponent);
7035
+ if (this._params) {
7036
+ cmp.init(Object.assign(Object.assign({}, this._params), { tabLocation }));
7037
+ }
7038
+ if (this._updateEvent) {
7039
+ (_a = cmp.update) === null || _a === void 0 ? void 0 : _a.call(cmp, this._updateEvent);
7040
+ }
7041
+ return cmp;
7042
+ }
6583
7043
  init(params) {
7044
+ this._params = params;
6584
7045
  this.content.init(params);
6585
- this.tab.init(params);
6586
- }
6587
- updateParentGroup(_group, _isPanelVisible) {
6588
- // noop
7046
+ this.tab.init(Object.assign(Object.assign({}, params), { tabLocation: 'header' }));
6589
7047
  }
6590
7048
  layout(width, height) {
6591
7049
  var _a, _b;
@@ -6593,6 +7051,7 @@
6593
7051
  }
6594
7052
  update(event) {
6595
7053
  var _a, _b, _c, _d;
7054
+ this._updateEvent = event;
6596
7055
  (_b = (_a = this.content).update) === null || _b === void 0 ? void 0 : _b.call(_a, event);
6597
7056
  (_d = (_c = this.tab).update) === null || _d === void 0 ? void 0 : _d.call(_c, event);
6598
7057
  }
@@ -7430,6 +7889,132 @@
7430
7889
  }
7431
7890
  }
7432
7891
 
7892
+ class PopupService extends CompositeDisposable {
7893
+ constructor(root) {
7894
+ super();
7895
+ this.root = root;
7896
+ this._active = null;
7897
+ this._activeDisposable = new MutableDisposable();
7898
+ this._element = document.createElement('div');
7899
+ this._element.className = 'dv-popover-anchor';
7900
+ this._element.style.position = 'relative';
7901
+ this.root.prepend(this._element);
7902
+ this.addDisposables(exports.DockviewDisposable.from(() => {
7903
+ this.close();
7904
+ }), this._activeDisposable);
7905
+ }
7906
+ openPopover(element, position) {
7907
+ this.close();
7908
+ const wrapper = document.createElement('div');
7909
+ wrapper.style.position = 'absolute';
7910
+ wrapper.style.zIndex = '99';
7911
+ wrapper.appendChild(element);
7912
+ const anchorBox = this._element.getBoundingClientRect();
7913
+ const offsetX = anchorBox.left;
7914
+ const offsetY = anchorBox.top;
7915
+ wrapper.style.top = `${position.y - offsetY}px`;
7916
+ wrapper.style.left = `${position.x - offsetX}px`;
7917
+ this._element.appendChild(wrapper);
7918
+ this._active = wrapper;
7919
+ this._activeDisposable.value = new CompositeDisposable(addDisposableWindowListener(window, 'pointerdown', (event) => {
7920
+ var _a;
7921
+ const target = event.target;
7922
+ if (!(target instanceof HTMLElement)) {
7923
+ return;
7924
+ }
7925
+ let el = target;
7926
+ while (el && el !== wrapper) {
7927
+ el = (_a = el === null || el === void 0 ? void 0 : el.parentElement) !== null && _a !== void 0 ? _a : null;
7928
+ }
7929
+ if (el) {
7930
+ return; // clicked within popover
7931
+ }
7932
+ this.close();
7933
+ }));
7934
+ }
7935
+ close() {
7936
+ if (this._active) {
7937
+ this._active.remove();
7938
+ this._activeDisposable.dispose();
7939
+ this._active = null;
7940
+ }
7941
+ }
7942
+ }
7943
+
7944
+ class DropTargetAnchorContainer extends CompositeDisposable {
7945
+ get disabled() {
7946
+ return this._disabled;
7947
+ }
7948
+ set disabled(value) {
7949
+ var _a;
7950
+ if (this.disabled === value) {
7951
+ return;
7952
+ }
7953
+ this._disabled = value;
7954
+ if (value) {
7955
+ (_a = this.model) === null || _a === void 0 ? void 0 : _a.clear();
7956
+ }
7957
+ }
7958
+ get model() {
7959
+ if (this.disabled) {
7960
+ return undefined;
7961
+ }
7962
+ return {
7963
+ clear: () => {
7964
+ var _a;
7965
+ if (this._model) {
7966
+ (_a = this._model.root.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(this._model.root);
7967
+ }
7968
+ this._model = undefined;
7969
+ },
7970
+ exists: () => {
7971
+ return !!this._model;
7972
+ },
7973
+ getElements: (event, outline) => {
7974
+ const changed = this._outline !== outline;
7975
+ this._outline = outline;
7976
+ if (this._model) {
7977
+ this._model.changed = changed;
7978
+ return this._model;
7979
+ }
7980
+ const container = this.createContainer();
7981
+ const anchor = this.createAnchor();
7982
+ this._model = { root: container, overlay: anchor, changed };
7983
+ container.appendChild(anchor);
7984
+ this.element.appendChild(container);
7985
+ if ((event === null || event === void 0 ? void 0 : event.target) instanceof HTMLElement) {
7986
+ const targetBox = event.target.getBoundingClientRect();
7987
+ const box = this.element.getBoundingClientRect();
7988
+ anchor.style.left = `${targetBox.left - box.left}px`;
7989
+ anchor.style.top = `${targetBox.top - box.top}px`;
7990
+ }
7991
+ return this._model;
7992
+ },
7993
+ };
7994
+ }
7995
+ constructor(element, options) {
7996
+ super();
7997
+ this.element = element;
7998
+ this._disabled = false;
7999
+ this._disabled = options.disabled;
8000
+ this.addDisposables(exports.DockviewDisposable.from(() => {
8001
+ var _a;
8002
+ (_a = this.model) === null || _a === void 0 ? void 0 : _a.clear();
8003
+ }));
8004
+ }
8005
+ createContainer() {
8006
+ const el = document.createElement('div');
8007
+ el.className = 'dv-drop-target-container';
8008
+ return el;
8009
+ }
8010
+ createAnchor() {
8011
+ const el = document.createElement('div');
8012
+ el.className = 'dv-drop-target-anchor';
8013
+ el.style.visibility = 'hidden';
8014
+ return el;
8015
+ }
8016
+ }
8017
+
7433
8018
  const DEFAULT_ROOT_OVERLAY_MODEL = {
7434
8019
  activationSize: { type: 'pixels', value: 10 },
7435
8020
  size: { type: 'pixels', value: 20 },
@@ -7475,14 +8060,11 @@
7475
8060
  get api() {
7476
8061
  return this._api;
7477
8062
  }
7478
- get gap() {
7479
- return this.gridview.margin;
7480
- }
7481
8063
  get floatingGroups() {
7482
8064
  return this._floatingGroups;
7483
8065
  }
7484
8066
  constructor(container, options) {
7485
- var _a;
8067
+ var _a, _b, _c;
7486
8068
  super(container, {
7487
8069
  proportionalLayout: true,
7488
8070
  orientation: exports.Orientation.HORIZONTAL,
@@ -7491,12 +8073,12 @@
7491
8073
  : undefined,
7492
8074
  disableAutoResizing: options.disableAutoResizing,
7493
8075
  locked: options.locked,
7494
- margin: options.gap,
8076
+ margin: (_b = (_a = options.theme) === null || _a === void 0 ? void 0 : _a.gap) !== null && _b !== void 0 ? _b : 0,
7495
8077
  className: options.className,
7496
8078
  });
7497
8079
  this.nextGroupId = sequentialNumberGenerator();
7498
8080
  this._deserializer = new DefaultDockviewDeserialzier(this);
7499
- this.watermark = null;
8081
+ this._watermark = null;
7500
8082
  this._onWillDragPanel = new Emitter();
7501
8083
  this.onWillDragPanel = this._onWillDragPanel.event;
7502
8084
  this._onWillDragGroup = new Emitter();
@@ -7527,16 +8109,22 @@
7527
8109
  this.onDidRemoveGroup = this._onDidRemoveGroup.event;
7528
8110
  this._onDidAddGroup = new Emitter();
7529
8111
  this.onDidAddGroup = this._onDidAddGroup.event;
8112
+ this._onDidOptionsChange = new Emitter();
8113
+ this.onDidOptionsChange = this._onDidOptionsChange.event;
7530
8114
  this._onDidActiveGroupChange = new Emitter();
7531
8115
  this.onDidActiveGroupChange = this._onDidActiveGroupChange.event;
7532
8116
  this._moving = false;
8117
+ this.popupService = new PopupService(this.element);
8118
+ this.updateDropTargetModel(options);
8119
+ this._themeClassnames = new Classnames(this.element);
8120
+ this.rootDropTargetContainer = new DropTargetAnchorContainer(this.element, { disabled: true });
7533
8121
  this.overlayRenderContainer = new OverlayRenderContainer(this.gridview.element, this);
7534
8122
  toggleClass(this.gridview.element, 'dv-dockview', true);
7535
8123
  toggleClass(this.element, 'dv-debug', !!options.debug);
7536
8124
  if (options.debug) {
7537
8125
  this.addDisposables(new StrictEventsSequencing(this));
7538
8126
  }
7539
- 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(() => {
8127
+ 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(() => {
7540
8128
  this.updateWatermark();
7541
8129
  }), this.onDidAdd((event) => {
7542
8130
  if (!this._moving) {
@@ -7570,7 +8158,9 @@
7570
8158
  }
7571
8159
  }));
7572
8160
  this._options = options;
8161
+ this.updateTheme();
7573
8162
  this._rootDropTarget = new Droptarget(this.element, {
8163
+ className: 'dv-drop-target-edge',
7574
8164
  canDisplayOverlay: (event, position) => {
7575
8165
  const data = getPanelData();
7576
8166
  if (data) {
@@ -7597,7 +8187,8 @@
7597
8187
  return firedEvent.isAccepted;
7598
8188
  },
7599
8189
  acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
7600
- overlayModel: (_a = this.options.rootOverlayModel) !== null && _a !== void 0 ? _a : DEFAULT_ROOT_OVERLAY_MODEL,
8190
+ overlayModel: (_c = this.options.rootOverlayModel) !== null && _c !== void 0 ? _c : DEFAULT_ROOT_OVERLAY_MODEL,
8191
+ getOverrideTarget: () => { var _a; return (_a = this.rootDropTargetContainer) === null || _a === void 0 ? void 0 : _a.model; },
7601
8192
  });
7602
8193
  this.addDisposables(this._rootDropTarget, this._rootDropTarget.onWillShowOverlay((event) => {
7603
8194
  if (this.gridview.length > 0 && event.position === 'center') {
@@ -7775,6 +8366,10 @@
7775
8366
  popoutContainer.style.overflow = 'hidden';
7776
8367
  popoutContainer.appendChild(gready);
7777
8368
  popoutContainer.appendChild(group.element);
8369
+ const anchor = document.createElement('div');
8370
+ const dropTargetContainer = new DropTargetAnchorContainer(anchor, { disabled: this.rootDropTargetContainer.disabled });
8371
+ popoutContainer.appendChild(anchor);
8372
+ group.model.dropTargetContainer = dropTargetContainer;
7778
8373
  group.model.location = {
7779
8374
  type: 'popout',
7780
8375
  getWindow: () => _window.window,
@@ -7841,6 +8436,8 @@
7841
8436
  else if (this.getPanel(group.id)) {
7842
8437
  group.model.renderContainer =
7843
8438
  this.overlayRenderContainer;
8439
+ group.model.dropTargetContainer =
8440
+ this.rootDropTargetContainer;
7844
8441
  returnedGroup = group;
7845
8442
  const alreadyRemoved = !this._popoutGroups.find((p) => p.popoutGroup === group);
7846
8443
  if (alreadyRemoved) {
@@ -8061,7 +8658,7 @@
8061
8658
  }
8062
8659
  }
8063
8660
  updateOptions(options) {
8064
- var _a, _b, _c, _d;
8661
+ var _a, _b;
8065
8662
  super.updateOptions(options);
8066
8663
  if ('floatingGroupBounds' in options) {
8067
8664
  for (const group of this._floatingGroups) {
@@ -8085,13 +8682,11 @@
8085
8682
  group.overlay.setBounds();
8086
8683
  }
8087
8684
  }
8088
- if ('rootOverlayModel' in options) {
8089
- this._rootDropTarget.setOverlayModel((_c = options.rootOverlayModel) !== null && _c !== void 0 ? _c : DEFAULT_ROOT_OVERLAY_MODEL);
8090
- }
8091
- if ('gap' in options) {
8092
- this.gridview.margin = (_d = options.gap) !== null && _d !== void 0 ? _d : 0;
8093
- }
8685
+ this.updateDropTargetModel(options);
8094
8686
  this._options = Object.assign(Object.assign({}, this.options), options);
8687
+ if ('theme' in options) {
8688
+ this.updateTheme();
8689
+ }
8095
8690
  this.layout(this.gridview.width, this.gridview.height, true);
8096
8691
  }
8097
8692
  layout(width, height, forceResize) {
@@ -8509,22 +9104,22 @@
8509
9104
  updateWatermark() {
8510
9105
  var _a, _b;
8511
9106
  if (this.groups.filter((x) => x.api.location.type === 'grid' && x.api.isVisible).length === 0) {
8512
- if (!this.watermark) {
8513
- this.watermark = this.createWatermarkComponent();
8514
- this.watermark.init({
9107
+ if (!this._watermark) {
9108
+ this._watermark = this.createWatermarkComponent();
9109
+ this._watermark.init({
8515
9110
  containerApi: new DockviewApi(this),
8516
9111
  });
8517
9112
  const watermarkContainer = document.createElement('div');
8518
9113
  watermarkContainer.className = 'dv-watermark-container';
8519
9114
  addTestId(watermarkContainer, 'watermark-component');
8520
- watermarkContainer.appendChild(this.watermark.element);
9115
+ watermarkContainer.appendChild(this._watermark.element);
8521
9116
  this.gridview.element.appendChild(watermarkContainer);
8522
9117
  }
8523
9118
  }
8524
- else if (this.watermark) {
8525
- this.watermark.element.parentElement.remove();
8526
- (_b = (_a = this.watermark).dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
8527
- this.watermark = null;
9119
+ else if (this._watermark) {
9120
+ this._watermark.element.parentElement.remove();
9121
+ (_b = (_a = this._watermark).dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
9122
+ this._watermark = null;
8528
9123
  }
8529
9124
  }
8530
9125
  addGroup(options) {
@@ -9010,6 +9605,38 @@
9010
9605
  ? rootOrientation
9011
9606
  : orthogonal(rootOrientation);
9012
9607
  }
9608
+ updateDropTargetModel(options) {
9609
+ if ('dndEdges' in options) {
9610
+ this._rootDropTarget.disabled =
9611
+ typeof options.dndEdges === 'boolean' &&
9612
+ options.dndEdges === false;
9613
+ if (typeof options.dndEdges === 'object' &&
9614
+ options.dndEdges !== null) {
9615
+ this._rootDropTarget.setOverlayModel(options.dndEdges);
9616
+ }
9617
+ else {
9618
+ this._rootDropTarget.setOverlayModel(DEFAULT_ROOT_OVERLAY_MODEL);
9619
+ }
9620
+ }
9621
+ if ('rootOverlayModel' in options) {
9622
+ this.updateDropTargetModel({ dndEdges: options.dndEdges });
9623
+ }
9624
+ }
9625
+ updateTheme() {
9626
+ var _a, _b;
9627
+ const theme = (_a = this._options.theme) !== null && _a !== void 0 ? _a : themeAbyss;
9628
+ this._themeClassnames.setClassNames(theme.className);
9629
+ this.gridview.margin = (_b = theme.gap) !== null && _b !== void 0 ? _b : 0;
9630
+ switch (theme.dndOverlayMounting) {
9631
+ case 'absolute':
9632
+ this.rootDropTargetContainer.disabled = false;
9633
+ break;
9634
+ case 'relative':
9635
+ default:
9636
+ this.rootDropTargetContainer.disabled = true;
9637
+ break;
9638
+ }
9639
+ }
9013
9640
  }
9014
9641
 
9015
9642
  class GridviewComponent extends BaseGrid {
@@ -9533,6 +10160,7 @@
9533
10160
  for (const view of views) {
9534
10161
  view.dispose();
9535
10162
  }
10163
+ this.element.remove();
9536
10164
  super.dispose();
9537
10165
  }
9538
10166
  }
@@ -9873,6 +10501,7 @@
9873
10501
  value.dispose();
9874
10502
  }
9875
10503
  this._viewDisposables.clear();
10504
+ this.element.remove();
9876
10505
  this.paneview.dispose();
9877
10506
  }
9878
10507
  }
@@ -10190,6 +10819,7 @@
10190
10819
  params: parameters.params,
10191
10820
  api: parameters.api,
10192
10821
  containerApi: parameters.containerApi,
10822
+ tabLocation: parameters.tabLocation,
10193
10823
  });
10194
10824
  }
10195
10825
  update(event) {
@@ -10495,7 +11125,7 @@
10495
11125
  });
10496
11126
  DockviewReact.displayName = 'DockviewComponent';
10497
11127
 
10498
- const CloseButton = () => (React.createElement("svg", { height: "11", width: "11", viewBox: "0 0 28 28", "aria-hidden": 'false', focusable: false, className: "dockview-svg" },
11128
+ const CloseButton = () => (React.createElement("svg", { height: "11", width: "11", viewBox: "0 0 28 28", "aria-hidden": 'false', focusable: false, className: "dv-svg" },
10499
11129
  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" })));
10500
11130
 
10501
11131
  var __rest = (undefined && undefined.__rest) || function (s, e) {
@@ -10522,7 +11152,7 @@
10522
11152
  return title;
10523
11153
  }
10524
11154
  const DockviewDefaultTab = (_a) => {
10525
- var { api, containerApi: _containerApi, params: _params, hideClose, closeActionOverride, onPointerDown, onPointerUp, onPointerLeave } = _a, rest = __rest(_a, ["api", "containerApi", "params", "hideClose", "closeActionOverride", "onPointerDown", "onPointerUp", "onPointerLeave"]);
11155
+ 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"]);
10526
11156
  const title = useTitle(api);
10527
11157
  const isMiddleMouseButton = React.useRef(false);
10528
11158
  const onClose = React.useCallback((event) => {
@@ -10554,7 +11184,7 @@
10554
11184
  }, [onPointerLeave]);
10555
11185
  return (React.createElement("div", Object.assign({ "data-testid": "dockview-dv-default-tab" }, rest, { onPointerDown: _onPointerDown, onPointerUp: _onPointerUp, onPointerLeave: _onPointerLeave, className: "dv-default-tab" }),
10556
11186
  React.createElement("span", { className: "dv-default-tab-content" }, title),
10557
- !hideClose && (React.createElement("div", { className: "dv-default-tab-action", onPointerDown: onBtnPointerDown, onClick: onClose },
11187
+ !hideClose && tabLocation !== 'headerOverflow' && (React.createElement("div", { className: "dv-default-tab-action", onPointerDown: onBtnPointerDown, onClick: onClose },
10558
11188
  React.createElement(CloseButton, null)))));
10559
11189
  };
10560
11190
 
@@ -10919,6 +11549,14 @@
10919
11549
  exports.isReactComponent = isReactComponent;
10920
11550
  exports.orthogonal = orthogonal;
10921
11551
  exports.positionToDirection = positionToDirection;
11552
+ exports.themeAbyss = themeAbyss;
11553
+ exports.themeAbyssSpaced = themeAbyssSpaced;
11554
+ exports.themeDark = themeDark;
11555
+ exports.themeDracula = themeDracula;
11556
+ exports.themeLight = themeLight;
11557
+ exports.themeLightSpaced = themeLightSpaced;
11558
+ exports.themeReplit = themeReplit;
11559
+ exports.themeVisualStudio = themeVisualStudio;
10922
11560
  exports.toTarget = toTarget;
10923
11561
  exports.usePortalsLifecycle = usePortalsLifecycle;
10924
11562