dockview-core 6.2.2 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/README.md +1 -0
  2. package/dist/cjs/api/dockviewGroupPanelApi.d.ts +10 -1
  3. package/dist/cjs/api/dockviewGroupPanelApi.js +16 -0
  4. package/dist/cjs/dnd/backend.d.ts +70 -0
  5. package/dist/cjs/dnd/backend.js +171 -0
  6. package/dist/cjs/dnd/dropOverlay.d.ts +20 -0
  7. package/dist/cjs/dnd/dropOverlay.js +197 -0
  8. package/dist/cjs/dnd/droptarget.d.ts +20 -6
  9. package/dist/cjs/dnd/droptarget.js +14 -208
  10. package/dist/cjs/dnd/pointer/index.d.ts +11 -0
  11. package/dist/cjs/dnd/pointer/index.js +13 -0
  12. package/dist/cjs/dnd/pointer/longPress.d.ts +32 -0
  13. package/dist/cjs/dnd/pointer/longPress.js +151 -0
  14. package/dist/cjs/dnd/pointer/pointerDragController.d.ts +60 -0
  15. package/dist/cjs/dnd/pointer/pointerDragController.js +241 -0
  16. package/dist/cjs/dnd/pointer/pointerDragSource.d.ts +61 -0
  17. package/dist/cjs/dnd/pointer/pointerDragSource.js +195 -0
  18. package/dist/cjs/dnd/pointer/pointerDropTarget.d.ts +39 -0
  19. package/dist/cjs/dnd/pointer/pointerDropTarget.js +198 -0
  20. package/dist/cjs/dnd/pointer/pointerGhost.d.ts +30 -0
  21. package/dist/cjs/dnd/pointer/pointerGhost.js +44 -0
  22. package/dist/cjs/dnd/pointer/types.d.ts +16 -0
  23. package/dist/cjs/dnd/pointer/types.js +2 -0
  24. package/dist/cjs/dockview/components/panel/content.d.ts +3 -1
  25. package/dist/cjs/dockview/components/panel/content.js +33 -16
  26. package/dist/cjs/dockview/components/popupService.js +34 -0
  27. package/dist/cjs/dockview/components/tab/tab.d.ts +11 -3
  28. package/dist/cjs/dockview/components/tab/tab.js +151 -117
  29. package/dist/cjs/dockview/components/titlebar/tabGroupChip.d.ts +9 -2
  30. package/dist/cjs/dockview/components/titlebar/tabGroupChip.js +15 -6
  31. package/dist/cjs/dockview/components/titlebar/tabGroupIndicator.js +2 -2
  32. package/dist/cjs/dockview/components/titlebar/tabGroups.d.ts +33 -5
  33. package/dist/cjs/dockview/components/titlebar/tabGroups.js +231 -40
  34. package/dist/cjs/dockview/components/titlebar/tabs.d.ts +38 -1
  35. package/dist/cjs/dockview/components/titlebar/tabs.js +381 -253
  36. package/dist/cjs/dockview/components/titlebar/tabsContainer.d.ts +5 -3
  37. package/dist/cjs/dockview/components/titlebar/voidContainer.d.ts +6 -2
  38. package/dist/cjs/dockview/components/titlebar/voidContainer.js +190 -22
  39. package/dist/cjs/dockview/contextMenu.js +19 -4
  40. package/dist/cjs/dockview/dndCapabilities.d.ts +19 -0
  41. package/dist/cjs/dockview/dndCapabilities.js +39 -0
  42. package/dist/cjs/dockview/dockviewComponent.d.ts +2 -0
  43. package/dist/cjs/dockview/dockviewComponent.js +241 -158
  44. package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts +10 -5
  45. package/dist/cjs/dockview/dockviewGroupPanelModel.js +34 -11
  46. package/dist/cjs/dockview/dockviewPanel.js +5 -0
  47. package/dist/cjs/dockview/dockviewPanelModel.d.ts +2 -0
  48. package/dist/cjs/dockview/dockviewPanelModel.js +8 -0
  49. package/dist/cjs/dockview/events.d.ts +2 -1
  50. package/dist/cjs/dockview/events.js +1 -0
  51. package/dist/cjs/dockview/framework.d.ts +8 -0
  52. package/dist/cjs/dockview/options.d.ts +31 -5
  53. package/dist/cjs/dockview/options.js +3 -0
  54. package/dist/cjs/dom.d.ts +5 -1
  55. package/dist/cjs/dom.js +21 -5
  56. package/dist/cjs/index.d.ts +1 -1
  57. package/dist/cjs/overlay/overlay.d.ts +12 -0
  58. package/dist/cjs/overlay/overlay.js +84 -16
  59. package/dist/cjs/paneview/draggablePaneviewPanel.d.ts +3 -1
  60. package/dist/cjs/paneview/draggablePaneviewPanel.js +27 -26
  61. package/dist/cjs/paneview/options.d.ts +4 -3
  62. package/dist/cjs/popoutWindow.d.ts +2 -0
  63. package/dist/cjs/popoutWindow.js +3 -1
  64. package/dist/dockview-core.js +2431 -937
  65. package/dist/dockview-core.min.js +2 -2
  66. package/dist/dockview-core.min.js.map +1 -1
  67. package/dist/dockview-core.min.noStyle.js +2 -2
  68. package/dist/dockview-core.min.noStyle.js.map +1 -1
  69. package/dist/dockview-core.noStyle.js +2430 -936
  70. package/dist/esm/api/dockviewGroupPanelApi.d.ts +10 -1
  71. package/dist/esm/api/dockviewGroupPanelApi.js +12 -0
  72. package/dist/esm/dnd/backend.d.ts +70 -0
  73. package/dist/esm/dnd/backend.js +148 -0
  74. package/dist/esm/dnd/dropOverlay.d.ts +20 -0
  75. package/dist/esm/dnd/dropOverlay.js +192 -0
  76. package/dist/esm/dnd/droptarget.d.ts +20 -6
  77. package/dist/esm/dnd/droptarget.js +16 -210
  78. package/dist/esm/dnd/pointer/index.d.ts +11 -0
  79. package/dist/esm/dnd/pointer/index.js +5 -0
  80. package/dist/esm/dnd/pointer/longPress.d.ts +32 -0
  81. package/dist/esm/dnd/pointer/longPress.js +127 -0
  82. package/dist/esm/dnd/pointer/pointerDragController.d.ts +60 -0
  83. package/dist/esm/dnd/pointer/pointerDragController.js +191 -0
  84. package/dist/esm/dnd/pointer/pointerDragSource.d.ts +61 -0
  85. package/dist/esm/dnd/pointer/pointerDragSource.js +171 -0
  86. package/dist/esm/dnd/pointer/pointerDropTarget.d.ts +39 -0
  87. package/dist/esm/dnd/pointer/pointerDropTarget.js +168 -0
  88. package/dist/esm/dnd/pointer/pointerGhost.d.ts +30 -0
  89. package/dist/esm/dnd/pointer/pointerGhost.js +39 -0
  90. package/dist/esm/dnd/pointer/types.d.ts +16 -0
  91. package/dist/esm/dnd/pointer/types.js +1 -0
  92. package/dist/esm/dockview/components/panel/content.d.ts +3 -1
  93. package/dist/esm/dockview/components/panel/content.js +33 -16
  94. package/dist/esm/dockview/components/popupService.js +34 -0
  95. package/dist/esm/dockview/components/tab/tab.d.ts +11 -3
  96. package/dist/esm/dockview/components/tab/tab.js +139 -114
  97. package/dist/esm/dockview/components/titlebar/tabGroupChip.d.ts +9 -2
  98. package/dist/esm/dockview/components/titlebar/tabGroupChip.js +15 -6
  99. package/dist/esm/dockview/components/titlebar/tabGroupIndicator.js +2 -2
  100. package/dist/esm/dockview/components/titlebar/tabGroups.d.ts +33 -5
  101. package/dist/esm/dockview/components/titlebar/tabGroups.js +177 -12
  102. package/dist/esm/dockview/components/titlebar/tabs.d.ts +38 -1
  103. package/dist/esm/dockview/components/titlebar/tabs.js +360 -229
  104. package/dist/esm/dockview/components/titlebar/tabsContainer.d.ts +5 -3
  105. package/dist/esm/dockview/components/titlebar/voidContainer.d.ts +6 -2
  106. package/dist/esm/dockview/components/titlebar/voidContainer.js +180 -26
  107. package/dist/esm/dockview/contextMenu.js +19 -4
  108. package/dist/esm/dockview/dndCapabilities.d.ts +19 -0
  109. package/dist/esm/dockview/dndCapabilities.js +36 -0
  110. package/dist/esm/dockview/dockviewComponent.d.ts +2 -0
  111. package/dist/esm/dockview/dockviewComponent.js +104 -41
  112. package/dist/esm/dockview/dockviewGroupPanelModel.d.ts +10 -5
  113. package/dist/esm/dockview/dockviewGroupPanelModel.js +33 -11
  114. package/dist/esm/dockview/dockviewPanel.js +5 -0
  115. package/dist/esm/dockview/dockviewPanelModel.d.ts +2 -0
  116. package/dist/esm/dockview/dockviewPanelModel.js +8 -0
  117. package/dist/esm/dockview/events.d.ts +2 -1
  118. package/dist/esm/dockview/events.js +1 -0
  119. package/dist/esm/dockview/framework.d.ts +8 -0
  120. package/dist/esm/dockview/options.d.ts +31 -5
  121. package/dist/esm/dockview/options.js +3 -0
  122. package/dist/esm/dom.d.ts +5 -1
  123. package/dist/esm/dom.js +20 -5
  124. package/dist/esm/index.d.ts +1 -1
  125. package/dist/esm/overlay/overlay.d.ts +12 -0
  126. package/dist/esm/overlay/overlay.js +85 -17
  127. package/dist/esm/paneview/draggablePaneviewPanel.d.ts +3 -1
  128. package/dist/esm/paneview/draggablePaneviewPanel.js +26 -20
  129. package/dist/esm/paneview/options.d.ts +4 -3
  130. package/dist/esm/popoutWindow.d.ts +2 -0
  131. package/dist/esm/popoutWindow.js +3 -1
  132. package/dist/package/main.cjs.js +2430 -936
  133. package/dist/package/main.cjs.min.js +2 -2
  134. package/dist/package/main.esm.min.mjs +2 -2
  135. package/dist/package/main.esm.mjs +2430 -936
  136. package/dist/styles/dockview.css +117 -1
  137. package/package.json +3 -1
  138. package/dist/cjs/dnd/abstractDragHandler.d.ts +0 -14
  139. package/dist/cjs/dnd/abstractDragHandler.js +0 -86
  140. package/dist/cjs/dnd/groupDragHandler.d.ts +0 -12
  141. package/dist/cjs/dnd/groupDragHandler.js +0 -82
  142. package/dist/esm/dnd/abstractDragHandler.d.ts +0 -14
  143. package/dist/esm/dnd/abstractDragHandler.js +0 -63
  144. package/dist/esm/dnd/groupDragHandler.d.ts +0 -12
  145. package/dist/esm/dnd/groupDragHandler.js +0 -59
