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
  */
@@ -264,9 +264,6 @@
264
264
  get isDisposed() {
265
265
  return this._isDisposed;
266
266
  }
267
- static from(...args) {
268
- return new CompositeDisposable(...args);
269
- }
270
267
  constructor(...args) {
271
268
  this._isDisposed = false;
272
269
  this._disposables = args;
@@ -2470,6 +2467,12 @@
2470
2467
  get onDidDrop() {
2471
2468
  return this.component.onDidDrop;
2472
2469
  }
2470
+ get onWillDragGroup() {
2471
+ return this.component.onWillDragGroup;
2472
+ }
2473
+ get onWillDragPanel() {
2474
+ return this.component.onWillDragPanel;
2475
+ }
2473
2476
  get panels() {
2474
2477
  return this.component.panels;
2475
2478
  }
@@ -2932,7 +2935,7 @@
2932
2935
  }
2933
2936
  configure() {
2934
2937
  this.addDisposables(this._onDragStart, addDisposableListener(this.el, 'dragstart', (event) => {
2935
- if (this.isCancelled(event)) {
2938
+ if (event.defaultPrevented || this.isCancelled(event)) {
2936
2939
  event.preventDefault();
2937
2940
  return;
2938
2941
  }
@@ -2952,19 +2955,23 @@
2952
2955
  }
2953
2956
  this.el.classList.add('dv-dragged');
2954
2957
  setTimeout(() => this.el.classList.remove('dv-dragged'), 0);
2955
- this.dataDisposable.value = this.getData(event.dataTransfer);
2958
+ this.dataDisposable.value = this.getData(event);
2959
+ this._onDragStart.fire(event);
2956
2960
  if (event.dataTransfer) {
2957
2961
  event.dataTransfer.effectAllowed = 'move';
2958
- /**
2959
- * Although this is not used by dockview many third party dnd libraries will check
2960
- * dataTransfer.types to determine valid drag events.
2961
- *
2962
- * For example: in react-dnd if dataTransfer.types is not set then the dragStart event will be cancelled
2963
- * through .preventDefault(). Since this is applied globally to all drag events this would break dockviews
2964
- * dnd logic. You can see the code at
2965
- * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
2966
- */
2967
- event.dataTransfer.setData('text/plain', '__dockview_internal_drag_event__');
2962
+ const hasData = event.dataTransfer.items.length > 0;
2963
+ if (!hasData) {
2964
+ /**
2965
+ * Although this is not used by dockview many third party dnd libraries will check
2966
+ * dataTransfer.types to determine valid drag events.
2967
+ *
2968
+ * For example: in react-dnd if dataTransfer.types is not set then the dragStart event will be cancelled
2969
+ * through .preventDefault(). Since this is applied globally to all drag events this would break dockviews
2970
+ * dnd logic. You can see the code at
2971
+ * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
2972
+ */
2973
+ event.dataTransfer.setData('text/plain', '__dockview_internal_drag_event__');
2974
+ }
2968
2975
  }
2969
2976
  }), addDisposableListener(this.el, 'dragend', () => {
2970
2977
  this.pointerEventsDisposable.dispose();
@@ -2973,44 +2980,45 @@
2973
2980
  }
2974
2981
  }
2975
2982
 
2983
+ class TabDragHandler extends DragHandler {
2984
+ constructor(element, accessor, group, panel) {
2985
+ super(element);
2986
+ this.accessor = accessor;
2987
+ this.group = group;
2988
+ this.panel = panel;
2989
+ this.panelTransfer = LocalSelectionTransfer.getInstance();
2990
+ }
2991
+ getData(event) {
2992
+ this.panelTransfer.setData([new PanelTransfer(this.accessor.id, this.group.id, this.panel.id)], PanelTransfer.prototype);
2993
+ return {
2994
+ dispose: () => {
2995
+ this.panelTransfer.clearData(PanelTransfer.prototype);
2996
+ },
2997
+ };
2998
+ }
2999
+ }
2976
3000
  class Tab extends CompositeDisposable {
2977
3001
  get element() {
2978
3002
  return this._element;
2979
3003
  }
2980
- constructor(panelId, accessor, group) {
3004
+ constructor(panel, accessor, group) {
2981
3005
  super();
2982
- this.panelId = panelId;
3006
+ this.panel = panel;
2983
3007
  this.accessor = accessor;
2984
3008
  this.group = group;
3009
+ this.content = undefined;
2985
3010
  this._onChanged = new Emitter();
2986
3011
  this.onChanged = this._onChanged.event;
2987
3012
  this._onDropped = new Emitter();
2988
3013
  this.onDrop = this._onDropped.event;
3014
+ this._onDragStart = new Emitter();
3015
+ this.onDragStart = this._onDragStart.event;
2989
3016
  this._element = document.createElement('div');
2990
3017
  this._element.className = 'tab';
2991
3018
  this._element.tabIndex = 0;
2992
3019
  this._element.draggable = true;
2993
3020
  toggleClass(this.element, 'inactive-tab', true);
2994
- this.addDisposables(this._onChanged, this._onDropped, new (class Handler extends DragHandler {
2995
- constructor() {
2996
- super(...arguments);
2997
- this.panelTransfer = LocalSelectionTransfer.getInstance();
2998
- }
2999
- getData() {
3000
- this.panelTransfer.setData([new PanelTransfer(accessor.id, group.id, panelId)], PanelTransfer.prototype);
3001
- return {
3002
- dispose: () => {
3003
- this.panelTransfer.clearData(PanelTransfer.prototype);
3004
- },
3005
- };
3006
- }
3007
- })(this._element));
3008
- this.addDisposables(addDisposableListener(this._element, 'mousedown', (event) => {
3009
- if (event.defaultPrevented) {
3010
- return;
3011
- }
3012
- this._onChanged.fire(event);
3013
- }));
3021
+ const dragHandler = new TabDragHandler(this._element, this.accessor, this.group, this.panel);
3014
3022
  this.droptarget = new Droptarget(this._element, {
3015
3023
  acceptedTargetZones: ['center'],
3016
3024
  canDisplayOverlay: (event, position) => {
@@ -3024,12 +3032,19 @@
3024
3032
  // don't allow group move to drop on self
3025
3033
  return false;
3026
3034
  }
3027
- return this.panelId !== data.panelId;
3035
+ return this.panel.id !== data.panelId;
3028
3036
  }
3029
3037
  return this.group.model.canDisplayOverlay(event, position, exports.DockviewDropTargets.Tab);
3030
3038
  },
3031
3039
  });
3032
- this.addDisposables(this.droptarget.onDrop((event) => {
3040
+ this.addDisposables(this._onChanged, this._onDropped, this._onDragStart, dragHandler.onDragStart((event) => {
3041
+ this._onDragStart.fire(event);
3042
+ }), dragHandler, addDisposableListener(this._element, 'mousedown', (event) => {
3043
+ if (event.defaultPrevented) {
3044
+ return;
3045
+ }
3046
+ this._onChanged.fire(event);
3047
+ }), this.droptarget.onDrop((event) => {
3033
3048
  this._onDropped.fire(event);
3034
3049
  }), this.droptarget);
3035
3050
  }
@@ -3061,9 +3076,9 @@
3061
3076
  }
3062
3077
 
3063
3078
  class GroupDragHandler extends DragHandler {
3064
- constructor(element, accessorId, group) {
3079
+ constructor(element, accessor, group) {
3065
3080
  super(element);
3066
- this.accessorId = accessorId;
3081
+ this.accessor = accessor;
3067
3082
  this.group = group;
3068
3083
  this.panelTransfer = LocalSelectionTransfer.getInstance();
3069
3084
  this.addDisposables(addDisposableListener(element, 'mousedown', (e) => {
@@ -3083,8 +3098,9 @@
3083
3098
  }
3084
3099
  return false;
3085
3100
  }
3086
- getData(dataTransfer) {
3087
- this.panelTransfer.setData([new PanelTransfer(this.accessorId, this.group.id, null)], PanelTransfer.prototype);
3101
+ getData(dragEvent) {
3102
+ const dataTransfer = dragEvent.dataTransfer;
3103
+ this.panelTransfer.setData([new PanelTransfer(this.accessor.id, this.group.id, null)], PanelTransfer.prototype);
3088
3104
  const style = window.getComputedStyle(this.el);
3089
3105
  const bgColor = style.getPropertyValue('--dv-activegroup-visiblepanel-tab-background-color');
3090
3106
  const color = style.getPropertyValue('--dv-activegroup-visiblepanel-tab-color');
@@ -3119,14 +3135,16 @@
3119
3135
  this.group = group;
3120
3136
  this._onDrop = new Emitter();
3121
3137
  this.onDrop = this._onDrop.event;
3138
+ this._onDragStart = new Emitter();
3139
+ this.onDragStart = this._onDragStart.event;
3122
3140
  this._element = document.createElement('div');
3123
3141
  this._element.className = 'void-container';
3124
3142
  this._element.tabIndex = 0;
3125
3143
  this._element.draggable = true;
3126
- this.addDisposables(this._onDrop, addDisposableListener(this._element, 'click', () => {
3144
+ this.addDisposables(this._onDrop, this._onDragStart, addDisposableListener(this._element, 'click', () => {
3127
3145
  this.accessor.doSetGroupActive(this.group);
3128
3146
  }));
3129
- const handler = new GroupDragHandler(this._element, accessor.id, group);
3147
+ const handler = new GroupDragHandler(this._element, accessor, group);
3130
3148
  this.voidDropTarget = new Droptarget(this._element, {
3131
3149
  acceptedTargetZones: ['center'],
3132
3150
  canDisplayOverlay: (event, position) => {
@@ -3144,7 +3162,9 @@
3144
3162
  return group.model.canDisplayOverlay(event, position, exports.DockviewDropTargets.Panel);
3145
3163
  },
3146
3164
  });
3147
- this.addDisposables(handler, this.voidDropTarget.onDrop((event) => {
3165
+ this.addDisposables(handler, handler.onDragStart((event) => {
3166
+ this._onDragStart.fire(event);
3167
+ }), this.voidDropTarget.onDrop((event) => {
3148
3168
  this._onDrop.fire(event);
3149
3169
  }), this.voidDropTarget);
3150
3170
  }
@@ -3152,7 +3172,7 @@
3152
3172
 
3153
3173
  class TabsContainer extends CompositeDisposable {
3154
3174
  get panels() {
3155
- return this.tabs.map((_) => _.value.panelId);
3175
+ return this.tabs.map((_) => _.value.panel.id);
3156
3176
  }
3157
3177
  get size() {
3158
3178
  return this.tabs.length;
@@ -3206,7 +3226,7 @@
3206
3226
  this.tabs[this.selectedIndex].value === tab);
3207
3227
  }
3208
3228
  indexOf(id) {
3209
- return this.tabs.findIndex((tab) => tab.value.panelId === id);
3229
+ return this.tabs.findIndex((tab) => tab.value.panel.id === id);
3210
3230
  }
3211
3231
  constructor(accessor, group) {
3212
3232
  super();
@@ -3217,7 +3237,11 @@
3217
3237
  this._hidden = false;
3218
3238
  this._onDrop = new Emitter();
3219
3239
  this.onDrop = this._onDrop.event;
3220
- this.addDisposables(this._onDrop);
3240
+ this._onTabDragStart = new Emitter();
3241
+ this.onTabDragStart = this._onTabDragStart.event;
3242
+ this._onGroupDragStart = new Emitter();
3243
+ this.onGroupDragStart = this._onGroupDragStart.event;
3244
+ this.addDisposables(this._onDrop, this._onTabDragStart, this._onGroupDragStart);
3221
3245
  this._element = document.createElement('div');
3222
3246
  this._element.className = 'tabs-and-actions-container';
3223
3247
  toggleClass(this._element, 'dv-full-width-single-tab', this.accessor.options.singleTabMode === 'fullwidth');
@@ -3241,7 +3265,12 @@
3241
3265
  this._element.appendChild(this.leftActionsContainer);
3242
3266
  this._element.appendChild(this.voidContainer.element);
3243
3267
  this._element.appendChild(this.rightActionsContainer);
3244
- this.addDisposables(this.voidContainer, this.voidContainer.onDrop((event) => {
3268
+ this.addDisposables(this.voidContainer, this.voidContainer.onDragStart((event) => {
3269
+ this._onGroupDragStart.fire({
3270
+ nativeEvent: event,
3271
+ group: this.group,
3272
+ });
3273
+ }), this.voidContainer.onDrop((event) => {
3245
3274
  this._onDrop.fire({
3246
3275
  event: event.nativeEvent,
3247
3276
  index: this.tabs.length,
@@ -3287,7 +3316,7 @@
3287
3316
  }
3288
3317
  }
3289
3318
  delete(id) {
3290
- const index = this.tabs.findIndex((tab) => tab.value.panelId === id);
3319
+ const index = this.tabs.findIndex((tab) => tab.value.panel.id === id);
3291
3320
  const tabToRemove = this.tabs.splice(index, 1)[0];
3292
3321
  const { value, disposable } = tabToRemove;
3293
3322
  disposable.dispose();
@@ -3296,21 +3325,23 @@
3296
3325
  }
3297
3326
  setActivePanel(panel) {
3298
3327
  this.tabs.forEach((tab) => {
3299
- const isActivePanel = panel.id === tab.value.panelId;
3328
+ const isActivePanel = panel.id === tab.value.panel.id;
3300
3329
  tab.value.setActive(isActivePanel);
3301
3330
  });
3302
3331
  }
3303
3332
  openPanel(panel, index = this.tabs.length) {
3304
3333
  var _a;
3305
- if (this.tabs.find((tab) => tab.value.panelId === panel.id)) {
3334
+ if (this.tabs.find((tab) => tab.value.panel.id === panel.id)) {
3306
3335
  return;
3307
3336
  }
3308
- const tabToAdd = new Tab(panel.id, this.accessor, this.group);
3337
+ const tab = new Tab(panel, this.accessor, this.group);
3309
3338
  if (!((_a = panel.view) === null || _a === void 0 ? void 0 : _a.tab)) {
3310
3339
  throw new Error('invalid header component');
3311
3340
  }
3312
- tabToAdd.setContent(panel.view.tab);
3313
- const disposable = CompositeDisposable.from(tabToAdd.onChanged((event) => {
3341
+ tab.setContent(panel.view.tab);
3342
+ const disposable = new CompositeDisposable(tab.onDragStart((event) => {
3343
+ this._onTabDragStart.fire({ nativeEvent: event, panel });
3344
+ }), tab.onChanged((event) => {
3314
3345
  var _a;
3315
3346
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3316
3347
  const isFloatingWithOnePanel = this.group.api.isFloating && this.size === 1;
@@ -3318,8 +3349,8 @@
3318
3349
  !isFloatingWithOnePanel &&
3319
3350
  event.shiftKey) {
3320
3351
  event.preventDefault();
3321
- const panel = this.accessor.getGroupPanel(tabToAdd.panelId);
3322
- const { top, left } = tabToAdd.element.getBoundingClientRect();
3352
+ const panel = this.accessor.getGroupPanel(tab.panel.id);
3353
+ const { top, left } = tab.element.getBoundingClientRect();
3323
3354
  const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
3324
3355
  this.accessor.addFloatingGroup(panel, {
3325
3356
  x: left - rootLeft,
@@ -3336,13 +3367,13 @@
3336
3367
  this.group.model.openPanel(panel, {
3337
3368
  skipFocus: alreadyFocused,
3338
3369
  });
3339
- }), tabToAdd.onDrop((event) => {
3370
+ }), tab.onDrop((event) => {
3340
3371
  this._onDrop.fire({
3341
3372
  event: event.nativeEvent,
3342
- index: this.tabs.findIndex((x) => x.value === tabToAdd),
3373
+ index: this.tabs.findIndex((x) => x.value === tab),
3343
3374
  });
3344
3375
  }));
3345
- const value = { value: tabToAdd, disposable };
3376
+ const value = { value: tab, disposable };
3346
3377
  this.addTab(value, index);
3347
3378
  }
3348
3379
  closePanel(panel) {
@@ -3370,7 +3401,7 @@
3370
3401
  }
3371
3402
  set locked(value) {
3372
3403
  this._locked = value;
3373
- toggleClass(this.container, 'locked-groupview', value);
3404
+ toggleClass(this.container, 'locked-groupview', value === 'no-drop-target' || value);
3374
3405
  }
3375
3406
  get isActive() {
3376
3407
  return this._isGroupActive;
@@ -3427,6 +3458,10 @@
3427
3458
  this.onMove = this._onMove.event;
3428
3459
  this._onDidDrop = new Emitter();
3429
3460
  this.onDidDrop = this._onDidDrop.event;
3461
+ this._onTabDragStart = new Emitter();
3462
+ this.onTabDragStart = this._onTabDragStart.event;
3463
+ this._onGroupDragStart = new Emitter();
3464
+ this.onGroupDragStart = this._onGroupDragStart.event;
3430
3465
  this._onDidAddPanel = new Emitter();
3431
3466
  this.onDidAddPanel = this._onDidAddPanel.event;
3432
3467
  this._onDidRemovePanel = new Emitter();
@@ -3439,7 +3474,8 @@
3439
3474
  this.dropTarget = new Droptarget(this.contentContainer.element, {
3440
3475
  acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
3441
3476
  canDisplayOverlay: (event, position) => {
3442
- if (this.locked && position === 'center') {
3477
+ if (this.locked === 'no-drop-target' ||
3478
+ (this.locked && position === 'center')) {
3443
3479
  return false;
3444
3480
  }
3445
3481
  const data = getPanelData();
@@ -3465,8 +3501,12 @@
3465
3501
  });
3466
3502
  container.append(this.tabsContainer.element, this.contentContainer.element);
3467
3503
  this.header.hidden = !!options.hideHeader;
3468
- this.locked = !!options.locked;
3469
- this.addDisposables(this.tabsContainer.onDrop((event) => {
3504
+ this.locked = options.locked || false;
3505
+ this.addDisposables(this._onTabDragStart, this._onGroupDragStart, this.tabsContainer.onTabDragStart((event) => {
3506
+ this._onTabDragStart.fire(event);
3507
+ }), this.tabsContainer.onGroupDragStart((event) => {
3508
+ this._onGroupDragStart.fire(event);
3509
+ }), this.tabsContainer.onDrop((event) => {
3470
3510
  this.handleDropEvent(event.event, 'center', event.index);
3471
3511
  }), this.contentContainer.onDidFocus(() => {
3472
3512
  this.accessor.doSetGroupActive(this.groupPanel, true);
@@ -3521,8 +3561,8 @@
3521
3561
  activeView: (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.id,
3522
3562
  id: this.id,
3523
3563
  };
3524
- if (this.locked) {
3525
- result.locked = true;
3564
+ if (this.locked !== false) {
3565
+ result.locked = this.locked;
3526
3566
  }
3527
3567
  if (this.header.hidden) {
3528
3568
  result.hideHeader = true;
@@ -3772,6 +3812,9 @@
3772
3812
  return false;
3773
3813
  }
3774
3814
  handleDropEvent(event, position, index) {
3815
+ if (this.locked === 'no-drop-target') {
3816
+ return;
3817
+ }
3775
3818
  const data = getPanelData();
3776
3819
  if (data && data.viewId === this.accessor.id) {
3777
3820
  if (data.panelId === null) {
@@ -5229,6 +5272,12 @@
5229
5272
  return pushToTop;
5230
5273
  })();
5231
5274
  class Overlay extends CompositeDisposable {
5275
+ set minimumInViewportWidth(value) {
5276
+ this.options.minimumInViewportWidth = value;
5277
+ }
5278
+ set minimumInViewportHeight(value) {
5279
+ this.options.minimumInViewportHeight = value;
5280
+ }
5232
5281
  constructor(options) {
5233
5282
  super();
5234
5283
  this.options = options;
@@ -5274,9 +5323,11 @@
5274
5323
  const overlayRect = this._element.getBoundingClientRect();
5275
5324
  // region: ensure bounds within allowable limits
5276
5325
  // a minimum width of minimumViewportWidth must be inside the viewport
5277
- const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5326
+ const xOffset = Math.max(0, this.getMinimumWidth(overlayRect.width));
5278
5327
  // a minimum height of minimumViewportHeight must be inside the viewport
5279
- const yOffset = Math.max(0, overlayRect.height - this.options.minimumInViewportHeight);
5328
+ const yOffset = typeof this.options.minimumInViewportHeight === 'number'
5329
+ ? Math.max(0, this.getMinimumHeight(overlayRect.height))
5330
+ : 0;
5280
5331
  const left = clamp(overlayRect.left - containerRect.left, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5281
5332
  const top = clamp(overlayRect.top - containerRect.top, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5282
5333
  this._element.style.left = `${left}px`;
@@ -5322,9 +5373,10 @@
5322
5373
  y: e.clientY - overlayRect.top,
5323
5374
  };
5324
5375
  }
5325
- const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5326
- const yOffset = Math.max(0, overlayRect.height -
5327
- this.options.minimumInViewportHeight);
5376
+ const xOffset = Math.max(0, this.getMinimumWidth(overlayRect.width));
5377
+ const yOffset = Math.max(0, this.options.minimumInViewportHeight
5378
+ ? this.getMinimumHeight(overlayRect.height)
5379
+ : 0);
5328
5380
  const left = clamp(x - offset.x, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5329
5381
  const top = clamp(y - offset.y, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5330
5382
  this.setBounds({ top, left });
@@ -5398,14 +5450,11 @@
5398
5450
  let height = undefined;
5399
5451
  let left = undefined;
5400
5452
  let width = undefined;
5401
- const minimumInViewportHeight = this.options.minimumInViewportHeight;
5402
- const minimumInViewportWidth = this.options.minimumInViewportWidth;
5403
- function moveTop() {
5453
+ const moveTop = () => {
5404
5454
  top = clamp(y, -Number.MAX_VALUE, startPosition.originalY +
5405
5455
  startPosition.originalHeight >
5406
5456
  containerRect.height
5407
- ? containerRect.height -
5408
- minimumInViewportHeight
5457
+ ? this.getMinimumHeight(containerRect.height)
5409
5458
  : Math.max(0, startPosition.originalY +
5410
5459
  startPosition.originalHeight -
5411
5460
  Overlay.MINIMUM_HEIGHT));
@@ -5413,21 +5462,23 @@
5413
5462
  startPosition.originalY +
5414
5463
  startPosition.originalHeight -
5415
5464
  top;
5416
- }
5417
- function moveBottom() {
5465
+ };
5466
+ const moveBottom = () => {
5418
5467
  top =
5419
5468
  startPosition.originalY -
5420
5469
  startPosition.originalHeight;
5421
- height = clamp(y - top, top < 0
5422
- ? -top + minimumInViewportHeight
5470
+ height = clamp(y - top, top < 0 &&
5471
+ typeof this.options
5472
+ .minimumInViewportHeight === 'number'
5473
+ ? -top +
5474
+ this.options.minimumInViewportHeight
5423
5475
  : Overlay.MINIMUM_HEIGHT, Number.MAX_VALUE);
5424
- }
5425
- function moveLeft() {
5476
+ };
5477
+ const moveLeft = () => {
5426
5478
  left = clamp(x, -Number.MAX_VALUE, startPosition.originalX +
5427
5479
  startPosition.originalWidth >
5428
5480
  containerRect.width
5429
- ? containerRect.width -
5430
- minimumInViewportWidth
5481
+ ? this.getMinimumWidth(containerRect.width)
5431
5482
  : Math.max(0, startPosition.originalX +
5432
5483
  startPosition.originalWidth -
5433
5484
  Overlay.MINIMUM_WIDTH));
@@ -5435,15 +5486,18 @@
5435
5486
  startPosition.originalX +
5436
5487
  startPosition.originalWidth -
5437
5488
  left;
5438
- }
5439
- function moveRight() {
5489
+ };
5490
+ const moveRight = () => {
5440
5491
  left =
5441
5492
  startPosition.originalX -
5442
5493
  startPosition.originalWidth;
5443
- width = clamp(x - left, left < 0
5444
- ? -left + minimumInViewportWidth
5494
+ width = clamp(x - left, left < 0 &&
5495
+ typeof this.options
5496
+ .minimumInViewportWidth === 'number'
5497
+ ? -left +
5498
+ this.options.minimumInViewportWidth
5445
5499
  : Overlay.MINIMUM_WIDTH, Number.MAX_VALUE);
5446
- }
5500
+ };
5447
5501
  switch (direction) {
5448
5502
  case 'top':
5449
5503
  moveTop();
@@ -5487,6 +5541,18 @@
5487
5541
  }));
5488
5542
  }));
5489
5543
  }
5544
+ getMinimumWidth(width) {
5545
+ if (typeof this.options.minimumInViewportWidth === 'number') {
5546
+ return width - this.options.minimumInViewportWidth;
5547
+ }
5548
+ return 0;
5549
+ }
5550
+ getMinimumHeight(height) {
5551
+ if (typeof this.options.minimumInViewportHeight === 'number') {
5552
+ return height - this.options.minimumInViewportHeight;
5553
+ }
5554
+ return height;
5555
+ }
5490
5556
  dispose() {
5491
5557
  this._element.remove();
5492
5558
  super.dispose();
@@ -5507,6 +5573,7 @@
5507
5573
  }
5508
5574
  }
5509
5575
 
5576
+ const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100;
5510
5577
  class DockviewComponent extends BaseGrid {
5511
5578
  get orientation() {
5512
5579
  return this.gridview.orientation;
@@ -5537,6 +5604,10 @@
5537
5604
  this.nextGroupId = sequentialNumberGenerator();
5538
5605
  this._deserializer = new DefaultDockviewDeserialzier(this);
5539
5606
  this.watermark = null;
5607
+ this._onWillDragPanel = new Emitter();
5608
+ this.onWillDragPanel = this._onWillDragPanel.event;
5609
+ this._onWillDragGroup = new Emitter();
5610
+ this.onWillDragGroup = this._onWillDragGroup.event;
5540
5611
  this._onDidDrop = new Emitter();
5541
5612
  this.onDidDrop = this._onDidDrop.event;
5542
5613
  this._onDidRemovePanel = new Emitter();
@@ -5549,7 +5620,7 @@
5549
5620
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
5550
5621
  this.floatingGroups = [];
5551
5622
  toggleClass(this.gridview.element, 'dv-dockview', true);
5552
- this.addDisposables(this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
5623
+ this.addDisposables(this._onWillDragPanel, this._onWillDragGroup, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
5553
5624
  this.updateWatermark();
5554
5625
  }), exports.DockviewEvent.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => {
5555
5626
  this._bufferOnDidLayoutChange.fire();
@@ -5586,7 +5657,7 @@
5586
5657
  return true;
5587
5658
  }
5588
5659
  if (this.options.showDndOverlay) {
5589
- if (position === 'center') {
5660
+ if (position === 'center' && this.gridview.length !== 0) {
5590
5661
  /**
5591
5662
  * for external events only show the four-corner drag overlays, disable
5592
5663
  * the center position so that external drag events can fall through to the group
@@ -5622,7 +5693,7 @@
5622
5693
  this.updateWatermark();
5623
5694
  }
5624
5695
  addFloatingGroup(item, coord, options) {
5625
- var _a, _b;
5696
+ var _a, _b, _c, _d, _e, _f;
5626
5697
  let group;
5627
5698
  if (item instanceof DockviewPanel) {
5628
5699
  group = this.createGroup();
@@ -5650,8 +5721,12 @@
5650
5721
  width: (_b = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _b !== void 0 ? _b : 300,
5651
5722
  left: overlayLeft,
5652
5723
  top: overlayTop,
5653
- minimumInViewportWidth: 100,
5654
- minimumInViewportHeight: 100,
5724
+ minimumInViewportWidth: this.options.floatingGroupBounds === 'boundedWithinViewport'
5725
+ ? undefined
5726
+ : (_d = (_c = this.options.floatingGroupBounds) === null || _c === void 0 ? void 0 : _c.minimumWidthWithinViewport) !== null && _d !== void 0 ? _d : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
5727
+ minimumInViewportHeight: this.options.floatingGroupBounds === 'boundedWithinViewport'
5728
+ ? undefined
5729
+ : (_f = (_e = this.options.floatingGroupBounds) === null || _e === void 0 ? void 0 : _e.minimumHeightWithinViewport) !== null && _f !== void 0 ? _f : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
5655
5730
  });
5656
5731
  const el = group.element.querySelector('.void-container');
5657
5732
  if (!el) {
@@ -5722,12 +5797,37 @@
5722
5797
  }
5723
5798
  }
5724
5799
  updateOptions(options) {
5800
+ var _a, _b;
5725
5801
  const hasOrientationChanged = typeof options.orientation === 'string' &&
5726
5802
  this.gridview.orientation !== options.orientation;
5803
+ const hasFloatingGroupOptionsChanged = options.floatingGroupBounds !== undefined &&
5804
+ options.floatingGroupBounds !== this.options.floatingGroupBounds;
5727
5805
  this._options = Object.assign(Object.assign({}, this.options), options);
5728
5806
  if (hasOrientationChanged) {
5729
5807
  this.gridview.orientation = options.orientation;
5730
5808
  }
5809
+ if (hasFloatingGroupOptionsChanged) {
5810
+ for (const group of this.floatingGroups) {
5811
+ switch (this.options.floatingGroupBounds) {
5812
+ case 'boundedWithinViewport':
5813
+ group.overlay.minimumInViewportHeight = undefined;
5814
+ group.overlay.minimumInViewportWidth = undefined;
5815
+ break;
5816
+ case undefined:
5817
+ group.overlay.minimumInViewportHeight =
5818
+ DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE;
5819
+ group.overlay.minimumInViewportWidth =
5820
+ DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE;
5821
+ break;
5822
+ default:
5823
+ group.overlay.minimumInViewportHeight =
5824
+ (_a = this.options.floatingGroupBounds) === null || _a === void 0 ? void 0 : _a.minimumHeightWithinViewport;
5825
+ group.overlay.minimumInViewportWidth =
5826
+ (_b = this.options.floatingGroupBounds) === null || _b === void 0 ? void 0 : _b.minimumWidthWithinViewport;
5827
+ }
5828
+ group.overlay.setBounds({});
5829
+ }
5830
+ }
5731
5831
  this.layout(this.gridview.width, this.gridview.height, true);
5732
5832
  }
5733
5833
  layout(width, height, forceResize) {
@@ -6210,7 +6310,11 @@
6210
6310
  const view = new DockviewGroupPanel(this, id, options);
6211
6311
  view.init({ params: {}, accessor: null }); // required to initialized .part and allow for correct disposal of group
6212
6312
  if (!this._groups.has(view.id)) {
6213
- const disposable = new CompositeDisposable(view.model.onMove((event) => {
6313
+ const disposable = new CompositeDisposable(view.model.onTabDragStart((event) => {
6314
+ this._onWillDragPanel.fire(event);
6315
+ }), view.model.onGroupDragStart((event) => {
6316
+ this._onWillDragGroup.fire(event);
6317
+ }), view.model.onMove((event) => {
6214
6318
  const { groupId, itemId, target, index } = event;
6215
6319
  this.moveGroupOrPanel(view, groupId, itemId, target, index);
6216
6320
  }), view.model.onDidDrop((event) => {
@@ -6249,13 +6353,6 @@
6249
6353
  var _a;
6250
6354
  return (_a = Array.from(this._groups.values()).find((group) => group.value.model.containsPanel(panel))) === null || _a === void 0 ? void 0 : _a.value;
6251
6355
  }
6252
- dispose() {
6253
- this._onDidActivePanelChange.dispose();
6254
- this._onDidAddPanel.dispose();
6255
- this._onDidRemovePanel.dispose();
6256
- this._onDidLayoutFromJSON.dispose();
6257
- super.dispose();
6258
- }
6259
6356
  }
6260
6357
 
6261
6358
  class GridviewComponent extends BaseGrid {
@@ -7553,6 +7650,7 @@
7553
7650
  createRightHeaderActionsElement: createGroupControlElement(props.rightHeaderActionsComponent, { addPortal }),
7554
7651
  singleTabMode: props.singleTabMode,
7555
7652
  disableFloatingGroups: props.disableFloatingGroups,
7653
+ floatingGroupBounds: props.floatingGroupBounds,
7556
7654
  });
7557
7655
  const { clientWidth, clientHeight } = domRef.current;
7558
7656
  dockview.layout(clientWidth, clientHeight);
@@ -7587,6 +7685,14 @@
7587
7685
  frameworkComponents: props.components,
7588
7686
  });
7589
7687
  }, [props.components]);
7688
+ React__namespace.useEffect(() => {
7689
+ if (!dockviewRef.current) {
7690
+ return;
7691
+ }
7692
+ dockviewRef.current.updateOptions({
7693
+ floatingGroupBounds: props.floatingGroupBounds,
7694
+ });
7695
+ }, [props.floatingGroupBounds]);
7590
7696
  React__namespace.useEffect(() => {
7591
7697
  if (!dockviewRef.current) {
7592
7698
  return;
@@ -7693,25 +7799,32 @@
7693
7799
  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" })));
7694
7800
 
7695
7801
  const DockviewDefaultTab = (_a) => {
7696
- var { api, containerApi: _containerApi, params: _params } = _a, rest = __rest(_a, ["api", "containerApi", "params"]);
7802
+ var { api, containerApi: _containerApi, params: _params, hideClose, closeActionOverride } = _a, rest = __rest(_a, ["api", "containerApi", "params", "hideClose", "closeActionOverride"]);
7697
7803
  const onClose = React__namespace.useCallback((event) => {
7698
- event.stopPropagation();
7699
- api.close();
7700
- }, [api]);
7804
+ event.preventDefault();
7805
+ if (closeActionOverride) {
7806
+ closeActionOverride();
7807
+ }
7808
+ else {
7809
+ api.close();
7810
+ }
7811
+ }, [api, closeActionOverride]);
7812
+ const onMouseDown = React__namespace.useCallback((e) => {
7813
+ e.preventDefault();
7814
+ }, []);
7701
7815
  const onClick = React__namespace.useCallback((event) => {
7816
+ if (event.defaultPrevented) {
7817
+ return;
7818
+ }
7702
7819
  api.setActive();
7703
7820
  if (rest.onClick) {
7704
7821
  rest.onClick(event);
7705
7822
  }
7706
7823
  }, [api, rest.onClick]);
7707
- const iconClassname = React__namespace.useMemo(() => {
7708
- const cn = ['dockview-react-tab-action'];
7709
- return cn.join(',');
7710
- }, []);
7711
- return (React__namespace.createElement("div", Object.assign({}, rest, { onClick: onClick, className: "dockview-react-tab" }),
7824
+ return (React__namespace.createElement("div", Object.assign({ "data-testid": "dockview-default-tab" }, rest, { onClick: onClick, className: "dockview-react-tab" }),
7712
7825
  React__namespace.createElement("span", { className: "dockview-react-tab-title" }, api.title),
7713
- React__namespace.createElement("div", { className: iconClassname, onClick: onClose },
7714
- React__namespace.createElement(CloseButton, null))));
7826
+ !hideClose && (React__namespace.createElement("div", { className: "dv-react-tab-close-btn", onMouseDown: onMouseDown, onClick: onClose },
7827
+ React__namespace.createElement(CloseButton, null)))));
7715
7828
  };
7716
7829
 
7717
7830
  class ReactPanelView extends SplitviewPanel {