dockview 1.8.1 → 1.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/cjs/dockview/defaultTab.d.ts +4 -1
  2. package/dist/cjs/dockview/defaultTab.d.ts.map +1 -1
  3. package/dist/cjs/dockview/defaultTab.js +18 -11
  4. package/dist/cjs/dockview/defaultTab.js.map +1 -1
  5. package/dist/cjs/dockview/dockview.d.ts +4 -0
  6. package/dist/cjs/dockview/dockview.d.ts.map +1 -1
  7. package/dist/cjs/dockview/dockview.js +9 -0
  8. package/dist/cjs/dockview/dockview.js.map +1 -1
  9. package/dist/cjs/react.d.ts.map +1 -1
  10. package/dist/cjs/react.js.map +1 -1
  11. package/dist/cjs/types.d.ts +2 -1
  12. package/dist/cjs/types.d.ts.map +1 -1
  13. package/dist/dockview.amd.js +229 -116
  14. package/dist/dockview.amd.js.map +1 -1
  15. package/dist/dockview.amd.min.js +2 -2
  16. package/dist/dockview.amd.min.js.map +1 -1
  17. package/dist/dockview.amd.min.noStyle.js +2 -2
  18. package/dist/dockview.amd.min.noStyle.js.map +1 -1
  19. package/dist/dockview.amd.noStyle.js +228 -115
  20. package/dist/dockview.amd.noStyle.js.map +1 -1
  21. package/dist/dockview.cjs.js +229 -116
  22. package/dist/dockview.cjs.js.map +1 -1
  23. package/dist/dockview.esm.js +229 -116
  24. package/dist/dockview.esm.js.map +1 -1
  25. package/dist/dockview.esm.min.js +2 -2
  26. package/dist/dockview.esm.min.js.map +1 -1
  27. package/dist/dockview.js +229 -116
  28. package/dist/dockview.js.map +1 -1
  29. package/dist/dockview.min.js +2 -2
  30. package/dist/dockview.min.js.map +1 -1
  31. package/dist/dockview.min.noStyle.js +2 -2
  32. package/dist/dockview.min.noStyle.js.map +1 -1
  33. package/dist/dockview.noStyle.js +228 -115
  34. package/dist/dockview.noStyle.js.map +1 -1
  35. package/dist/esm/dockview/defaultTab.d.ts +4 -1
  36. package/dist/esm/dockview/defaultTab.d.ts.map +1 -1
  37. package/dist/esm/dockview/defaultTab.js +18 -11
  38. package/dist/esm/dockview/defaultTab.js.map +1 -1
  39. package/dist/esm/dockview/dockview.d.ts +4 -0
  40. package/dist/esm/dockview/dockview.d.ts.map +1 -1
  41. package/dist/esm/dockview/dockview.js +9 -0
  42. package/dist/esm/dockview/dockview.js.map +1 -1
  43. package/dist/esm/react.d.ts.map +1 -1
  44. package/dist/esm/react.js.map +1 -1
  45. package/dist/esm/types.d.ts +2 -1
  46. package/dist/esm/types.d.ts.map +1 -1
  47. package/dist/styles/dockview.css +3 -3
  48. package/package.json +3 -3
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * dockview
3
- * @version 1.8.1
3
+ * @version 1.8.3
4
4
  * @link https://github.com/mathuo/dockview
5
5
  * @license MIT
6
6
  */
@@ -34,7 +34,7 @@ function styleInject(css, ref) {
34
34
  }
35
35
  }
36
36
 
37
- var css_248z = "@import \"dockview-core/dist/styles/dockview.css\";\n.tab .dockview-react-tab {\n display: flex;\n padding: 0px 8px;\n align-items: center;\n height: 100%;\n}\n.tab .dockview-react-tab .dockview-react-tab-title {\n padding: 0px 8px;\n flex-grow: 1;\n}\n.tab .dockview-react-tab .dockview-react-tab-action {\n padding: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n}\n.tab .dockview-react-tab .dockview-react-tab-action:hover {\n border-radius: 2px;\n background-color: var(--dv-icon-hover-background-color);\n}\n.tab.inactive-tab:not(:hover) .dockview-react-tab-action {\n visibility: hidden;\n}\n.dockview-react-part {\n height: 100%;\n width: 100%;\n}";
37
+ var css_248z = "@import \"dockview-core/dist/styles/dockview.css\";\n.tab .dockview-react-tab {\n display: flex;\n padding: 0px 8px;\n align-items: center;\n height: 100%;\n}\n.tab .dockview-react-tab .dockview-react-tab-title {\n padding: 0px 8px;\n flex-grow: 1;\n}\n.tab .dockview-react-tab .dv-react-tab-close-btn {\n padding: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n}\n.tab .dockview-react-tab .dv-react-tab-close-btn:hover {\n border-radius: 2px;\n background-color: var(--dv-icon-hover-background-color);\n}\n.tab.inactive-tab:not(:hover) .dv-react-tab-close-btn {\n visibility: hidden;\n}\n.dockview-react-part {\n height: 100%;\n width: 100%;\n}";
38
38
  styleInject(css_248z);
39
39
 
