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
  */
@@ -53,7 +53,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
53
53
  }
54
54
  }
55
55
 
56
- 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}";
56
+ 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}";
57
57
  styleInject(css_248z);
58
58
 
59
59
  class TransferObject {
@@ -290,9 +290,6 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
290
290
  get isDisposed() {
291
291
  return this._isDisposed;
292
292
  }
293
- static from(...args) {
294
- return new CompositeDisposable(...args);
295
- }
296
293
  constructor(...args) {
297
294
  this._isDisposed = false;
298
295
  this._disposables = args;
@@ -2496,6 +2493,12 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
2496
2493
  get onDidDrop() {
2497
2494
  return this.component.onDidDrop;
2498
2495
  }
2496
+ get onWillDragGroup() {
2497
+ return this.component.onWillDragGroup;
2498
+ }
2499
+ get onWillDragPanel() {
2500
+ return this.component.onWillDragPanel;
2501
+ }
2499
2502
  get panels() {
2500
2503
  return this.component.panels;
2501
2504
  }
@@ -2958,7 +2961,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
2958
2961
  }
2959
2962
  configure() {
2960
2963
  this.addDisposables(this._onDragStart, addDisposableListener(this.el, 'dragstart', (event) => {
2961
- if (this.isCancelled(event)) {
2964
+ if (event.defaultPrevented || this.isCancelled(event)) {
2962
2965
  event.preventDefault();
2963
2966
  return;
2964
2967
  }
@@ -2978,19 +2981,23 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
2978
2981
  }
2979
2982
  this.el.classList.add('dv-dragged');
2980
2983
  setTimeout(() => this.el.classList.remove('dv-dragged'), 0);
2981
- this.dataDisposable.value = this.getData(event.dataTransfer);
2984
+ this.dataDisposable.value = this.getData(event);
2985
+ this._onDragStart.fire(event);
2982
2986
  if (event.dataTransfer) {
2983
2987
  event.dataTransfer.effectAllowed = 'move';
2984
- /**
2985
- * Although this is not used by dockview many third party dnd libraries will check
2986
- * dataTransfer.types to determine valid drag events.
2987
- *
2988
- * For example: in react-dnd if dataTransfer.types is not set then the dragStart event will be cancelled
2989
- * through .preventDefault(). Since this is applied globally to all drag events this would break dockviews
2990
- * dnd logic. You can see the code at
2991
- * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
2992
- */
2993
- event.dataTransfer.setData('text/plain', '__dockview_internal_drag_event__');
2988
+ const hasData = event.dataTransfer.items.length > 0;
2989
+ if (!hasData) {
2990
+ /**
2991
+ * Although this is not used by dockview many third party dnd libraries will check
2992
+ * dataTransfer.types to determine valid drag events.
2993
+ *
2994
+ * For example: in react-dnd if dataTransfer.types is not set then the dragStart event will be cancelled
2995
+ * through .preventDefault(). Since this is applied globally to all drag events this would break dockviews
2996
+ * dnd logic. You can see the code at
2997
+ * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
2998
+ */
2999
+ event.dataTransfer.setData('text/plain', '__dockview_internal_drag_event__');
3000
+ }
2994
3001
  }
2995
3002
  }), addDisposableListener(this.el, 'dragend', () => {
2996
3003
  this.pointerEventsDisposable.dispose();
@@ -2999,44 +3006,45 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
2999
3006
  }
3000
3007
  }
3001
3008
 
3009
+ class TabDragHandler extends DragHandler {
3010
+ constructor(element, accessor, group, panel) {
3011
+ super(element);
3012
+ this.accessor = accessor;
3013
+ this.group = group;
3014
+ this.panel = panel;
3015
+ this.panelTransfer = LocalSelectionTransfer.getInstance();
3016
+ }
3017
+ getData(event) {
3018
+ this.panelTransfer.setData([new PanelTransfer(this.accessor.id, this.group.id, this.panel.id)], PanelTransfer.prototype);
3019
+ return {
3020
+ dispose: () => {
3021
+ this.panelTransfer.clearData(PanelTransfer.prototype);
3022
+ },
3023
+ };
3024
+ }
3025
+ }
3002
3026
  class Tab extends CompositeDisposable {
3003
3027
  get element() {
3004
3028
  return this._element;
3005
3029
  }
3006
- constructor(panelId, accessor, group) {
3030
+ constructor(panel, accessor, group) {
3007
3031
  super();
3008
- this.panelId = panelId;
3032
+ this.panel = panel;
3009
3033
  this.accessor = accessor;
3010
3034
  this.group = group;
3035
+ this.content = undefined;
3011
3036
  this._onChanged = new Emitter();
3012
3037
  this.onChanged = this._onChanged.event;
3013
3038
  this._onDropped = new Emitter();
3014
3039
  this.onDrop = this._onDropped.event;
3040
+ this._onDragStart = new Emitter();
3041
+ this.onDragStart = this._onDragStart.event;
3015
3042
  this._element = document.createElement('div');
3016
3043
  this._element.className = 'tab';
3017
3044
  this._element.tabIndex = 0;
3018
3045
  this._element.draggable = true;
3019
3046
  toggleClass(this.element, 'inactive-tab', true);
3020
- this.addDisposables(this._onChanged, this._onDropped, new (class Handler extends DragHandler {
3021
- constructor() {
3022
- super(...arguments);
3023
- this.panelTransfer = LocalSelectionTransfer.getInstance();
3024
- }
3025
- getData() {
3026
- this.panelTransfer.setData([new PanelTransfer(accessor.id, group.id, panelId)], PanelTransfer.prototype);
3027
- return {
3028
- dispose: () => {
3029
- this.panelTransfer.clearData(PanelTransfer.prototype);
3030
- },
3031
- };
3032
- }
3033
- })(this._element));
3034
- this.addDisposables(addDisposableListener(this._element, 'mousedown', (event) => {
3035
- if (event.defaultPrevented) {
3036
- return;
3037
- }
3038
- this._onChanged.fire(event);
3039
- }));
3047
+ const dragHandler = new TabDragHandler(this._element, this.accessor, this.group, this.panel);
3040
3048
  this.droptarget = new Droptarget(this._element, {
3041
3049
  acceptedTargetZones: ['center'],
3042
3050
  canDisplayOverlay: (event, position) => {
@@ -3050,12 +3058,19 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3050
3058
  // don't allow group move to drop on self
3051
3059
  return false;
3052
3060
  }
3053
- return this.panelId !== data.panelId;
3061
+ return this.panel.id !== data.panelId;
3054
3062
  }
3055
3063
  return this.group.model.canDisplayOverlay(event, position, exports.DockviewDropTargets.Tab);
3056
3064
  },
3057
3065
  });
3058
- this.addDisposables(this.droptarget.onDrop((event) => {
3066
+ this.addDisposables(this._onChanged, this._onDropped, this._onDragStart, dragHandler.onDragStart((event) => {
3067
+ this._onDragStart.fire(event);
3068
+ }), dragHandler, addDisposableListener(this._element, 'mousedown', (event) => {
3069
+ if (event.defaultPrevented) {
3070
+ return;
3071
+ }
3072
+ this._onChanged.fire(event);
3073
+ }), this.droptarget.onDrop((event) => {
3059
3074
  this._onDropped.fire(event);
3060
3075
  }), this.droptarget);
3061
3076
  }
@@ -3087,9 +3102,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3087
3102
  }
3088
3103
 
3089
3104
  class GroupDragHandler extends DragHandler {
3090
- constructor(element, accessorId, group) {
3105
+ constructor(element, accessor, group) {
3091
3106
  super(element);
3092
- this.accessorId = accessorId;
3107
+ this.accessor = accessor;
3093
3108
  this.group = group;
3094
3109
  this.panelTransfer = LocalSelectionTransfer.getInstance();
3095
3110
  this.addDisposables(addDisposableListener(element, 'mousedown', (e) => {
@@ -3109,8 +3124,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3109
3124
  }
3110
3125
  return false;
3111
3126
  }
3112
- getData(dataTransfer) {
3113
- this.panelTransfer.setData([new PanelTransfer(this.accessorId, this.group.id, null)], PanelTransfer.prototype);
3127
+ getData(dragEvent) {
3128
+ const dataTransfer = dragEvent.dataTransfer;
3129
+ this.panelTransfer.setData([new PanelTransfer(this.accessor.id, this.group.id, null)], PanelTransfer.prototype);
3114
3130
  const style = window.getComputedStyle(this.el);
3115
3131
  const bgColor = style.getPropertyValue('--dv-activegroup-visiblepanel-tab-background-color');
3116
3132
  const color = style.getPropertyValue('--dv-activegroup-visiblepanel-tab-color');
@@ -3145,14 +3161,16 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3145
3161
  this.group = group;
3146
3162
  this._onDrop = new Emitter();
3147
3163
  this.onDrop = this._onDrop.event;
3164
+ this._onDragStart = new Emitter();
3165
+ this.onDragStart = this._onDragStart.event;
3148
3166
  this._element = document.createElement('div');
3149
3167
  this._element.className = 'void-container';
3150
3168
  this._element.tabIndex = 0;
3151
3169
  this._element.draggable = true;
3152
- this.addDisposables(this._onDrop, addDisposableListener(this._element, 'click', () => {
3170
+ this.addDisposables(this._onDrop, this._onDragStart, addDisposableListener(this._element, 'click', () => {
3153
3171
  this.accessor.doSetGroupActive(this.group);
3154
3172
  }));
3155
- const handler = new GroupDragHandler(this._element, accessor.id, group);
3173
+ const handler = new GroupDragHandler(this._element, accessor, group);
3156
3174
  this.voidDropTarget = new Droptarget(this._element, {
3157
3175
  acceptedTargetZones: ['center'],
3158
3176
  canDisplayOverlay: (event, position) => {
@@ -3170,7 +3188,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3170
3188
  return group.model.canDisplayOverlay(event, position, exports.DockviewDropTargets.Panel);
3171
3189
  },
3172
3190
  });
3173
- this.addDisposables(handler, this.voidDropTarget.onDrop((event) => {
3191
+ this.addDisposables(handler, handler.onDragStart((event) => {
3192
+ this._onDragStart.fire(event);
3193
+ }), this.voidDropTarget.onDrop((event) => {
3174
3194
  this._onDrop.fire(event);
3175
3195
  }), this.voidDropTarget);
3176
3196
  }
@@ -3178,7 +3198,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3178
3198
 
3179
3199
  class TabsContainer extends CompositeDisposable {
3180
3200
  get panels() {
3181
- return this.tabs.map((_) => _.value.panelId);
3201
+ return this.tabs.map((_) => _.value.panel.id);
3182
3202
  }
3183
3203
  get size() {
3184
3204
  return this.tabs.length;
@@ -3232,7 +3252,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3232
3252
  this.tabs[this.selectedIndex].value === tab);
3233
3253
  }
3234
3254
  indexOf(id) {
3235
- return this.tabs.findIndex((tab) => tab.value.panelId === id);
3255
+ return this.tabs.findIndex((tab) => tab.value.panel.id === id);
3236
3256
  }
3237
3257
  constructor(accessor, group) {
3238
3258
  super();
@@ -3243,7 +3263,11 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3243
3263
  this._hidden = false;
3244
3264
  this._onDrop = new Emitter();
3245
3265
  this.onDrop = this._onDrop.event;
3246
- this.addDisposables(this._onDrop);
3266
+ this._onTabDragStart = new Emitter();
3267
+ this.onTabDragStart = this._onTabDragStart.event;
3268
+ this._onGroupDragStart = new Emitter();
3269
+ this.onGroupDragStart = this._onGroupDragStart.event;
3270
+ this.addDisposables(this._onDrop, this._onTabDragStart, this._onGroupDragStart);
3247
3271
  this._element = document.createElement('div');
3248
3272
  this._element.className = 'tabs-and-actions-container';
3249
3273
  toggleClass(this._element, 'dv-full-width-single-tab', this.accessor.options.singleTabMode === 'fullwidth');
@@ -3267,7 +3291,12 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3267
3291
  this._element.appendChild(this.leftActionsContainer);
3268
3292
  this._element.appendChild(this.voidContainer.element);
3269
3293
  this._element.appendChild(this.rightActionsContainer);
3270
- this.addDisposables(this.voidContainer, this.voidContainer.onDrop((event) => {
3294
+ this.addDisposables(this.voidContainer, this.voidContainer.onDragStart((event) => {
3295
+ this._onGroupDragStart.fire({
3296
+ nativeEvent: event,
3297
+ group: this.group,
3298
+ });
3299
+ }), this.voidContainer.onDrop((event) => {
3271
3300
  this._onDrop.fire({
3272
3301
  event: event.nativeEvent,
3273
3302
  index: this.tabs.length,
@@ -3313,7 +3342,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3313
3342
  }
3314
3343
  }
3315
3344
  delete(id) {
3316
- const index = this.tabs.findIndex((tab) => tab.value.panelId === id);
3345
+ const index = this.tabs.findIndex((tab) => tab.value.panel.id === id);
3317
3346
  const tabToRemove = this.tabs.splice(index, 1)[0];
3318
3347
  const { value, disposable } = tabToRemove;
3319
3348
  disposable.dispose();
@@ -3322,21 +3351,23 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3322
3351
  }
3323
3352
  setActivePanel(panel) {
3324
3353
  this.tabs.forEach((tab) => {
3325
- const isActivePanel = panel.id === tab.value.panelId;
3354
+ const isActivePanel = panel.id === tab.value.panel.id;
3326
3355
  tab.value.setActive(isActivePanel);
3327
3356
  });
3328
3357
  }
3329
3358
  openPanel(panel, index = this.tabs.length) {
3330
3359
  var _a;
3331
- if (this.tabs.find((tab) => tab.value.panelId === panel.id)) {
3360
+ if (this.tabs.find((tab) => tab.value.panel.id === panel.id)) {
3332
3361
  return;
3333
3362
  }
3334
- const tabToAdd = new Tab(panel.id, this.accessor, this.group);
3363
+ const tab = new Tab(panel, this.accessor, this.group);
3335
3364
  if (!((_a = panel.view) === null || _a === void 0 ? void 0 : _a.tab)) {
3336
3365
  throw new Error('invalid header component');
3337
3366
  }
3338
- tabToAdd.setContent(panel.view.tab);
3339
- const disposable = CompositeDisposable.from(tabToAdd.onChanged((event) => {
3367
+ tab.setContent(panel.view.tab);
3368
+ const disposable = new CompositeDisposable(tab.onDragStart((event) => {
3369
+ this._onTabDragStart.fire({ nativeEvent: event, panel });
3370
+ }), tab.onChanged((event) => {
3340
3371
  var _a;
3341
3372
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3342
3373
  const isFloatingWithOnePanel = this.group.api.isFloating && this.size === 1;
@@ -3344,8 +3375,8 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3344
3375
  !isFloatingWithOnePanel &&
3345
3376
  event.shiftKey) {
3346
3377
  event.preventDefault();
3347
- const panel = this.accessor.getGroupPanel(tabToAdd.panelId);
3348
- const { top, left } = tabToAdd.element.getBoundingClientRect();
3378
+ const panel = this.accessor.getGroupPanel(tab.panel.id);
3379
+ const { top, left } = tab.element.getBoundingClientRect();
3349
3380
  const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
3350
3381
  this.accessor.addFloatingGroup(panel, {
3351
3382
  x: left - rootLeft,
@@ -3362,13 +3393,13 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3362
3393
  this.group.model.openPanel(panel, {
3363
3394
  skipFocus: alreadyFocused,
3364
3395
  });
3365
- }), tabToAdd.onDrop((event) => {
3396
+ }), tab.onDrop((event) => {
3366
3397
  this._onDrop.fire({
3367
3398
  event: event.nativeEvent,
3368
- index: this.tabs.findIndex((x) => x.value === tabToAdd),
3399
+ index: this.tabs.findIndex((x) => x.value === tab),
3369
3400
  });
3370
3401
  }));
3371
- const value = { value: tabToAdd, disposable };
3402
+ const value = { value: tab, disposable };
3372
3403
  this.addTab(value, index);
3373
3404
  }
3374
3405
  closePanel(panel) {
@@ -3396,7 +3427,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3396
3427
  }
3397
3428
  set locked(value) {
3398
3429
  this._locked = value;
3399
- toggleClass(this.container, 'locked-groupview', value);
3430
+ toggleClass(this.container, 'locked-groupview', value === 'no-drop-target' || value);
3400
3431
  }
3401
3432
  get isActive() {
3402
3433
  return this._isGroupActive;
@@ -3453,6 +3484,10 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3453
3484
  this.onMove = this._onMove.event;
3454
3485
  this._onDidDrop = new Emitter();
3455
3486
  this.onDidDrop = this._onDidDrop.event;
3487
+ this._onTabDragStart = new Emitter();
3488
+ this.onTabDragStart = this._onTabDragStart.event;
3489
+ this._onGroupDragStart = new Emitter();
3490
+ this.onGroupDragStart = this._onGroupDragStart.event;
3456
3491
  this._onDidAddPanel = new Emitter();
3457
3492
  this.onDidAddPanel = this._onDidAddPanel.event;
3458
3493
  this._onDidRemovePanel = new Emitter();
@@ -3465,7 +3500,8 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3465
3500
  this.dropTarget = new Droptarget(this.contentContainer.element, {
3466
3501
  acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
3467
3502
  canDisplayOverlay: (event, position) => {
3468
- if (this.locked && position === 'center') {
3503
+ if (this.locked === 'no-drop-target' ||
3504
+ (this.locked && position === 'center')) {
3469
3505
  return false;
3470
3506
  }
3471
3507
  const data = getPanelData();
@@ -3491,8 +3527,12 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3491
3527
  });
3492
3528
  container.append(this.tabsContainer.element, this.contentContainer.element);
3493
3529
  this.header.hidden = !!options.hideHeader;
3494
- this.locked = !!options.locked;
3495
- this.addDisposables(this.tabsContainer.onDrop((event) => {
3530
+ this.locked = options.locked || false;
3531
+ this.addDisposables(this._onTabDragStart, this._onGroupDragStart, this.tabsContainer.onTabDragStart((event) => {
3532
+ this._onTabDragStart.fire(event);
3533
+ }), this.tabsContainer.onGroupDragStart((event) => {
3534
+ this._onGroupDragStart.fire(event);
3535
+ }), this.tabsContainer.onDrop((event) => {
3496
3536
  this.handleDropEvent(event.event, 'center', event.index);
3497
3537
  }), this.contentContainer.onDidFocus(() => {
3498
3538
  this.accessor.doSetGroupActive(this.groupPanel, true);
@@ -3547,8 +3587,8 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3547
3587
  activeView: (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.id,
3548
3588
  id: this.id,
3549
3589
  };
3550
- if (this.locked) {
3551
- result.locked = true;
3590
+ if (this.locked !== false) {
3591
+ result.locked = this.locked;
3552
3592
  }
3553
3593
  if (this.header.hidden) {
3554
3594
  result.hideHeader = true;
@@ -3798,6 +3838,9 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
3798
3838
  return false;
3799
3839
  }
3800
3840
  handleDropEvent(event, position, index) {
3841
+ if (this.locked === 'no-drop-target') {
3842
+ return;
3843
+ }
3801
3844
  const data = getPanelData();
3802
3845
  if (data && data.viewId === this.accessor.id) {
3803
3846
  if (data.panelId === null) {
@@ -5255,6 +5298,12 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5255
5298
  return pushToTop;
5256
5299
  })();
5257
5300
  class Overlay extends CompositeDisposable {
5301
+ set minimumInViewportWidth(value) {
5302
+ this.options.minimumInViewportWidth = value;
5303
+ }
5304
+ set minimumInViewportHeight(value) {
5305
+ this.options.minimumInViewportHeight = value;
5306
+ }
5258
5307
  constructor(options) {
5259
5308
  super();
5260
5309
  this.options = options;
@@ -5300,9 +5349,11 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5300
5349
  const overlayRect = this._element.getBoundingClientRect();
5301
5350
  // region: ensure bounds within allowable limits
5302
5351
  // a minimum width of minimumViewportWidth must be inside the viewport
5303
- const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5352
+ const xOffset = Math.max(0, this.getMinimumWidth(overlayRect.width));
5304
5353
  // a minimum height of minimumViewportHeight must be inside the viewport
5305
- const yOffset = Math.max(0, overlayRect.height - this.options.minimumInViewportHeight);
5354
+ const yOffset = typeof this.options.minimumInViewportHeight === 'number'
5355
+ ? Math.max(0, this.getMinimumHeight(overlayRect.height))
5356
+ : 0;
5306
5357
  const left = clamp(overlayRect.left - containerRect.left, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5307
5358
  const top = clamp(overlayRect.top - containerRect.top, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5308
5359
  this._element.style.left = `${left}px`;
@@ -5348,9 +5399,10 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5348
5399
  y: e.clientY - overlayRect.top,
5349
5400
  };
5350
5401
  }
5351
- const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5352
- const yOffset = Math.max(0, overlayRect.height -
5353
- this.options.minimumInViewportHeight);
5402
+ const xOffset = Math.max(0, this.getMinimumWidth(overlayRect.width));
5403
+ const yOffset = Math.max(0, this.options.minimumInViewportHeight
5404
+ ? this.getMinimumHeight(overlayRect.height)
5405
+ : 0);
5354
5406
  const left = clamp(x - offset.x, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5355
5407
  const top = clamp(y - offset.y, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5356
5408
  this.setBounds({ top, left });
@@ -5424,14 +5476,11 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5424
5476
  let height = undefined;
5425
5477
  let left = undefined;
5426
5478
  let width = undefined;
5427
- const minimumInViewportHeight = this.options.minimumInViewportHeight;
5428
- const minimumInViewportWidth = this.options.minimumInViewportWidth;
5429
- function moveTop() {
5479
+ const moveTop = () => {
5430
5480
  top = clamp(y, -Number.MAX_VALUE, startPosition.originalY +
5431
5481
  startPosition.originalHeight >
5432
5482
  containerRect.height
5433
- ? containerRect.height -
5434
- minimumInViewportHeight
5483
+ ? this.getMinimumHeight(containerRect.height)
5435
5484
  : Math.max(0, startPosition.originalY +
5436
5485
  startPosition.originalHeight -
5437
5486
  Overlay.MINIMUM_HEIGHT));
@@ -5439,21 +5488,23 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5439
5488
  startPosition.originalY +
5440
5489
  startPosition.originalHeight -
5441
5490
  top;
5442
- }
5443
- function moveBottom() {
5491
+ };
5492
+ const moveBottom = () => {
5444
5493
  top =
5445
5494
  startPosition.originalY -
5446
5495
  startPosition.originalHeight;
5447
- height = clamp(y - top, top < 0
5448
- ? -top + minimumInViewportHeight
5496
+ height = clamp(y - top, top < 0 &&
5497
+ typeof this.options
5498
+ .minimumInViewportHeight === 'number'
5499
+ ? -top +
5500
+ this.options.minimumInViewportHeight
5449
5501
  : Overlay.MINIMUM_HEIGHT, Number.MAX_VALUE);
5450
- }
5451
- function moveLeft() {
5502
+ };
5503
+ const moveLeft = () => {
5452
5504
  left = clamp(x, -Number.MAX_VALUE, startPosition.originalX +
5453
5505
  startPosition.originalWidth >
5454
5506
  containerRect.width
5455
- ? containerRect.width -
5456
- minimumInViewportWidth
5507
+ ? this.getMinimumWidth(containerRect.width)
5457
5508
  : Math.max(0, startPosition.originalX +
5458
5509
  startPosition.originalWidth -
5459
5510
  Overlay.MINIMUM_WIDTH));
@@ -5461,15 +5512,18 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5461
5512
  startPosition.originalX +
5462
5513
  startPosition.originalWidth -
5463
5514
  left;
5464
- }
5465
- function moveRight() {
5515
+ };
5516
+ const moveRight = () => {
5466
5517
  left =
5467
5518
  startPosition.originalX -
5468
5519
  startPosition.originalWidth;
5469
- width = clamp(x - left, left < 0
5470
- ? -left + minimumInViewportWidth
5520
+ width = clamp(x - left, left < 0 &&
5521
+ typeof this.options
5522
+ .minimumInViewportWidth === 'number'
5523
+ ? -left +
5524
+ this.options.minimumInViewportWidth
5471
5525
  : Overlay.MINIMUM_WIDTH, Number.MAX_VALUE);
5472
- }
5526
+ };
5473
5527
  switch (direction) {
5474
5528
  case 'top':
5475
5529
  moveTop();
@@ -5513,6 +5567,18 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5513
5567
  }));
5514
5568
  }));
5515
5569
  }
5570
+ getMinimumWidth(width) {
5571
+ if (typeof this.options.minimumInViewportWidth === 'number') {
5572
+ return width - this.options.minimumInViewportWidth;
5573
+ }
5574
+ return 0;
5575
+ }
5576
+ getMinimumHeight(height) {
5577
+ if (typeof this.options.minimumInViewportHeight === 'number') {
5578
+ return height - this.options.minimumInViewportHeight;
5579
+ }
5580
+ return height;
5581
+ }
5516
5582
  dispose() {
5517
5583
  this._element.remove();
5518
5584
  super.dispose();
@@ -5533,6 +5599,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5533
5599
  }
5534
5600
  }
5535
5601
 
5602
+ const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100;
5536
5603
  class DockviewComponent extends BaseGrid {
5537
5604
  get orientation() {
5538
5605
  return this.gridview.orientation;
@@ -5563,6 +5630,10 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5563
5630
  this.nextGroupId = sequentialNumberGenerator();
5564
5631
  this._deserializer = new DefaultDockviewDeserialzier(this);
5565
5632
  this.watermark = null;
5633
+ this._onWillDragPanel = new Emitter();
5634
+ this.onWillDragPanel = this._onWillDragPanel.event;
5635
+ this._onWillDragGroup = new Emitter();
5636
+ this.onWillDragGroup = this._onWillDragGroup.event;
5566
5637
  this._onDidDrop = new Emitter();
5567
5638
  this.onDidDrop = this._onDidDrop.event;
5568
5639
  this._onDidRemovePanel = new Emitter();
@@ -5575,7 +5646,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5575
5646
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
5576
5647
  this.floatingGroups = [];
5577
5648
  toggleClass(this.gridview.element, 'dv-dockview', true);
5578
- this.addDisposables(this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
5649
+ this.addDisposables(this._onWillDragPanel, this._onWillDragGroup, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
5579
5650
  this.updateWatermark();
5580
5651
  }), exports.DockviewEvent.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => {
5581
5652
  this._bufferOnDidLayoutChange.fire();
@@ -5612,7 +5683,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5612
5683
  return true;
5613
5684
  }
5614
5685
  if (this.options.showDndOverlay) {
5615
- if (position === 'center') {
5686
+ if (position === 'center' && this.gridview.length !== 0) {
5616
5687
  /**
5617
5688
  * for external events only show the four-corner drag overlays, disable
5618
5689
  * the center position so that external drag events can fall through to the group
@@ -5648,7 +5719,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5648
5719
  this.updateWatermark();
5649
5720
  }
5650
5721
  addFloatingGroup(item, coord, options) {
5651
- var _a, _b;
5722
+ var _a, _b, _c, _d, _e, _f;
5652
5723
  let group;
5653
5724
  if (item instanceof DockviewPanel) {
5654
5725
  group = this.createGroup();
@@ -5676,8 +5747,12 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5676
5747
  width: (_b = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _b !== void 0 ? _b : 300,
5677
5748
  left: overlayLeft,
5678
5749
  top: overlayTop,
5679
- minimumInViewportWidth: 100,
5680
- minimumInViewportHeight: 100,
5750
+ minimumInViewportWidth: this.options.floatingGroupBounds === 'boundedWithinViewport'
5751
+ ? undefined
5752
+ : (_d = (_c = this.options.floatingGroupBounds) === null || _c === void 0 ? void 0 : _c.minimumWidthWithinViewport) !== null && _d !== void 0 ? _d : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
5753
+ minimumInViewportHeight: this.options.floatingGroupBounds === 'boundedWithinViewport'
5754
+ ? undefined
5755
+ : (_f = (_e = this.options.floatingGroupBounds) === null || _e === void 0 ? void 0 : _e.minimumHeightWithinViewport) !== null && _f !== void 0 ? _f : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
5681
5756
  });
5682
5757
  const el = group.element.querySelector('.void-container');
5683
5758
  if (!el) {
@@ -5748,12 +5823,37 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
5748
5823
  }
5749
5824
  }
5750
5825
  updateOptions(options) {
5826
+ var _a, _b;
5751
5827
  const hasOrientationChanged = typeof options.orientation === 'string' &&
5752
5828
  this.gridview.orientation !== options.orientation;
5829
+ const hasFloatingGroupOptionsChanged = options.floatingGroupBounds !== undefined &&
5830
+ options.floatingGroupBounds !== this.options.floatingGroupBounds;
5753
5831
  this._options = Object.assign(Object.assign({}, this.options), options);
5754
5832
  if (hasOrientationChanged) {
5755
5833
  this.gridview.orientation = options.orientation;
5756
5834
  }
5835
+ if (hasFloatingGroupOptionsChanged) {
5836
+ for (const group of this.floatingGroups) {
5837
+ switch (this.options.floatingGroupBounds) {
5838
+ case 'boundedWithinViewport':
5839
+ group.overlay.minimumInViewportHeight = undefined;
5840
+ group.overlay.minimumInViewportWidth = undefined;
5841
+ break;
5842
+ case undefined:
5843
+ group.overlay.minimumInViewportHeight =
5844
+ DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE;
5845
+ group.overlay.minimumInViewportWidth =
5846
+ DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE;
5847
+ break;
5848
+ default:
5849
+ group.overlay.minimumInViewportHeight =
5850
+ (_a = this.options.floatingGroupBounds) === null || _a === void 0 ? void 0 : _a.minimumHeightWithinViewport;
5851
+ group.overlay.minimumInViewportWidth =
5852
+ (_b = this.options.floatingGroupBounds) === null || _b === void 0 ? void 0 : _b.minimumWidthWithinViewport;
5853
+ }
5854
+ group.overlay.setBounds({});
5855
+ }
5856
+ }
5757
5857
  this.layout(this.gridview.width, this.gridview.height, true);
5758
5858
  }
5759
5859
  layout(width, height, forceResize) {
@@ -6236,7 +6336,11 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6236
6336
  const view = new DockviewGroupPanel(this, id, options);
6237
6337
  view.init({ params: {}, accessor: null }); // required to initialized .part and allow for correct disposal of group
6238
6338
  if (!this._groups.has(view.id)) {
6239
- const disposable = new CompositeDisposable(view.model.onMove((event) => {
6339
+ const disposable = new CompositeDisposable(view.model.onTabDragStart((event) => {
6340
+ this._onWillDragPanel.fire(event);
6341
+ }), view.model.onGroupDragStart((event) => {
6342
+ this._onWillDragGroup.fire(event);
6343
+ }), view.model.onMove((event) => {
6240
6344
  const { groupId, itemId, target, index } = event;
6241
6345
  this.moveGroupOrPanel(view, groupId, itemId, target, index);
6242
6346
  }), view.model.onDidDrop((event) => {
@@ -6275,13 +6379,6 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
6275
6379
  var _a;
6276
6380
  return (_a = Array.from(this._groups.values()).find((group) => group.value.model.containsPanel(panel))) === null || _a === void 0 ? void 0 : _a.value;
6277
6381
  }
6278
- dispose() {
6279
- this._onDidActivePanelChange.dispose();
6280
- this._onDidAddPanel.dispose();
6281
- this._onDidRemovePanel.dispose();
6282
- this._onDidLayoutFromJSON.dispose();
6283
- super.dispose();
6284
- }
6285
6382
  }
6286
6383
 
6287
6384
  class GridviewComponent extends BaseGrid {
@@ -7579,6 +7676,7 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
7579
7676
  createRightHeaderActionsElement: createGroupControlElement(props.rightHeaderActionsComponent, { addPortal }),
7580
7677
  singleTabMode: props.singleTabMode,
7581
7678
  disableFloatingGroups: props.disableFloatingGroups,
7679
+ floatingGroupBounds: props.floatingGroupBounds,
7582
7680
  });
7583
7681
  const { clientWidth, clientHeight } = domRef.current;
7584
7682
  dockview.layout(clientWidth, clientHeight);
@@ -7613,6 +7711,14 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
7613
7711
  frameworkComponents: props.components,
7614
7712
  });
7615
7713
  }, [props.components]);
7714
+ React__namespace.useEffect(() => {
7715
+ if (!dockviewRef.current) {
7716
+ return;
7717
+ }
7718
+ dockviewRef.current.updateOptions({
7719
+ floatingGroupBounds: props.floatingGroupBounds,
7720
+ });
7721
+ }, [props.floatingGroupBounds]);
7616
7722
  React__namespace.useEffect(() => {
7617
7723
  if (!dockviewRef.current) {
7618
7724
  return;
@@ -7719,25 +7825,32 @@ define(['exports', 'react', 'react-dom'], (function (exports, React, ReactDOM) {
7719
7825
  React__namespace.createElement("path", { d: "M2.1 27.3L0 25.2L11.55 13.65L0 2.1L2.1 0L13.65 11.55L25.2 0L27.3 2.1L15.75 13.65L27.3 25.2L25.2 27.3L13.65 15.75L2.1 27.3Z" })));
7720
7826
 
7721
7827
  const DockviewDefaultTab = (_a) => {
7722
- var { api, containerApi: _containerApi, params: _params } = _a, rest = __rest(_a, ["api", "containerApi", "params"]);
7828
+ var { api, containerApi: _containerApi, params: _params, hideClose, closeActionOverride } = _a, rest = __rest(_a, ["api", "containerApi", "params", "hideClose", "closeActionOverride"]);
7723
7829
  const onClose = React__namespace.useCallback((event) => {
7724
- event.stopPropagation();
7725
- api.close();
7726
- }, [api]);
7830
+ event.preventDefault();
7831
+ if (closeActionOverride) {
7832
+ closeActionOverride();
7833
+ }
7834
+ else {
7835
+ api.close();
7836
+ }
7837
+ }, [api, closeActionOverride]);
7838
+ const onMouseDown = React__namespace.useCallback((e) => {
7839
+ e.preventDefault();
7840
+ }, []);
7727
7841
  const onClick = React__namespace.useCallback((event) => {
7842
+ if (event.defaultPrevented) {
7843
+ return;
7844
+ }
7728
7845
  api.setActive();
7729
7846
  if (rest.onClick) {
7730
7847
  rest.onClick(event);
7731
7848
  }
7732
7849
  }, [api, rest.onClick]);
7733
- const iconClassname = React__namespace.useMemo(() => {
7734
- const cn = ['dockview-react-tab-action'];
7735
- return cn.join(',');
7736
- }, []);
7737
- return (React__namespace.createElement("div", Object.assign({}, rest, { onClick: onClick, className: "dockview-react-tab" }),
7850
+ return (React__namespace.createElement("div", Object.assign({ "data-testid": "dockview-default-tab" }, rest, { onClick: onClick, className: "dockview-react-tab" }),
7738
7851
  React__namespace.createElement("span", { className: "dockview-react-tab-title" }, api.title),
7739
- React__namespace.createElement("div", { className: iconClassname, onClick: onClose },
7740
- React__namespace.createElement(CloseButton, null))));
7852
+ !hideClose && (React__namespace.createElement("div", { className: "dv-react-tab-close-btn", onMouseDown: onMouseDown, onClick: onClose },
7853
+ React__namespace.createElement(CloseButton, null)))));
7741
7854
  };
7742
7855
 
7743
7856
  class ReactPanelView extends SplitviewPanel {