@@ -1,5 +1,6 @@
1
1
  import { getRelativeLocation, getGridLocation, orthogonal, } from '../gridview/gridview';
2
- import { directionToPosition, Droptarget, } from '../dnd/droptarget';
2
+ import { directionToPosition, } from '../dnd/droptarget';
3
+ import { html5Backend, pointerBackend } from '../dnd/backend';
3
4
  import { tail, sequenceEquals, remove } from '../array';
4
5
  import { DockviewPanel } from './dockviewPanel';
5
6
  import { CompositeDisposable, Disposable } from '../lifecycle';
@@ -98,7 +99,7 @@ export class DockviewComponent extends BaseGrid {
98
99
  return this._popoutRestorationPromise;
99
100
  }
100
101
  constructor(container, options) {
101
- var _a, _b, _c, _d, _e, _f;
102
+ var _a, _b, _c, _d, _e, _f, _g;
102
103
  super(container, {
103
104
  proportionalLayout: true,
104
105
  orientation: Orientation.HORIZONTAL,
@@ -162,6 +163,7 @@ export class DockviewComponent extends BaseGrid {
162
163
  this._floatingGroups = [];
163
164
  this._popoutGroups = [];
164
165
  this._popoutRestorationPromise = Promise.resolve();
166
+ this._popoutRestorationCleanups = new Set();
165
167
  this._onDidRemoveGroup = new Emitter();
166
168
  this.onDidRemoveGroup = this._onDidRemoveGroup.event;
167
169
  this._onDidAddGroup = new Emitter();
@@ -196,37 +198,51 @@ export class DockviewComponent extends BaseGrid {
196
198
  this._floatingOverlayHost = document.createElement('div');
197
199
  this._floatingOverlayHost.className = 'dv-floating-overlay-host';
198
200
  this._shellManager.element.appendChild(this._floatingOverlayHost);
199
- this._rootDropTarget = new Droptarget(this.element, {
200
- className: 'dv-drop-target-edge',
201
- canDisplayOverlay: (event, position) => {
202
- const data = getPanelData();
203
- if (data) {
204
- if (data.viewId !== this.id) {
205
- return false;
206
- }
207
- if (position === 'center') {
208
- // center drop target is only allowed if there are no panels in the grid
209
- // floating panels are allowed
210
- return this.gridview.length === 0;
211
- }
212
- return true;
213
- }
214
- if (position === 'center' && this.gridview.length !== 0) {
215
- /**
216
- * for external events only show the four-corner drag overlays, disable
217
- * the center position so that external drag events can fall through to the group
218
- * and panel drop target handlers
219
- */
201
+ const rootCanDisplayOverlay = (event, position) => {
202
+ const data = getPanelData();
203
+ if (data) {
204
+ if (data.viewId !== this.id) {
220
205
  return false;
221
206
  }
222
- const firedEvent = new DockviewUnhandledDragOverEvent(event, 'edge', position, getPanelData);
223
- this._onUnhandledDragOverEvent.fire(firedEvent);
224
- return firedEvent.isAccepted;
225
- },
207
+ if (position === 'center') {
208
+ // center drop target is only allowed if there are no panels in the grid
209
+ // floating panels are allowed
210
+ return this.gridview.length === 0;
211
+ }
212
+ return true;
213
+ }
214
+ if (position === 'center' && this.gridview.length !== 0) {
215
+ /**
216
+ * for external events only show the four-corner drag overlays, disable
217
+ * the center position so that external drag events can fall through to the group
218
+ * and panel drop target handlers
219
+ */
220
+ return false;
221
+ }
222
+ const firedEvent = new DockviewUnhandledDragOverEvent(event, 'edge', position, getPanelData);
223
+ this._onUnhandledDragOverEvent.fire(firedEvent);
224
+ return firedEvent.isAccepted;
225
+ };
226
+ this._rootDropTarget = html5Backend.createDropTarget(this.element, {
227
+ className: 'dv-drop-target-edge',
228
+ canDisplayOverlay: rootCanDisplayOverlay,
226
229
  acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
227
230
  overlayModel: (_f = options.rootOverlayModel) !== null && _f !== void 0 ? _f : DEFAULT_ROOT_OVERLAY_MODEL,
228
231
  getOverrideTarget: () => { var _a; return (_a = this.rootDropTargetContainer) === null || _a === void 0 ? void 0 : _a.model; },
229
232
  });
233
+ this._rootPointerDropTarget = pointerBackend.createDropTarget(this.element, {
234
+ className: 'dv-drop-target-edge',
235
+ canDisplayOverlay: rootCanDisplayOverlay,
236
+ acceptedTargetZones: [
237
+ 'top',
238
+ 'bottom',
239
+ 'left',
240
+ 'right',
241
+ 'center',
242
+ ],
243
+ overlayModel: (_g = options.rootOverlayModel) !== null && _g !== void 0 ? _g : DEFAULT_ROOT_OVERLAY_MODEL,
244
+ getOverrideTarget: () => { var _a; return (_a = this.rootDropTargetContainer) === null || _a === void 0 ? void 0 : _a.model; },
245
+ });
230
246
  this.updateDropTargetModel(options);
231
247
  toggleClass(this.gridview.element, 'dv-dockview', true);
232
248
  toggleClass(this.element, 'dv-debug', !!options.debug);
@@ -267,6 +283,14 @@ export class DockviewComponent extends BaseGrid {
267
283
  this._bufferOnDidLayoutChange.fire();
268
284
  }), Disposable.from(() => {
269
285
  var _a;
286
+ // Cancel any pending popout-restoration timers scheduled by
287
+ // fromJSON so they don't open new browser windows after
288
+ // dispose, and resolve their promises so callers awaiting
289
+ // popoutRestorationPromise don't hang. See issue #851.
290
+ for (const cleanup of [...this._popoutRestorationCleanups]) {
291
+ cleanup();
292
+ }
293
+ this._popoutRestorationCleanups.clear();
270
294
  // iterate over a copy of the array since .dispose() mutates the original array
271
295
  for (const group of [...this._floatingGroups]) {
272
296
  group.dispose();
@@ -280,7 +304,7 @@ export class DockviewComponent extends BaseGrid {
280
304
  d.dispose();
281
305
  }
282
306
  this._edgeGroupDisposables.clear();
283
- }), this._rootDropTarget, this._rootDropTarget.onWillShowOverlay((event) => {
307
+ }), this._rootDropTarget, this._rootPointerDropTarget, Event.any(this._rootDropTarget.onWillShowOverlay, this._rootPointerDropTarget.onWillShowOverlay)((event) => {
284
308
  if (this.gridview.length > 0 && event.position === 'center') {
285
309
  // option only available when no panels in primary grid
286
310
  return;
@@ -292,7 +316,7 @@ export class DockviewComponent extends BaseGrid {
292
316
  group: undefined,
293
317
  getData: getPanelData,
294
318
  }));
295
- }), this._rootDropTarget.onDrop((event) => {
319
+ }), Event.any(this._rootDropTarget.onDrop, this._rootPointerDropTarget.onDrop)((event) => {
296
320
  var _a;
297
321
  const willDropEvent = new DockviewWillDropEvent({
298
322
  nativeEvent: event.nativeEvent,
@@ -330,7 +354,7 @@ export class DockviewComponent extends BaseGrid {
330
354
  getData: getPanelData,
331
355
  }));
332
356
  }
333
- }), this._rootDropTarget);
357
+ }));
334
358
  }
335
359
  setVisible(panel, visible) {
336
360
  switch (panel.api.location.type) {
@@ -366,7 +390,7 @@ export class DockviewComponent extends BaseGrid {
366
390
  return (_a = this._popoutPopupServices.get(group.id)) !== null && _a !== void 0 ? _a : this.popupService;
367
391
  }
368
392
  addPopoutGroup(itemToPopout, options) {
369
- var _a, _b, _c, _d, _e;
393
+ var _a, _b, _c, _d, _e, _f;
370
394
  if (itemToPopout instanceof DockviewGroupPanel &&
371
395
  itemToPopout.model.location.type === 'edge') {
372
396
  // edge groups are permanent structural elements and cannot be popped out
@@ -401,6 +425,7 @@ export class DockviewComponent extends BaseGrid {
401
425
  height: box.height,
402
426
  onDidOpen: options === null || options === void 0 ? void 0 : options.onDidOpen,
403
427
  onWillClose: options === null || options === void 0 ? void 0 : options.onWillClose,
428
+ nonce: (_f = this.options) === null || _f === void 0 ? void 0 : _f.nonce,
404
429
  });
405
430
  const popoutWindowDisposable = new CompositeDisposable(_window, _window.onDidClose(() => {
406
431
  popoutWindowDisposable.dispose();
@@ -820,7 +845,7 @@ export class DockviewComponent extends BaseGrid {
820
845
  }
821
846
  }
822
847
  updateOptions(options) {
823
- var _a, _b, _c;
848
+ var _a, _b, _c, _d, _e;
824
849
  super.updateOptions(options);
825
850
  if ('floatingGroupBounds' in options) {
826
851
  for (const group of this._floatingGroups) {
@@ -846,9 +871,12 @@ export class DockviewComponent extends BaseGrid {
846
871
  }
847
872
  this.updateDropTargetModel(options);
848
873
  const oldDisableDnd = this.options.disableDnd;
874
+ const oldDndStrategy = this.options.dndStrategy;
849
875
  this._options = Object.assign(Object.assign({}, this.options), options);
850
876
  const newDisableDnd = this.options.disableDnd;
851
- if (oldDisableDnd !== newDisableDnd) {
877
+ const newDndStrategy = this.options.dndStrategy;
878
+ if (oldDisableDnd !== newDisableDnd ||
879
+ oldDndStrategy !== newDndStrategy) {
852
880
  this.updateDragAndDropState();
853
881
  }
854
882
  if ('theme' in options) {
@@ -861,8 +889,19 @@ export class DockviewComponent extends BaseGrid {
861
889
  group.model.updateHeaderActions();
862
890
  }
863
891
  }
892
+ if ('createWatermarkComponent' in options) {
893
+ if (this._watermark) {
894
+ this._watermark.element.parentElement.remove();
895
+ (_d = (_c = this._watermark).dispose) === null || _d === void 0 ? void 0 : _d.call(_c);
896
+ this._watermark = null;
897
+ }
898
+ this.updateWatermark();
899
+ for (const group of this.groups) {
900
+ group.model.refreshWatermark();
901
+ }
902
+ }
864
903
  if ('tabGroupColors' in options || 'tabGroupAccent' in options) {
865
- this._tabGroupColorPalette.setEntries((_c = this._options.tabGroupColors) !== null && _c !== void 0 ? _c : DEFAULT_TAB_GROUP_COLORS);
904
+ this._tabGroupColorPalette.setEntries((_e = this._options.tabGroupColors) !== null && _e !== void 0 ? _e : DEFAULT_TAB_GROUP_COLORS);
866
905
  this._tabGroupColorPalette.enabled =
867
906
  this._options.tabGroupAccent !== 'off';
868
907
  for (const group of this.groups) {
@@ -1288,7 +1327,23 @@ export class DockviewComponent extends BaseGrid {
1288
1327
  const group = createGroupFromSerializedState(data);
1289
1328
  // Add a small delay for each popup after the first to avoid browser popup blocking
1290
1329
  const popoutPromise = new Promise((resolve) => {
1291
- setTimeout(() => {
1330
+ const cleanup = () => {
1331
+ this._popoutRestorationCleanups.delete(cleanup);
1332
+ clearTimeout(handle);
1333
+ resolve();
1334
+ };
1335
+ const handle = setTimeout(() => {
1336
+ this._popoutRestorationCleanups.delete(cleanup);
1337
+ // Guard against the component being disposed before
1338
+ // this timer fires. Under React StrictMode the
1339
+ // component is mounted -> disposed -> remounted, and
1340
+ // without this guard the first instance's queued
1341
+ // restoration would open a second popout window.
1342
+ // See issue #851.
1343
+ if (this.isDisposed) {
1344
+ resolve();
1345
+ return;
1346
+ }
1292
1347
  this.addPopoutGroup(group, {
1293
1348
  position: position !== null && position !== void 0 ? position : undefined,
1294
1349
  overridePopoutGroup: gridReferenceGroup
@@ -1301,6 +1356,7 @@ export class DockviewComponent extends BaseGrid {
1301
1356
  });
1302
1357
  resolve();
1303
1358
  }, index * DESERIALIZATION_POPOUT_DELAY_MS); // 100ms delay between each popup
1359
+ this._popoutRestorationCleanups.add(cleanup);
1304
1360
  });
1305
1361
  popoutPromises.push(popoutPromise);
1306
1362
  });
@@ -1831,8 +1887,11 @@ export class DockviewComponent extends BaseGrid {
1831
1887
  * the source group is a popout group with a single panel
1832
1888
  *
1833
1889
  * 1. remove the panel from the group without triggering any events
1834
- * 2. remove the popout group
1835
- * 3. create a new group at the requested location and add that panel
1890
+ * 2. remove the popout group — this may cascade-remove the empty
1891
+ * reference group it left behind in the main grid (see
1892
+ * doRemoveGroup for popout groups), which can shift grid indices
1893
+ * 3. recompute the target location now that the grid is stable
1894
+ * 4. create a new group at the recomputed location and add that panel
1836
1895
  */
1837
1896
  const popoutGroup = this._popoutGroups.find((group) => group.popoutGroup === sourceGroup);
1838
1897
  const removedPanel = this.movingLock(() => popoutGroup.popoutGroup.model.removePanel(popoutGroup.popoutGroup.panels[0], {
@@ -1840,7 +1899,8 @@ export class DockviewComponent extends BaseGrid {
1840
1899
  skipSetActiveGroup: true,
1841
1900
  }));
1842
1901
  this.doRemoveGroup(sourceGroup, { skipActive: true });
1843
- const newGroup = this.createGroupAtLocation(targetLocation);
1902
+ const updatedTargetLocation = getRelativeLocation(this.gridview.orientation, getGridLocation(destinationGroup.element), destinationTarget);
1903
+ const newGroup = this.createGroupAtLocation(updatedTargetLocation);
1844
1904
  this.movingLock(() => newGroup.model.openPanel(removedPanel, {
1845
1905
  skipSetActive: true,
1846
1906
  }));
@@ -2380,15 +2440,18 @@ export class DockviewComponent extends BaseGrid {
2380
2440
  }
2381
2441
  updateDropTargetModel(options) {
2382
2442
  if ('dndEdges' in options) {
2383
- this._rootDropTarget.disabled =
2384
- typeof options.dndEdges === 'boolean' &&
2385
- options.dndEdges === false;
2443
+ const disabled = typeof options.dndEdges === 'boolean' &&
2444
+ options.dndEdges === false;
2445
+ this._rootDropTarget.disabled = disabled;
2446
+ this._rootPointerDropTarget.disabled = disabled;
2386
2447
  if (typeof options.dndEdges === 'object' &&
2387
2448
  options.dndEdges !== null) {
2388
2449
  this._rootDropTarget.setOverlayModel(options.dndEdges);
2450
+ this._rootPointerDropTarget.setOverlayModel(options.dndEdges);
2389
2451
  }
2390
2452
  else {
2391
2453
  this._rootDropTarget.setOverlayModel(DEFAULT_ROOT_OVERLAY_MODEL);
2454
+ this._rootPointerDropTarget.setOverlayModel(DEFAULT_ROOT_OVERLAY_MODEL);
2392
2455
  }
2393
2456
  }
2394
2457
  if ('rootOverlayModel' in options) {
@@ -52,13 +52,17 @@ export interface CreateTabGroupOptions extends TabGroupOptions {
52
52
  }
53
53
  export declare class DockviewDidDropEvent extends DockviewEvent {
54
54
  private readonly options;
55
- get nativeEvent(): DragEvent;
55
+ /**
56
+ * `PointerEvent` for touch drags has no `dataTransfer`; use
57
+ * `getData()` for the dockview payload regardless of input method.
58
+ */
59
+ get nativeEvent(): DragEvent | PointerEvent;
56
60
  get position(): Position;
57
61
  get panel(): IDockviewPanel | undefined;
58
62
  get group(): DockviewGroupPanel | undefined;
59
63
  get api(): DockviewApi;
60
64
  constructor(options: {
61
- readonly nativeEvent: DragEvent;
65
+ readonly nativeEvent: DragEvent | PointerEvent;
62
66
  readonly position: Position;
63
67
  readonly panel?: IDockviewPanel;
64
68
  getData(): PanelTransfer | undefined;
@@ -71,7 +75,7 @@ export declare class DockviewWillDropEvent extends DockviewDidDropEvent {
71
75
  private readonly _kind;
72
76
  get kind(): DockviewGroupDropLocation;
73
77
  constructor(options: {
74
- readonly nativeEvent: DragEvent;
78
+ readonly nativeEvent: DragEvent | PointerEvent;
75
79
  readonly position: Position;
76
80
  readonly panel?: IDockviewPanel;
77
81
  getData(): PanelTransfer | undefined;
@@ -122,7 +126,7 @@ export interface IDockviewGroupPanelModel extends IPanel {
122
126
  panel?: IDockviewPanel;
123
127
  suppressRoll?: boolean;
124
128
  }): void;
125
- canDisplayOverlay(event: DragEvent, position: Position, target: DockviewGroupDropLocation): boolean;
129
+ canDisplayOverlay(event: DragEvent | PointerEvent, position: Position, target: DockviewGroupDropLocation): boolean;
126
130
  }
127
131
  export type DockviewGroupLocation = {
128
132
  type: 'grid';
@@ -272,6 +276,7 @@ export declare class DockviewGroupPanelModel extends CompositeDisposable impleme
272
276
  getTabGroups(): readonly ITabGroup[];
273
277
  updateTabGroups(): void;
274
278
  refreshTabGroupAccent(): void;
279
+ refreshWatermark(): void;
275
280
  getTabGroupForPanel(panelId: string): ITabGroup | undefined;
276
281
  private _findTabGroupForPanel;
277
282
  private _removeTabGroupInternal;
@@ -323,7 +328,7 @@ export declare class DockviewGroupPanelModel extends CompositeDisposable impleme
323
328
  private doSetActivePanel;
324
329
  private updateMru;
325
330
  private updateContainer;
326
- canDisplayOverlay(event: DragEvent, position: Position, target: DockviewGroupDropLocation): boolean;
331
+ canDisplayOverlay(event: DragEvent | PointerEvent, position: Position, target: DockviewGroupDropLocation): boolean;
327
332
  private handleDropEvent;
328
333
  updateDragAndDropState(): void;
329
334
  dispose(): void;
@@ -9,6 +9,10 @@ import { TabsContainer, } from './components/titlebar/tabsContainer';
9
9
  import { DockviewUnhandledDragOverEvent, } from './options';
10
10
  import { TabGroup, } from './tabGroup';
11
11
  export class DockviewDidDropEvent extends DockviewEvent {
12
+ /**
13
+ * `PointerEvent` for touch drags has no `dataTransfer`; use
14
+ * `getData()` for the dockview payload regardless of input method.
15
+ */
12
16
  get nativeEvent() {
13
17
  return this.options.nativeEvent;
14
18
  }
@@ -113,29 +117,28 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
113
117
  toggleClass(this.container, 'dv-groupview-floating', false);
114
118
  toggleClass(this.container, 'dv-groupview-popout', false);
115
119
  toggleClass(this.container, 'dv-groupview-edge', false);
120
+ // Mouse and touch drop targets must agree on accepted zones.
121
+ const applyZones = (zones) => {
122
+ this.contentContainer.dropTarget.setTargetZones(zones);
123
+ this.contentContainer.pointerDropTarget.setTargetZones(zones);
124
+ };
116
125
  switch (value.type) {
117
126
  case 'grid':
118
- this.contentContainer.dropTarget.setTargetZones([
119
- 'top',
120
- 'bottom',
121
- 'left',
122
- 'right',
123
- 'center',
124
- ]);
127
+ applyZones(['top', 'bottom', 'left', 'right', 'center']);
125
128
  break;
126
129
  case 'floating':
127
- this.contentContainer.dropTarget.setTargetZones(['center']);
128
- this.contentContainer.dropTarget.setTargetZones(value
130
+ applyZones(['center']);
131
+ applyZones(value
129
132
  ? ['center']
130
133
  : ['top', 'bottom', 'left', 'right', 'center']);
131
134
  toggleClass(this.container, 'dv-groupview-floating', true);
132
135
  break;
133
136
  case 'popout':
134
- this.contentContainer.dropTarget.setTargetZones(['center']);
137
+ applyZones(['center']);
135
138
  toggleClass(this.container, 'dv-groupview-popout', true);
136
139
  break;
137
140
  case 'edge':
138
- this.contentContainer.dropTarget.setTargetZones(['center']);
141
+ applyZones(['center']);
139
142
  toggleClass(this.container, 'dv-groupview-edge', true);
140
143
  break;
141
144
  }
@@ -261,6 +264,8 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
261
264
  // noop
262
265
  }), this.contentContainer.dropTarget.onDrop((event) => {
263
266
  this.handleDropEvent('content', event.nativeEvent, event.position);
267
+ }), this.contentContainer.pointerDropTarget.onDrop((event) => {
268
+ this.handleDropEvent('content', event.nativeEvent, event.position);
264
269
  }), this.tabsContainer.onWillShowOverlay((event) => {
265
270
  this._onWillShowOverlay.fire(event);
266
271
  }), this.contentContainer.dropTarget.onWillShowOverlay((event) => {
@@ -271,6 +276,14 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
271
276
  group: this.groupPanel,
272
277
  getData: getPanelData,
273
278
  }));
279
+ }), this.contentContainer.pointerDropTarget.onWillShowOverlay((event) => {
280
+ this._onWillShowOverlay.fire(new DockviewWillShowOverlayLocationEvent(event, {
281
+ kind: 'content',
282
+ panel: this.activePanel,
283
+ api: this._api,
284
+ group: this.groupPanel,
285
+ getData: getPanelData,
286
+ }));
274
287
  }), this._onMove, this._onDidChange, this._onDidDrop, this._onWillDrop, this._onDidAddPanel, this._onDidRemovePanel, this._onDidActivePanelChange, this._onUnhandledDragOverEvent, this._onDidPanelTitleChange, this._onDidPanelParametersChange, this._onDidCreateTabGroup, this._onDidDestroyTabGroup, this._onDidAddPanelToTabGroup, this._onDidRemovePanelFromTabGroup, this._onDidTabGroupChange, this._onDidTabGroupCollapsedChange, this._onDidCreateTabGroup.event(() => {
275
288
  this._scheduleTabGroupUpdate();
276
289
  }), this._onDidDestroyTabGroup.event(() => {
@@ -527,6 +540,15 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
527
540
  refreshTabGroupAccent() {
528
541
  this.tabsContainer.refreshTabGroupAccent();
529
542
  }
543
+ refreshWatermark() {
544
+ var _a, _b;
545
+ if (this.watermark) {
546
+ this.watermark.element.remove();
547
+ (_b = (_a = this.watermark).dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
548
+ this.watermark = undefined;
549
+ }
550
+ this.updateContainer();
551
+ }
530
552
  getTabGroupForPanel(panelId) {
531
553
  return this._findTabGroupForPanel(panelId);
532
554
  }
@@ -85,6 +85,11 @@ export class DockviewPanel extends CompositeDisposable {
85
85
  const didTitleChange = title !== this.title;
86
86
  if (didTitleChange) {
87
87
  this._title = title;
88
+ // keep the view-model's cached init params in sync so that tab
89
+ // renderers constructed lazily (e.g. the header overflow
90
+ // dropdown via createTabRenderer) see the updated title
91
+ // (#914).
92
+ this.view.setTitle(title);
88
93
  this.api._onDidTitleChange.fire({ title });
89
94
  }
90
95
  }
@@ -12,6 +12,7 @@ export interface IDockviewPanelModel extends IDisposable {
12
12
  layout(width: number, height: number): void;
13
13
  init(params: GroupPanelPartInitParameters): void;
14
14
  createTabRenderer(tabLocation: TabLocation): ITabRenderer;
15
+ setTitle(title: string): void;
15
16
  }
16
17
  export declare class DockviewPanelModel implements IDockviewPanelModel {
17
18
  private readonly accessor;
@@ -27,6 +28,7 @@ export declare class DockviewPanelModel implements IDockviewPanelModel {
27
28
  constructor(accessor: IDockviewComponent, id: string, contentComponent: string, tabComponent?: string | undefined);
28
29
  createTabRenderer(tabLocation: TabLocation): ITabRenderer;
29
30
  init(params: GroupPanelPartInitParameters): void;
31
+ setTitle(title: string): void;
30
32
  layout(width: number, height: number): void;
31
33
  update(event: PanelUpdateEvent): void;
32
34
  dispose(): void;
@@ -30,6 +30,14 @@ export class DockviewPanelModel {
30
30
  this.content.init(params);
31
31
  this.tab.init(Object.assign(Object.assign({}, params), { tabLocation: 'header' }));
32
32
  }
33
+ setTitle(title) {
34
+ // keep the cached init params in sync so that tab renderers created
35
+ // lazily after the title changes (e.g. for the header overflow
36
+ // dropdown) see the current title rather than the stale original.
37
+ if (this._params) {
38
+ this._params.title = title;
39
+ }
40
+ }
33
41
  layout(width, height) {
34
42
  var _a, _b;
35
43
  (_b = (_a = this.content).layout) === null || _b === void 0 ? void 0 : _b.call(_a, width, height);
@@ -25,7 +25,8 @@ export declare class DockviewWillShowOverlayLocationEvent implements IDockviewEv
25
25
  private readonly event;
26
26
  readonly options: DockviewWillShowOverlayLocationEventOptions;
27
27
  get kind(): DockviewGroupDropLocation;
28
- get nativeEvent(): DragEvent;
28
+ /** Narrow with `instanceof DragEvent` before reading `dataTransfer`. */
29
+ get nativeEvent(): DragEvent | PointerEvent;
29
30
  get position(): Position;
30
31
  get defaultPrevented(): boolean;
31
32
  get panel(): IDockviewPanel | undefined;
@@ -2,6 +2,7 @@ export class DockviewWillShowOverlayLocationEvent {
2
2
  get kind() {
3
3
  return this.options.kind;
4
4
  }
5
+ /** Narrow with `instanceof DragEvent` before reading `dataTransfer`. */
5
6
  get nativeEvent() {
6
7
  return this.event.nativeEvent;
7
8
  }
@@ -55,3 +55,11 @@ export interface ITabGroupChipRenderer {
55
55
  }): void;
56
56
  dispose(): void;
57
57
  }
58
+ export interface IGroupDragGhostRenderer {
59
+ readonly element: HTMLElement;
60
+ init(params: {
61
+ group: IDockviewGroupPanel;
62
+ api: DockviewApi;
63
+ }): void;
64
+ dispose?(): void;
65
+ }
@@ -11,12 +11,14 @@ import { GroupOptions } from './dockviewGroupPanelModel';
11
11
  import { DockviewGroupDropLocation } from './events';
12
12
  import { IDockviewPanel } from './dockviewPanel';
13
13
  import { DockviewPanelRenderer } from '../overlay/overlayRenderContainer';
14
- import { IGroupHeaderProps, ITabGroupChipRenderer } from './framework';
14
+ import { IGroupDragGhostRenderer, IGroupHeaderProps, ITabGroupChipRenderer } from './framework';
15
15
  import { FloatingGroupOptions } from './dockviewComponent';
16
16
  import { Contraints } from '../gridview/gridviewPanel';
17
17
  import { AcceptableEvent, IAcceptableEvent } from '../events';
18
18
  import { DockviewTheme } from './theme';
19
19
  import { ITabGroup } from './tabGroup';
20
+ import { CspNonceProvider } from '../dom';
21
+ export { CspNonceProvider };
20
22
  import { DockviewTabGroupColorEntry } from './tabGroupAccent';
21
23
  export interface IHeaderActionsRenderer extends IDisposable {
22
24
  readonly element: HTMLElement;
@@ -75,6 +77,7 @@ export interface ViewFactoryData {
75
77
  }
76
78
  export type DockviewHeaderPosition = 'top' | 'bottom' | 'left' | 'right';
77
79
  export type DockviewHeaderDirection = 'horizontal' | 'vertical';
80
+ export type DockviewDndStrategy = 'auto' | 'pointer' | 'html5';
78
81
  export interface DockviewOptions {
79
82
  /**
80
83
  * Disable the auto-resizing which is controlled through a `ResizeObserver`.
@@ -89,6 +92,7 @@ export interface DockviewOptions {
89
92
  minimumWidthWithinViewport?: number;
90
93
  };
91
94
  popoutUrl?: string;
95
+ nonce?: CspNonceProvider;
92
96
  defaultRenderer?: DockviewPanelRenderer;
93
97
  defaultHeaderPosition?: DockviewHeaderPosition;
94
98
  debug?: boolean;
@@ -98,6 +102,19 @@ export interface DockviewOptions {
98
102
  * */
99
103
  rootOverlayModel?: DroptargetOverlayModel;
100
104
  disableDnd?: boolean;
105
+ /**
106
+ * Selects which drag-and-drop implementation is active.
107
+ *
108
+ * - `'auto'` (default): HTML5 drag-and-drop drives mouse drags; pointer
109
+ * events drive touch and pen drags. Matches the historical behaviour.
110
+ * - `'pointer'`: pointer events drive every input type. Useful in
111
+ * environments where HTML5 drag-and-drop is unreliable (some Linux
112
+ * browsers, certain Safari versions, embedded webviews). Cross-window
113
+ * HTML5 drag and the HTML5 native drag image are not available in this
114
+ * mode.
115
+ * - `'html5'`: HTML5 drag-and-drop only — disables touch / pen drag.
116
+ */
117
+ dndStrategy?: DockviewDndStrategy;
101
118
  locked?: boolean;
102
119
  className?: string;
103
120
  /**
@@ -140,6 +157,15 @@ export interface DockviewOptions {
140
157
  * If not provided, the default chip renderer is used.
141
158
  */
142
159
  createTabGroupChipComponent?: (tabGroup: ITabGroup) => ITabGroupChipRenderer;
160
+ /**
161
+ * Factory to create the custom ghost element shown while dragging a
162
+ * group of panels (the small floating chip that follows the cursor).
163
+ *
164
+ * If not provided, a default ghost rendering `"Multiple Panels (N)"`
165
+ * is used. Supplying a factory replaces the entire default ghost,
166
+ * enabling i18n / custom visuals.
167
+ */
168
+ createGroupDragGhostComponent?: (group: DockviewGroupPanel) => IGroupDragGhostRenderer;
143
169
  /**
144
170
  * Replace the built-in tab group color palette with a user-defined list.
145
171
  *
@@ -165,19 +191,20 @@ export interface DockviewOptions {
165
191
  }
166
192
  export type TabAnimation = 'smooth' | 'default';
167
193
  export interface DockviewDndOverlayEvent extends IAcceptableEvent {
168
- nativeEvent: DragEvent;
194
+ /** Narrow with `instanceof DragEvent` before reading `dataTransfer`. */
195
+ nativeEvent: DragEvent | PointerEvent;
169
196
  target: DockviewGroupDropLocation;
170
197
  position: Position;
171
198
  group?: DockviewGroupPanel;
172
199
  getData: () => PanelTransfer | undefined;
173
200
  }
174
201
  export declare class DockviewUnhandledDragOverEvent extends AcceptableEvent implements DockviewDndOverlayEvent {
175
- readonly nativeEvent: DragEvent;
202
+ readonly nativeEvent: DragEvent | PointerEvent;
176
203
  readonly target: DockviewGroupDropLocation;
177
204
  readonly position: Position;
178
205
  readonly getData: () => PanelTransfer | undefined;
179
206
  readonly group?: DockviewGroupPanel | undefined;
180
- constructor(nativeEvent: DragEvent, target: DockviewGroupDropLocation, position: Position, getData: () => PanelTransfer | undefined, group?: DockviewGroupPanel | undefined);
207
+ constructor(nativeEvent: DragEvent | PointerEvent, target: DockviewGroupDropLocation, position: Position, getData: () => PanelTransfer | undefined, group?: DockviewGroupPanel | undefined);
181
208
  }
182
209
  export declare const PROPERTY_KEYS_DOCKVIEW: (keyof DockviewOptions)[];
183
210
  export interface CreateComponentOptions {
@@ -292,4 +319,3 @@ export interface MovementOptions extends MovementOptions2 {
292
319
  includePanel?: boolean;
293
320
  group?: DockviewGroupPanel;
294
321
  }
295
- export {};
@@ -21,12 +21,14 @@ export const PROPERTY_KEYS_DOCKVIEW = (() => {
21
21
  disableFloatingGroups: undefined,
22
22
  floatingGroupBounds: undefined,
23
23
  popoutUrl: undefined,
24
+ nonce: undefined,
24
25
  defaultRenderer: undefined,
25
26
  defaultHeaderPosition: undefined,
26
27
  debug: undefined,
27
28
  rootOverlayModel: undefined,
28
29
  locked: undefined,
29
30
  disableDnd: undefined,
31
+ dndStrategy: undefined,
30
32
  className: undefined,
31
33
  noPanelsOverlay: undefined,
32
34
  dndEdges: undefined,
@@ -36,6 +38,7 @@ export const PROPERTY_KEYS_DOCKVIEW = (() => {
36
38
  getTabContextMenuItems: undefined,
37
39
  getTabGroupChipContextMenuItems: undefined,
38
40
  createTabGroupChipComponent: undefined,
41
+ createGroupDragGhostComponent: undefined,
39
42
  tabGroupColors: undefined,
40
43
  tabGroupAccent: undefined,
41
44
  };
package/dist/esm/dom.d.ts CHANGED
@@ -24,7 +24,11 @@ export interface IFocusTracker extends IDisposable {
24
24
  export declare function trackFocus(element: HTMLElement): IFocusTracker;
25
25
  export declare function quasiPreventDefault(event: Event): void;
26
26
  export declare function quasiDefaultPrevented(event: Event): boolean;
27
- export declare function addStyles(document: Document, styleSheetList: StyleSheetList): void;
27
+ export type CspNonceProvider = string | ((targetDocument: Document) => string | undefined);
28
+ export interface AddStylesOptions {
29
+ nonce?: CspNonceProvider;
30
+ }
31
+ export declare function addStyles(document: Document, styleSheetList: StyleSheetList, options?: AddStylesOptions): void;
28
32
  export declare function getDomNodePagePosition(domNode: Element): {
29
33
  left: number;
30
34
  top: number;