40
40
  class TransferObject {
@@ -271,9 +271,6 @@ class CompositeDisposable {
271
271
  get isDisposed() {
272
272
  return this._isDisposed;
273
273
  }
274
- static from(...args) {
275
- return new CompositeDisposable(...args);
276
- }
277
274
  constructor(...args) {
278
275
  this._isDisposed = false;
279
276
  this._disposables = args;
@@ -2477,6 +2474,12 @@ class DockviewApi {
2477
2474
  get onDidDrop() {
2478
2475
  return this.component.onDidDrop;
2479
2476
  }
2477
+ get onWillDragGroup() {
2478
+ return this.component.onWillDragGroup;
2479
+ }
2480
+ get onWillDragPanel() {
2481
+ return this.component.onWillDragPanel;
2482
+ }
2480
2483
  get panels() {
2481
2484
  return this.component.panels;
2482
2485
  }
@@ -2939,7 +2942,7 @@ class DragHandler extends CompositeDisposable {
2939
2942
  }
2940
2943
  configure() {
2941
2944
  this.addDisposables(this._onDragStart, addDisposableListener(this.el, 'dragstart', (event) => {
2942
- if (this.isCancelled(event)) {
2945
+ if (event.defaultPrevented || this.isCancelled(event)) {
2943
2946
  event.preventDefault();
2944
2947
  return;
2945
2948
  }
@@ -2959,19 +2962,23 @@ class DragHandler extends CompositeDisposable {
2959
2962
  }
2960
2963
  this.el.classList.add('dv-dragged');
2961
2964
  setTimeout(() => this.el.classList.remove('dv-dragged'), 0);
2962
- this.dataDisposable.value = this.getData(event.dataTransfer);
2965
+ this.dataDisposable.value = this.getData(event);
2966
+ this._onDragStart.fire(event);
2963
2967
  if (event.dataTransfer) {
2964
2968
  event.dataTransfer.effectAllowed = 'move';
2965
- /**
2966
- * Although this is not used by dockview many third party dnd libraries will check
2967
- * dataTransfer.types to determine valid drag events.
2968
- *
2969
- * For example: in react-dnd if dataTransfer.types is not set then the dragStart event will be cancelled
2970
- * through .preventDefault(). Since this is applied globally to all drag events this would break dockviews
2971
- * dnd logic. You can see the code at
2972
- * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
2973
- */
2974
- event.dataTransfer.setData('text/plain', '__dockview_internal_drag_event__');
2969
+ const hasData = event.dataTransfer.items.length > 0;
2970
+ if (!hasData) {
2971
+ /**
2972
+ * Although this is not used by dockview many third party dnd libraries will check
2973
+ * dataTransfer.types to determine valid drag events.
2974
+ *
2975
+ * For example: in react-dnd if dataTransfer.types is not set then the dragStart event will be cancelled
2976
+ * through .preventDefault(). Since this is applied globally to all drag events this would break dockviews
2977
+ * dnd logic. You can see the code at
2978
+ * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
2979
+ */
2980
+ event.dataTransfer.setData('text/plain', '__dockview_internal_drag_event__');
2981
+ }
2975
2982
  }
2976
2983
  }), addDisposableListener(this.el, 'dragend', () => {
2977
2984
  this.pointerEventsDisposable.dispose();
@@ -2980,44 +2987,45 @@ class DragHandler extends CompositeDisposable {
2980
2987
  }
2981
2988
  }
2982
2989
 
2990
+ class TabDragHandler extends DragHandler {
2991
+ constructor(element, accessor, group, panel) {
2992
+ super(element);
2993
+ this.accessor = accessor;
2994
+ this.group = group;
2995
+ this.panel = panel;
2996
+ this.panelTransfer = LocalSelectionTransfer.getInstance();
2997
+ }
2998
+ getData(event) {
2999
+ this.panelTransfer.setData([new PanelTransfer(this.accessor.id, this.group.id, this.panel.id)], PanelTransfer.prototype);
3000
+ return {
3001
+ dispose: () => {
3002
+ this.panelTransfer.clearData(PanelTransfer.prototype);
3003
+ },
3004
+ };
3005
+ }
3006
+ }
2983
3007
  class Tab extends CompositeDisposable {
2984
3008
  get element() {
2985
3009
  return this._element;
2986
3010
  }
2987
- constructor(panelId, accessor, group) {
3011
+ constructor(panel, accessor, group) {
2988
3012
  super();
2989
- this.panelId = panelId;
3013
+ this.panel = panel;
2990
3014
  this.accessor = accessor;
2991
3015
  this.group = group;
3016
+ this.content = undefined;
2992
3017
  this._onChanged = new Emitter();
2993
3018
  this.onChanged = this._onChanged.event;
2994
3019
  this._onDropped = new Emitter();
2995
3020
  this.onDrop = this._onDropped.event;
3021
+ this._onDragStart = new Emitter();
3022
+ this.onDragStart = this._onDragStart.event;
2996
3023
  this._element = document.createElement('div');
2997
3024
  this._element.className = 'tab';
2998
3025
  this._element.tabIndex = 0;
2999
3026
  this._element.draggable = true;
3000
3027
  toggleClass(this.element, 'inactive-tab', true);
3001
- this.addDisposables(this._onChanged, this._onDropped, new (class Handler extends DragHandler {
3002
- constructor() {
3003
- super(...arguments);
3004
- this.panelTransfer = LocalSelectionTransfer.getInstance();
3005
- }
3006
- getData() {
3007
- this.panelTransfer.setData([new PanelTransfer(accessor.id, group.id, panelId)], PanelTransfer.prototype);
3008
- return {
3009
- dispose: () => {
3010
- this.panelTransfer.clearData(PanelTransfer.prototype);
3011
- },
3012
- };
3013
- }
3014
- })(this._element));
3015
- this.addDisposables(addDisposableListener(this._element, 'mousedown', (event) => {
3016
- if (event.defaultPrevented) {
3017
- return;
3018
- }
3019
- this._onChanged.fire(event);
3020
- }));
3028
+ const dragHandler = new TabDragHandler(this._element, this.accessor, this.group, this.panel);
3021
3029
  this.droptarget = new Droptarget(this._element, {
3022
3030
  acceptedTargetZones: ['center'],
3023
3031
  canDisplayOverlay: (event, position) => {
@@ -3031,12 +3039,19 @@ class Tab extends CompositeDisposable {
3031
3039
  // don't allow group move to drop on self
3032
3040
  return false;
3033
3041
  }
3034
- return this.panelId !== data.panelId;
3042
+ return this.panel.id !== data.panelId;
3035
3043
  }
3036
3044
  return this.group.model.canDisplayOverlay(event, position, DockviewDropTargets.Tab);
3037
3045
  },
3038
3046
  });
3039
- this.addDisposables(this.droptarget.onDrop((event) => {
3047
+ this.addDisposables(this._onChanged, this._onDropped, this._onDragStart, dragHandler.onDragStart((event) => {
3048
+ this._onDragStart.fire(event);
3049
+ }), dragHandler, addDisposableListener(this._element, 'mousedown', (event) => {
3050
+ if (event.defaultPrevented) {
3051
+ return;
3052
+ }
3053
+ this._onChanged.fire(event);
3054
+ }), this.droptarget.onDrop((event) => {
3040
3055
  this._onDropped.fire(event);
3041
3056
  }), this.droptarget);
3042
3057
  }
@@ -3068,9 +3083,9 @@ function addGhostImage(dataTransfer, ghostElement) {
3068
3083
  }
3069
3084
 
3070
3085
  class GroupDragHandler extends DragHandler {
3071
- constructor(element, accessorId, group) {
3086
+ constructor(element, accessor, group) {
3072
3087
  super(element);
3073
- this.accessorId = accessorId;
3088
+ this.accessor = accessor;
3074
3089
  this.group = group;
3075
3090
  this.panelTransfer = LocalSelectionTransfer.getInstance();
3076
3091
  this.addDisposables(addDisposableListener(element, 'mousedown', (e) => {
@@ -3090,8 +3105,9 @@ class GroupDragHandler extends DragHandler {
3090
3105
  }
3091
3106
  return false;
3092
3107
  }
3093
- getData(dataTransfer) {
3094
- this.panelTransfer.setData([new PanelTransfer(this.accessorId, this.group.id, null)], PanelTransfer.prototype);
3108
+ getData(dragEvent) {
3109
+ const dataTransfer = dragEvent.dataTransfer;
3110
+ this.panelTransfer.setData([new PanelTransfer(this.accessor.id, this.group.id, null)], PanelTransfer.prototype);
3095
3111
  const style = window.getComputedStyle(this.el);
3096
3112
  const bgColor = style.getPropertyValue('--dv-activegroup-visiblepanel-tab-background-color');
3097
3113
  const color = style.getPropertyValue('--dv-activegroup-visiblepanel-tab-color');
@@ -3126,14 +3142,16 @@ class VoidContainer extends CompositeDisposable {
3126
3142
  this.group = group;
3127
3143
  this._onDrop = new Emitter();
3128
3144
  this.onDrop = this._onDrop.event;
3145
+ this._onDragStart = new Emitter();
3146
+ this.onDragStart = this._onDragStart.event;
3129
3147
  this._element = document.createElement('div');
3130
3148
  this._element.className = 'void-container';
3131
3149
  this._element.tabIndex = 0;
3132
3150
  this._element.draggable = true;
3133
- this.addDisposables(this._onDrop, addDisposableListener(this._element, 'click', () => {
3151
+ this.addDisposables(this._onDrop, this._onDragStart, addDisposableListener(this._element, 'click', () => {
3134
3152
  this.accessor.doSetGroupActive(this.group);
3135
3153
  }));
3136
- const handler = new GroupDragHandler(this._element, accessor.id, group);
3154
+ const handler = new GroupDragHandler(this._element, accessor, group);
3137
3155
  this.voidDropTarget = new Droptarget(this._element, {
3138
3156
  acceptedTargetZones: ['center'],
3139
3157
  canDisplayOverlay: (event, position) => {
@@ -3151,7 +3169,9 @@ class VoidContainer extends CompositeDisposable {
3151
3169
  return group.model.canDisplayOverlay(event, position, DockviewDropTargets.Panel);
3152
3170
  },
3153
3171
  });
3154
- this.addDisposables(handler, this.voidDropTarget.onDrop((event) => {
3172
+ this.addDisposables(handler, handler.onDragStart((event) => {
3173
+ this._onDragStart.fire(event);
3174
+ }), this.voidDropTarget.onDrop((event) => {
3155
3175
  this._onDrop.fire(event);
3156
3176
  }), this.voidDropTarget);
3157
3177
  }
@@ -3159,7 +3179,7 @@ class VoidContainer extends CompositeDisposable {
3159
3179
 
3160
3180
  class TabsContainer extends CompositeDisposable {
3161
3181
  get panels() {
3162
- return this.tabs.map((_) => _.value.panelId);
3182
+ return this.tabs.map((_) => _.value.panel.id);
3163
3183
  }
3164
3184
  get size() {
3165
3185
  return this.tabs.length;
@@ -3213,7 +3233,7 @@ class TabsContainer extends CompositeDisposable {
3213
3233
  this.tabs[this.selectedIndex].value === tab);
3214
3234
  }
3215
3235
  indexOf(id) {
3216
- return this.tabs.findIndex((tab) => tab.value.panelId === id);
3236
+ return this.tabs.findIndex((tab) => tab.value.panel.id === id);
3217
3237
  }
3218
3238
  constructor(accessor, group) {
3219
3239
  super();
@@ -3224,7 +3244,11 @@ class TabsContainer extends CompositeDisposable {
3224
3244
  this._hidden = false;
3225
3245
  this._onDrop = new Emitter();
3226
3246
  this.onDrop = this._onDrop.event;
3227
- this.addDisposables(this._onDrop);
3247
+ this._onTabDragStart = new Emitter();
3248
+ this.onTabDragStart = this._onTabDragStart.event;
3249
+ this._onGroupDragStart = new Emitter();
3250
+ this.onGroupDragStart = this._onGroupDragStart.event;
3251
+ this.addDisposables(this._onDrop, this._onTabDragStart, this._onGroupDragStart);
3228
3252
  this._element = document.createElement('div');
3229
3253
  this._element.className = 'tabs-and-actions-container';
3230
3254
  toggleClass(this._element, 'dv-full-width-single-tab', this.accessor.options.singleTabMode === 'fullwidth');
@@ -3248,7 +3272,12 @@ class TabsContainer extends CompositeDisposable {
3248
3272
  this._element.appendChild(this.leftActionsContainer);
3249
3273
  this._element.appendChild(this.voidContainer.element);
3250
3274
  this._element.appendChild(this.rightActionsContainer);
3251
- this.addDisposables(this.voidContainer, this.voidContainer.onDrop((event) => {
3275
+ this.addDisposables(this.voidContainer, this.voidContainer.onDragStart((event) => {
3276
+ this._onGroupDragStart.fire({
3277
+ nativeEvent: event,
3278
+ group: this.group,
3279
+ });
3280
+ }), this.voidContainer.onDrop((event) => {
3252
3281
  this._onDrop.fire({
3253
3282
  event: event.nativeEvent,
3254
3283
  index: this.tabs.length,
@@ -3294,7 +3323,7 @@ class TabsContainer extends CompositeDisposable {
3294
3323
  }
3295
3324
  }
3296
3325
  delete(id) {
3297
- const index = this.tabs.findIndex((tab) => tab.value.panelId === id);
3326
+ const index = this.tabs.findIndex((tab) => tab.value.panel.id === id);
3298
3327
  const tabToRemove = this.tabs.splice(index, 1)[0];
3299
3328
  const { value, disposable } = tabToRemove;
3300
3329
  disposable.dispose();
@@ -3303,21 +3332,23 @@ class TabsContainer extends CompositeDisposable {
3303
3332
  }
3304
3333
  setActivePanel(panel) {
3305
3334
  this.tabs.forEach((tab) => {
3306
- const isActivePanel = panel.id === tab.value.panelId;
3335
+ const isActivePanel = panel.id === tab.value.panel.id;
3307
3336
  tab.value.setActive(isActivePanel);
3308
3337
  });
3309
3338
  }
3310
3339
  openPanel(panel, index = this.tabs.length) {
3311
3340
  var _a;
3312
- if (this.tabs.find((tab) => tab.value.panelId === panel.id)) {
3341
+ if (this.tabs.find((tab) => tab.value.panel.id === panel.id)) {
3313
3342
  return;
3314
3343
  }
3315
- const tabToAdd = new Tab(panel.id, this.accessor, this.group);
3344
+ const tab = new Tab(panel, this.accessor, this.group);
3316
3345
  if (!((_a = panel.view) === null || _a === void 0 ? void 0 : _a.tab)) {
3317
3346
  throw new Error('invalid header component');
3318
3347
  }
3319
- tabToAdd.setContent(panel.view.tab);
3320
- const disposable = CompositeDisposable.from(tabToAdd.onChanged((event) => {
3348
+ tab.setContent(panel.view.tab);
3349
+ const disposable = new CompositeDisposable(tab.onDragStart((event) => {
3350
+ this._onTabDragStart.fire({ nativeEvent: event, panel });
3351
+ }), tab.onChanged((event) => {
3321
3352
  var _a;
3322
3353
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3323
3354
  const isFloatingWithOnePanel = this.group.api.isFloating && this.size === 1;
@@ -3325,8 +3356,8 @@ class TabsContainer extends CompositeDisposable {
3325
3356
  !isFloatingWithOnePanel &&
3326
3357
  event.shiftKey) {
3327
3358
  event.preventDefault();
3328
- const panel = this.accessor.getGroupPanel(tabToAdd.panelId);
3329
- const { top, left } = tabToAdd.element.getBoundingClientRect();
3359
+ const panel = this.accessor.getGroupPanel(tab.panel.id);
3360
+ const { top, left } = tab.element.getBoundingClientRect();
3330
3361
  const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
3331
3362
  this.accessor.addFloatingGroup(panel, {
3332
3363
  x: left - rootLeft,
@@ -3343,13 +3374,13 @@ class TabsContainer extends CompositeDisposable {
3343
3374
  this.group.model.openPanel(panel, {
3344
3375
  skipFocus: alreadyFocused,
3345
3376
  });
3346
- }), tabToAdd.onDrop((event) => {
3377
+ }), tab.onDrop((event) => {
3347
3378
  this._onDrop.fire({
3348
3379
  event: event.nativeEvent,
3349
- index: this.tabs.findIndex((x) => x.value === tabToAdd),
3380
+ index: this.tabs.findIndex((x) => x.value === tab),
3350
3381
  });
3351
3382
  }));
3352
- const value = { value: tabToAdd, disposable };
3383
+ const value = { value: tab, disposable };
3353
3384
  this.addTab(value, index);
3354
3385
  }
3355
3386
  closePanel(panel) {
@@ -3377,7 +3408,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3377
3408
  }
3378
3409
  set locked(value) {
3379
3410
  this._locked = value;
3380
- toggleClass(this.container, 'locked-groupview', value);
3411
+ toggleClass(this.container, 'locked-groupview', value === 'no-drop-target' || value);
3381
3412
  }
3382
3413
  get isActive() {
3383
3414
  return this._isGroupActive;
@@ -3434,6 +3465,10 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3434
3465
  this.onMove = this._onMove.event;
3435
3466
  this._onDidDrop = new Emitter();
3436
3467
  this.onDidDrop = this._onDidDrop.event;
3468
+ this._onTabDragStart = new Emitter();
3469
+ this.onTabDragStart = this._onTabDragStart.event;
3470
+ this._onGroupDragStart = new Emitter();
3471
+ this.onGroupDragStart = this._onGroupDragStart.event;
3437
3472
  this._onDidAddPanel = new Emitter();
3438
3473
  this.onDidAddPanel = this._onDidAddPanel.event;
3439
3474
  this._onDidRemovePanel = new Emitter();
@@ -3446,7 +3481,8 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3446
3481
  this.dropTarget = new Droptarget(this.contentContainer.element, {
3447
3482
  acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
3448
3483
  canDisplayOverlay: (event, position) => {
3449
- if (this.locked && position === 'center') {
3484
+ if (this.locked === 'no-drop-target' ||
3485
+ (this.locked && position === 'center')) {
3450
3486
  return false;
3451
3487
  }
3452
3488
  const data = getPanelData();
@@ -3472,8 +3508,12 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3472
3508
  });
3473
3509
  container.append(this.tabsContainer.element, this.contentContainer.element);
3474
3510
  this.header.hidden = !!options.hideHeader;
3475
- this.locked = !!options.locked;
3476
- this.addDisposables(this.tabsContainer.onDrop((event) => {
3511
+ this.locked = options.locked || false;
3512
+ this.addDisposables(this._onTabDragStart, this._onGroupDragStart, this.tabsContainer.onTabDragStart((event) => {
3513
+ this._onTabDragStart.fire(event);
3514
+ }), this.tabsContainer.onGroupDragStart((event) => {
3515
+ this._onGroupDragStart.fire(event);
3516
+ }), this.tabsContainer.onDrop((event) => {
3477
3517
  this.handleDropEvent(event.event, 'center', event.index);
3478
3518
  }), this.contentContainer.onDidFocus(() => {
3479
3519
  this.accessor.doSetGroupActive(this.groupPanel, true);
@@ -3528,8 +3568,8 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3528
3568
  activeView: (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.id,
3529
3569
  id: this.id,
3530
3570
  };
3531
- if (this.locked) {
3532
- result.locked = true;
3571
+ if (this.locked !== false) {
3572
+ result.locked = this.locked;
3533
3573
  }
3534
3574
  if (this.header.hidden) {
3535
3575
  result.hideHeader = true;
@@ -3779,6 +3819,9 @@ class DockviewGroupPanelModel extends CompositeDisposable {
3779
3819
  return false;
3780
3820
  }
3781
3821
  handleDropEvent(event, position, index) {
3822
+ if (this.locked === 'no-drop-target') {
3823
+ return;
3824
+ }
3782
3825
  const data = getPanelData();
3783
3826
  if (data && data.viewId === this.accessor.id) {
3784
3827
  if (data.panelId === null) {
@@ -5236,6 +5279,12 @@ const bringElementToFront = (() => {
5236
5279
  return pushToTop;
5237
5280
  })();
5238
5281
  class Overlay extends CompositeDisposable {
5282
+ set minimumInViewportWidth(value) {
5283
+ this.options.minimumInViewportWidth = value;
5284
+ }
5285
+ set minimumInViewportHeight(value) {
5286
+ this.options.minimumInViewportHeight = value;
5287
+ }
5239
5288
  constructor(options) {
5240
5289
  super();
5241
5290
  this.options = options;
@@ -5281,9 +5330,11 @@ class Overlay extends CompositeDisposable {
5281
5330
  const overlayRect = this._element.getBoundingClientRect();
5282
5331
  // region: ensure bounds within allowable limits
5283
5332
  // a minimum width of minimumViewportWidth must be inside the viewport
5284
- const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5333
+ const xOffset = Math.max(0, this.getMinimumWidth(overlayRect.width));
5285
5334
  // a minimum height of minimumViewportHeight must be inside the viewport
5286
- const yOffset = Math.max(0, overlayRect.height - this.options.minimumInViewportHeight);
5335
+ const yOffset = typeof this.options.minimumInViewportHeight === 'number'
5336
+ ? Math.max(0, this.getMinimumHeight(overlayRect.height))
5337
+ : 0;
5287
5338
  const left = clamp(overlayRect.left - containerRect.left, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5288
5339
  const top = clamp(overlayRect.top - containerRect.top, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5289
5340
  this._element.style.left = `${left}px`;
@@ -5329,9 +5380,10 @@ class Overlay extends CompositeDisposable {
5329
5380
  y: e.clientY - overlayRect.top,
5330
5381
  };
5331
5382
  }
5332
- const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5333
- const yOffset = Math.max(0, overlayRect.height -
5334
- this.options.minimumInViewportHeight);
5383
+ const xOffset = Math.max(0, this.getMinimumWidth(overlayRect.width));
5384
+ const yOffset = Math.max(0, this.options.minimumInViewportHeight
5385
+ ? this.getMinimumHeight(overlayRect.height)
5386
+ : 0);
5335
5387
  const left = clamp(x - offset.x, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5336
5388
  const top = clamp(y - offset.y, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5337
5389
  this.setBounds({ top, left });
@@ -5405,14 +5457,11 @@ class Overlay extends CompositeDisposable {
5405
5457
  let height = undefined;
5406
5458
  let left = undefined;
5407
5459
  let width = undefined;
5408
- const minimumInViewportHeight = this.options.minimumInViewportHeight;
5409
- const minimumInViewportWidth = this.options.minimumInViewportWidth;
5410
- function moveTop() {
5460
+ const moveTop = () => {
5411
5461
  top = clamp(y, -Number.MAX_VALUE, startPosition.originalY +
5412
5462
  startPosition.originalHeight >
5413
5463
  containerRect.height
5414
- ? containerRect.height -
5415
- minimumInViewportHeight
5464
+ ? this.getMinimumHeight(containerRect.height)
5416
5465
  : Math.max(0, startPosition.originalY +
5417
5466
  startPosition.originalHeight -
5418
5467
  Overlay.MINIMUM_HEIGHT));
@@ -5420,21 +5469,23 @@ class Overlay extends CompositeDisposable {
5420
5469
  startPosition.originalY +
5421
5470
  startPosition.originalHeight -
5422
5471
  top;
5423
- }
5424
- function moveBottom() {
5472
+ };
5473
+ const moveBottom = () => {
5425
5474
  top =
5426
5475
  startPosition.originalY -
5427
5476
  startPosition.originalHeight;
5428
- height = clamp(y - top, top < 0
5429
- ? -top + minimumInViewportHeight
5477
+ height = clamp(y - top, top < 0 &&
5478
+ typeof this.options
5479
+ .minimumInViewportHeight === 'number'
5480
+ ? -top +
5481
+ this.options.minimumInViewportHeight
5430
5482
  : Overlay.MINIMUM_HEIGHT, Number.MAX_VALUE);
5431
- }
5432
- function moveLeft() {
5483
+ };
5484
+ const moveLeft = () => {
5433
5485
  left = clamp(x, -Number.MAX_VALUE, startPosition.originalX +
5434
5486
  startPosition.originalWidth >
5435
5487
  containerRect.width
5436
- ? containerRect.width -
5437
- minimumInViewportWidth
5488
+ ? this.getMinimumWidth(containerRect.width)
5438
5489
  : Math.max(0, startPosition.originalX +
5439
5490
  startPosition.originalWidth -
5440
5491
  Overlay.MINIMUM_WIDTH));
@@ -5442,15 +5493,18 @@ class Overlay extends CompositeDisposable {
5442
5493
  startPosition.originalX +
5443
5494
  startPosition.originalWidth -
5444
5495
  left;
5445
- }
5446
- function moveRight() {
5496
+ };
5497
+ const moveRight = () => {
5447
5498
  left =
5448
5499
  startPosition.originalX -
5449
5500
  startPosition.originalWidth;
5450
- width = clamp(x - left, left < 0
5451
- ? -left + minimumInViewportWidth
5501
+ width = clamp(x - left, left < 0 &&
5502
+ typeof this.options
5503
+ .minimumInViewportWidth === 'number'
5504
+ ? -left +
5505
+ this.options.minimumInViewportWidth
5452
5506
  : Overlay.MINIMUM_WIDTH, Number.MAX_VALUE);
5453
- }
5507
+ };
5454
5508
  switch (direction) {
5455
5509
  case 'top':
5456
5510
  moveTop();
@@ -5494,6 +5548,18 @@ class Overlay extends CompositeDisposable {
5494
5548
  }));
5495
5549
  }));
5496
5550
  }
5551
+ getMinimumWidth(width) {
5552
+ if (typeof this.options.minimumInViewportWidth === 'number') {
5553
+ return width - this.options.minimumInViewportWidth;
5554
+ }
5555
+ return 0;
5556
+ }
5557
+ getMinimumHeight(height) {
5558
+ if (typeof this.options.minimumInViewportHeight === 'number') {
5559
+ return height - this.options.minimumInViewportHeight;
5560
+ }
5561
+ return height;
5562
+ }
5497
5563
  dispose() {
5498
5564
  this._element.remove();
5499
5565
  super.dispose();
@@ -5514,6 +5580,7 @@ class DockviewFloatingGroupPanel extends CompositeDisposable {
5514
5580
  }
5515
5581
  }
5516
5582
 
5583
+ const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100;
5517
5584
  class DockviewComponent extends BaseGrid {
5518
5585
  get orientation() {
5519
5586
  return this.gridview.orientation;
@@ -5544,6 +5611,10 @@ class DockviewComponent extends BaseGrid {
5544
5611
  this.nextGroupId = sequentialNumberGenerator();
5545
5612
  this._deserializer = new DefaultDockviewDeserialzier(this);
5546
5613
  this.watermark = null;
5614
+ this._onWillDragPanel = new Emitter();
5615
+ this.onWillDragPanel = this._onWillDragPanel.event;
5616
+ this._onWillDragGroup = new Emitter();
5617
+ this.onWillDragGroup = this._onWillDragGroup.event;
5547
5618
  this._onDidDrop = new Emitter();
5548
5619
  this.onDidDrop = this._onDidDrop.event;
5549
5620
  this._onDidRemovePanel = new Emitter();
@@ -5556,7 +5627,7 @@ class DockviewComponent extends BaseGrid {
5556
5627
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
5557
5628
  this.floatingGroups = [];
5558
5629
  toggleClass(this.gridview.element, 'dv-dockview', true);
5559
- this.addDisposables(this._onDidDrop, Event.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
5630
+ this.addDisposables(this._onWillDragPanel, this._onWillDragGroup, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, Event.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
5560
5631
  this.updateWatermark();
5561
5632
  }), Event.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => {
5562
5633
  this._bufferOnDidLayoutChange.fire();
@@ -5593,7 +5664,7 @@ class DockviewComponent extends BaseGrid {
5593
5664
  return true;
5594
5665
  }
5595
5666
  if (this.options.showDndOverlay) {
5596
- if (position === 'center') {
5667
+ if (position === 'center' && this.gridview.length !== 0) {
5597
5668
  /**
5598
5669
  * for external events only show the four-corner drag overlays, disable
5599
5670
  * the center position so that external drag events can fall through to the group
@@ -5629,7 +5700,7 @@ class DockviewComponent extends BaseGrid {
5629
5700
  this.updateWatermark();
5630
5701
  }
5631
5702
  addFloatingGroup(item, coord, options) {
5632
- var _a, _b;
5703
+ var _a, _b, _c, _d, _e, _f;
5633
5704
  let group;
5634
5705
  if (item instanceof DockviewPanel) {
5635
5706
  group = this.createGroup();
@@ -5657,8 +5728,12 @@ class DockviewComponent extends BaseGrid {
5657
5728
  width: (_b = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _b !== void 0 ? _b : 300,
5658
5729
  left: overlayLeft,
5659
5730
  top: overlayTop,
5660
- minimumInViewportWidth: 100,
5661
- minimumInViewportHeight: 100,
5731
+ minimumInViewportWidth: this.options.floatingGroupBounds === 'boundedWithinViewport'
5732
+ ? undefined
5733
+ : (_d = (_c = this.options.floatingGroupBounds) === null || _c === void 0 ? void 0 : _c.minimumWidthWithinViewport) !== null && _d !== void 0 ? _d : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
5734
+ minimumInViewportHeight: this.options.floatingGroupBounds === 'boundedWithinViewport'
5735
+ ? undefined
5736
+ : (_f = (_e = this.options.floatingGroupBounds) === null || _e === void 0 ? void 0 : _e.minimumHeightWithinViewport) !== null && _f !== void 0 ? _f : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
5662
5737
  });
5663
5738
  const el = group.element.querySelector('.void-container');
5664
5739
  if (!el) {
@@ -5729,12 +5804,37 @@ class DockviewComponent extends BaseGrid {
5729
5804
  }
5730
5805
  }
5731
5806
  updateOptions(options) {
5807
+ var _a, _b;
5732
5808
  const hasOrientationChanged = typeof options.orientation === 'string' &&
5733
5809
  this.gridview.orientation !== options.orientation;
5810
+ const hasFloatingGroupOptionsChanged = options.floatingGroupBounds !== undefined &&
5811
+ options.floatingGroupBounds !== this.options.floatingGroupBounds;
5734
5812
  this._options = Object.assign(Object.assign({}, this.options), options);
5735
5813
  if (hasOrientationChanged) {
5736
5814
  this.gridview.orientation = options.orientation;
5737
5815
  }
5816
+ if (hasFloatingGroupOptionsChanged) {
5817
+ for (const group of this.floatingGroups) {
5818
+ switch (this.options.floatingGroupBounds) {
5819
+ case 'boundedWithinViewport':
5820
+ group.overlay.minimumInViewportHeight = undefined;
5821
+ group.overlay.minimumInViewportWidth = undefined;
5822
+ break;
5823
+ case undefined:
5824
+ group.overlay.minimumInViewportHeight =
5825
+ DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE;
5826
+ group.overlay.minimumInViewportWidth =
5827
+ DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE;
5828
+ break;
5829
+ default:
5830
+ group.overlay.minimumInViewportHeight =
5831
+ (_a = this.options.floatingGroupBounds) === null || _a === void 0 ? void 0 : _a.minimumHeightWithinViewport;
5832
+ group.overlay.minimumInViewportWidth =
5833
+ (_b = this.options.floatingGroupBounds) === null || _b === void 0 ? void 0 : _b.minimumWidthWithinViewport;
5834
+ }
5835
+ group.overlay.setBounds({});
5836
+ }
5837
+ }
5738
5838
  this.layout(this.gridview.width, this.gridview.height, true);
5739
5839
  }
5740
5840
  layout(width, height, forceResize) {
@@ -6217,7 +6317,11 @@ class DockviewComponent extends BaseGrid {
6217
6317
  const view = new DockviewGroupPanel(this, id, options);
6218
6318
  view.init({ params: {}, accessor: null }); // required to initialized .part and allow for correct disposal of group
6219
6319
  if (!this._groups.has(view.id)) {
6220
- const disposable = new CompositeDisposable(view.model.onMove((event) => {
6320
+ const disposable = new CompositeDisposable(view.model.onTabDragStart((event) => {
6321
+ this._onWillDragPanel.fire(event);
6322
+ }), view.model.onGroupDragStart((event) => {
6323
+ this._onWillDragGroup.fire(event);
6324
+ }), view.model.onMove((event) => {
6221
6325
  const { groupId, itemId, target, index } = event;
6222
6326
  this.moveGroupOrPanel(view, groupId, itemId, target, index);
6223
6327
  }), view.model.onDidDrop((event) => {
@@ -6256,13 +6360,6 @@ class DockviewComponent extends BaseGrid {
6256
6360
  var _a;
6257
6361
  return (_a = Array.from(this._groups.values()).find((group) => group.value.model.containsPanel(panel))) === null || _a === void 0 ? void 0 : _a.value;
6258
6362
  }
6259
- dispose() {
6260
- this._onDidActivePanelChange.dispose();
6261
- this._onDidAddPanel.dispose();
6262
- this._onDidRemovePanel.dispose();
6263
- this._onDidLayoutFromJSON.dispose();
6264
- super.dispose();
6265
- }
6266
6363
  }
6267
6364
 
6268
6365
  class GridviewComponent extends BaseGrid {
@@ -7560,6 +7657,7 @@ const DockviewReact = React.forwardRef((props, ref) => {
7560
7657
  createRightHeaderActionsElement: createGroupControlElement(props.rightHeaderActionsComponent, { addPortal }),
7561
7658
  singleTabMode: props.singleTabMode,
7562
7659
  disableFloatingGroups: props.disableFloatingGroups,
7660
+ floatingGroupBounds: props.floatingGroupBounds,
7563
7661
  });
7564
7662
  const { clientWidth, clientHeight } = domRef.current;
7565
7663
  dockview.layout(clientWidth, clientHeight);
@@ -7594,6 +7692,14 @@ const DockviewReact = React.forwardRef((props, ref) => {
7594
7692
  frameworkComponents: props.components,
7595
7693
  });
7596
7694
  }, [props.components]);
7695
+ React.useEffect(() => {
7696
+ if (!dockviewRef.current) {
7697
+ return;
7698
+ }
7699
+ dockviewRef.current.updateOptions({
7700
+ floatingGroupBounds: props.floatingGroupBounds,
7701
+ });
7702
+ }, [props.floatingGroupBounds]);
7597
7703
  React.useEffect(() => {
7598
7704
  if (!dockviewRef.current) {
7599
7705
  return;
@@ -7700,25 +7806,32 @@ const CloseButton = () => (React.createElement("svg", { height: "11", width: "11
7700
7806
  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" })));
7701
7807
 
7702
7808
  const DockviewDefaultTab = (_a) => {
7703
- var { api, containerApi: _containerApi, params: _params } = _a, rest = __rest(_a, ["api", "containerApi", "params"]);
7809
+ var { api, containerApi: _containerApi, params: _params, hideClose, closeActionOverride } = _a, rest = __rest(_a, ["api", "containerApi", "params", "hideClose", "closeActionOverride"]);
7704
7810
  const onClose = React.useCallback((event) => {
7705
- event.stopPropagation();
7706
- api.close();
7707
- }, [api]);
7811
+ event.preventDefault();
7812
+ if (closeActionOverride) {
7813
+ closeActionOverride();
7814
+ }
7815
+ else {
7816
+ api.close();
7817
+ }
7818
+ }, [api, closeActionOverride]);
7819
+ const onMouseDown = React.useCallback((e) => {
7820
+ e.preventDefault();
7821
+ }, []);
7708
7822
  const onClick = React.useCallback((event) => {
7823
+ if (event.defaultPrevented) {
7824
+ return;
7825
+ }
7709
7826
  api.setActive();
7710
7827
  if (rest.onClick) {
7711
7828
  rest.onClick(event);
7712
7829
  }
7713
7830
  }, [api, rest.onClick]);
7714
- const iconClassname = React.useMemo(() => {
7715
- const cn = ['dockview-react-tab-action'];
7716
- return cn.join(',');
7717
- }, []);
7718
- return (React.createElement("div", Object.assign({}, rest, { onClick: onClick, className: "dockview-react-tab" }),
7831
+ return (React.createElement("div", Object.assign({ "data-testid": "dockview-default-tab" }, rest, { onClick: onClick, className: "dockview-react-tab" }),
7719
7832
  React.createElement("span", { className: "dockview-react-tab-title" }, api.title),
7720
- React.createElement("div", { className: iconClassname, onClick: onClose },
7721
- React.createElement(CloseButton, null))));
7833
+ !hideClose && (React.createElement("div", { className: "dv-react-tab-close-btn", onMouseDown: onMouseDown, onClick: onClose },
7834
+ React.createElement(CloseButton, null)))));
7722
7835
  };
7723
7836
 
7724
7837
  class ReactPanelView extends SplitviewPanel {