dockview-core 6.6.1 → 7.0.2

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 (153) hide show
  1. package/README.md +8 -1
  2. package/dist/cjs/api/component.api.d.ts +42 -21
  3. package/dist/cjs/api/component.api.js +111 -20
  4. package/dist/cjs/api/dockviewGroupPanelApi.d.ts +23 -8
  5. package/dist/cjs/api/dockviewGroupPanelApi.js +23 -0
  6. package/dist/cjs/api/dockviewPanelApi.d.ts +4 -3
  7. package/dist/cjs/api/dockviewPanelApi.js +8 -0
  8. package/dist/cjs/dnd/droptarget.d.ts +8 -0
  9. package/dist/cjs/dnd/droptarget.js +28 -0
  10. package/dist/cjs/dockview/accessibilityMessages.d.ts +32 -0
  11. package/dist/cjs/dockview/accessibilityMessages.js +51 -0
  12. package/dist/cjs/dockview/allModules.d.ts +8 -0
  13. package/dist/cjs/dockview/allModules.js +25 -0
  14. package/dist/cjs/dockview/components/panel/content.d.ts +2 -0
  15. package/dist/cjs/dockview/components/panel/content.js +35 -4
  16. package/dist/cjs/dockview/components/tab/tab.js +33 -5
  17. package/dist/cjs/dockview/components/titlebar/floatingTitleBar.d.ts +35 -0
  18. package/dist/cjs/dockview/components/titlebar/floatingTitleBar.js +95 -0
  19. package/dist/cjs/dockview/components/titlebar/groupDragSource.d.ts +52 -0
  20. package/dist/cjs/dockview/components/titlebar/groupDragSource.js +218 -0
  21. package/dist/cjs/dockview/components/titlebar/tabGroupIndicator.d.ts +2 -1
  22. package/dist/cjs/dockview/components/titlebar/tabGroupIndicator.js +31 -24
  23. package/dist/cjs/dockview/components/titlebar/tabGroups.js +1 -0
  24. package/dist/cjs/dockview/components/titlebar/tabs.d.ts +12 -0
  25. package/dist/cjs/dockview/components/titlebar/tabs.js +105 -2
  26. package/dist/cjs/dockview/components/titlebar/tabsContainer.d.ts +4 -0
  27. package/dist/cjs/dockview/components/titlebar/tabsContainer.js +13 -3
  28. package/dist/cjs/dockview/components/titlebar/voidContainer.d.ts +1 -4
  29. package/dist/cjs/dockview/components/titlebar/voidContainer.js +31 -155
  30. package/dist/cjs/dockview/dockviewComponent.d.ts +299 -44
  31. package/dist/cjs/dockview/dockviewComponent.js +1787 -1041
  32. package/dist/cjs/dockview/dockviewFloatingGroupPanel.d.ts +33 -2
  33. package/dist/cjs/dockview/dockviewFloatingGroupPanel.js +39 -3
  34. package/dist/cjs/dockview/dockviewGroupPanel.d.ts +0 -1
  35. package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts +36 -14
  36. package/dist/cjs/dockview/dockviewGroupPanelModel.js +133 -101
  37. package/dist/cjs/dockview/dockviewPanel.d.ts +2 -2
  38. package/dist/cjs/dockview/edgeGroupService.d.ts +38 -0
  39. package/dist/cjs/dockview/edgeGroupService.js +128 -0
  40. package/dist/cjs/dockview/floatingGroupService.d.ts +37 -0
  41. package/dist/cjs/dockview/floatingGroupService.js +231 -0
  42. package/dist/cjs/dockview/headerActionsService.d.ts +32 -0
  43. package/dist/cjs/dockview/headerActionsService.js +149 -0
  44. package/dist/cjs/dockview/liveRegionService.d.ts +53 -0
  45. package/dist/cjs/dockview/liveRegionService.js +185 -0
  46. package/dist/cjs/dockview/moduleContracts.d.ts +119 -0
  47. package/dist/cjs/dockview/moduleContracts.js +2 -0
  48. package/dist/cjs/dockview/modules.d.ts +110 -0
  49. package/dist/cjs/dockview/modules.js +304 -0
  50. package/dist/cjs/dockview/options.d.ts +159 -6
  51. package/dist/cjs/dockview/options.js +8 -1
  52. package/dist/cjs/dockview/popoutWindowService.d.ts +95 -0
  53. package/dist/cjs/dockview/popoutWindowService.js +261 -0
  54. package/dist/cjs/dockview/rootDropTargetService.d.ts +35 -0
  55. package/dist/cjs/dockview/rootDropTargetService.js +87 -0
  56. package/dist/cjs/dockview/watermarkService.d.ts +30 -0
  57. package/dist/cjs/dockview/watermarkService.js +61 -0
  58. package/dist/cjs/gridview/baseComponentGridview.d.ts +1 -1
  59. package/dist/cjs/gridview/baseComponentGridview.js +3 -2
  60. package/dist/cjs/gridview/gridviewComponent.d.ts +3 -3
  61. package/dist/cjs/gridview/gridviewPanel.d.ts +1 -1
  62. package/dist/cjs/index.d.ts +11 -4
  63. package/dist/cjs/index.js +14 -1
  64. package/dist/cjs/overlay/overlay.d.ts +43 -1
  65. package/dist/cjs/overlay/overlay.js +57 -8
  66. package/dist/cjs/paneview/draggablePaneviewPanel.d.ts +2 -2
  67. package/dist/cjs/paneview/draggablePaneviewPanel.js +4 -4
  68. package/dist/cjs/paneview/paneviewComponent.d.ts +3 -3
  69. package/dist/cjs/paneview/paneviewComponent.js +5 -5
  70. package/dist/dockview-core.js +3201 -1280
  71. package/dist/dockview-core.min.js +2 -2
  72. package/dist/dockview-core.min.js.map +1 -1
  73. package/dist/dockview-core.min.noStyle.js +2 -2
  74. package/dist/dockview-core.min.noStyle.js.map +1 -1
  75. package/dist/dockview-core.noStyle.js +3200 -1279
  76. package/dist/esm/api/component.api.d.ts +42 -21
  77. package/dist/esm/api/component.api.js +63 -18
  78. package/dist/esm/api/dockviewGroupPanelApi.d.ts +23 -8
  79. package/dist/esm/api/dockviewGroupPanelApi.js +19 -0
  80. package/dist/esm/api/dockviewPanelApi.d.ts +4 -3
  81. package/dist/esm/api/dockviewPanelApi.js +7 -0
  82. package/dist/esm/dnd/droptarget.d.ts +8 -0
  83. package/dist/esm/dnd/droptarget.js +28 -0
  84. package/dist/esm/dockview/accessibilityMessages.d.ts +32 -0
  85. package/dist/esm/dockview/accessibilityMessages.js +30 -0
  86. package/dist/esm/dockview/allModules.d.ts +8 -0
  87. package/dist/esm/dockview/allModules.js +22 -0
  88. package/dist/esm/dockview/components/panel/content.d.ts +2 -0
  89. package/dist/esm/dockview/components/panel/content.js +36 -5
  90. package/dist/esm/dockview/components/tab/tab.js +33 -5
  91. package/dist/esm/dockview/components/titlebar/floatingTitleBar.d.ts +35 -0
  92. package/dist/esm/dockview/components/titlebar/floatingTitleBar.js +65 -0
  93. package/dist/esm/dockview/components/titlebar/groupDragSource.d.ts +52 -0
  94. package/dist/esm/dockview/components/titlebar/groupDragSource.js +178 -0
  95. package/dist/esm/dockview/components/titlebar/tabGroupIndicator.d.ts +2 -1
  96. package/dist/esm/dockview/components/titlebar/tabGroupIndicator.js +31 -24
  97. package/dist/esm/dockview/components/titlebar/tabGroups.js +1 -0
  98. package/dist/esm/dockview/components/titlebar/tabs.d.ts +12 -0
  99. package/dist/esm/dockview/components/titlebar/tabs.js +102 -2
  100. package/dist/esm/dockview/components/titlebar/tabsContainer.d.ts +4 -0
  101. package/dist/esm/dockview/components/titlebar/tabsContainer.js +8 -2
  102. package/dist/esm/dockview/components/titlebar/voidContainer.d.ts +1 -4
  103. package/dist/esm/dockview/components/titlebar/voidContainer.js +33 -145
  104. package/dist/esm/dockview/dockviewComponent.d.ts +299 -44
  105. package/dist/esm/dockview/dockviewComponent.js +1420 -743
  106. package/dist/esm/dockview/dockviewFloatingGroupPanel.d.ts +33 -2
  107. package/dist/esm/dockview/dockviewFloatingGroupPanel.js +35 -3
  108. package/dist/esm/dockview/dockviewGroupPanel.d.ts +0 -1
  109. package/dist/esm/dockview/dockviewGroupPanelModel.d.ts +36 -14
  110. package/dist/esm/dockview/dockviewGroupPanelModel.js +109 -93
  111. package/dist/esm/dockview/dockviewPanel.d.ts +2 -2
  112. package/dist/esm/dockview/edgeGroupService.d.ts +38 -0
  113. package/dist/esm/dockview/edgeGroupService.js +63 -0
  114. package/dist/esm/dockview/floatingGroupService.d.ts +37 -0
  115. package/dist/esm/dockview/floatingGroupService.js +150 -0
  116. package/dist/esm/dockview/headerActionsService.d.ts +32 -0
  117. package/dist/esm/dockview/headerActionsService.js +86 -0
  118. package/dist/esm/dockview/liveRegionService.d.ts +53 -0
  119. package/dist/esm/dockview/liveRegionService.js +159 -0
  120. package/dist/esm/dockview/moduleContracts.d.ts +119 -0
  121. package/dist/esm/dockview/moduleContracts.js +1 -0
  122. package/dist/esm/dockview/modules.d.ts +110 -0
  123. package/dist/esm/dockview/modules.js +170 -0
  124. package/dist/esm/dockview/options.d.ts +159 -6
  125. package/dist/esm/dockview/options.js +8 -1
  126. package/dist/esm/dockview/popoutWindowService.d.ts +95 -0
  127. package/dist/esm/dockview/popoutWindowService.js +175 -0
  128. package/dist/esm/dockview/rootDropTargetService.d.ts +35 -0
  129. package/dist/esm/dockview/rootDropTargetService.js +82 -0
  130. package/dist/esm/dockview/watermarkService.d.ts +30 -0
  131. package/dist/esm/dockview/watermarkService.js +56 -0
  132. package/dist/esm/gridview/baseComponentGridview.d.ts +1 -1
  133. package/dist/esm/gridview/baseComponentGridview.js +2 -2
  134. package/dist/esm/gridview/gridviewComponent.d.ts +3 -3
  135. package/dist/esm/gridview/gridviewPanel.d.ts +1 -1
  136. package/dist/esm/index.d.ts +11 -4
  137. package/dist/esm/index.js +4 -0
  138. package/dist/esm/overlay/overlay.d.ts +43 -1
  139. package/dist/esm/overlay/overlay.js +53 -8
  140. package/dist/esm/paneview/draggablePaneviewPanel.d.ts +2 -2
  141. package/dist/esm/paneview/draggablePaneviewPanel.js +4 -4
  142. package/dist/esm/paneview/paneviewComponent.d.ts +3 -3
  143. package/dist/esm/paneview/paneviewComponent.js +5 -5
  144. package/dist/package/main.cjs.js +3236 -1315
  145. package/dist/package/main.cjs.min.js +2 -2
  146. package/dist/package/main.esm.min.mjs +2 -2
  147. package/dist/package/main.esm.mjs +3191 -1281
  148. package/dist/styles/dockview.css +275 -13
  149. package/package.json +10 -1
  150. package/dist/cjs/dockview/contextMenu.d.ts +0 -10
  151. package/dist/cjs/dockview/contextMenu.js +0 -313
  152. package/dist/esm/dockview/contextMenu.d.ts +0 -10
  153. package/dist/esm/dockview/contextMenu.js +0 -228
@@ -89,6 +89,7 @@ export class Tabs extends CompositeDisposable {
89
89
  return;
90
90
  }
91
91
  this._direction = value;
92
+ this._tabsList.setAttribute('aria-orientation', value === 'vertical' ? 'vertical' : 'horizontal');
92
93
  if (this._scrollbar) {
93
94
  this._scrollbar.orientation = value;
94
95
  }
@@ -134,6 +135,9 @@ export class Tabs extends CompositeDisposable {
134
135
  this.onOverflowTabsChange = this._onOverflowTabsChange.event;
135
136
  this._tabsList = document.createElement('div');
136
137
  this._tabsList.className = 'dv-tabs-container';
138
+ // WAI-ARIA Tabs pattern: the strip of tabs is the tablist.
139
+ this._tabsList.setAttribute('role', 'tablist');
140
+ this._tabsList.setAttribute('aria-orientation', this._direction === 'vertical' ? 'vertical' : 'horizontal');
137
141
  this.showTabsOverflowControl = options.showTabsOverflowControl;
138
142
  if (accessor.options.scrollbars === 'native') {
139
143
  this._element = this._tabsList;
@@ -153,7 +157,8 @@ export class Tabs extends CompositeDisposable {
153
157
  getDirection: () => this._direction,
154
158
  }, {
155
159
  onChipContextMenu: (tabGroup, event) => {
156
- this.accessor.contextMenuController.showForChip(tabGroup, this.group, event);
160
+ var _a;
161
+ (_a = this.accessor.contextMenuService) === null || _a === void 0 ? void 0 : _a.showForChip(tabGroup, this.group, event);
157
162
  },
158
163
  onChipDragStart: (tabGroup, chip, event) => {
159
164
  this._handleChipDragStart(tabGroup, chip, event);
@@ -246,7 +251,14 @@ export class Tabs extends CompositeDisposable {
246
251
  else {
247
252
  this._tabsList.scrollLeft = current + primary;
248
253
  }
249
- }, { passive: false }), addDisposableListener(this._tabsList, 'dragover', (event) => {
254
+ }, { passive: false }),
255
+ // WAI-ARIA Tabs keyboard pattern: arrow keys move the roving
256
+ // focus along the strip, Home/End jump to the ends, and
257
+ // Enter/Space activate the focused tab (manual activation, so
258
+ // arrowing through tabs doesn't switch panels until committed).
259
+ addDisposableListener(this._tabsList, 'keydown', (event) => {
260
+ this._onKeyDown(event);
261
+ }), addDisposableListener(this._tabsList, 'dragover', (event) => {
250
262
  if (this._processDragOver(event.clientX)) {
251
263
  // Allow `drop` to fire on the tabs list container.
252
264
  event.preventDefault();
@@ -325,10 +337,98 @@ export class Tabs extends CompositeDisposable {
325
337
  indexOf(id) {
326
338
  return this._tabs.findIndex((tab) => tab.value.panel.id === id);
327
339
  }
340
+ /** DOM id of the tab element for a panel — for the tabpanel's `aria-labelledby`. */
341
+ getTabId(panelId) {
342
+ var _a;
343
+ return (_a = this._tabMap.get(panelId)) === null || _a === void 0 ? void 0 : _a.value.element.id;
344
+ }
328
345
  isActive(tab) {
329
346
  return (this.selectedIndex > -1 &&
330
347
  this._tabs[this.selectedIndex].value === tab);
331
348
  }
349
+ _onKeyDown(event) {
350
+ // Only handle when a tab element itself is focused — never hijack keys
351
+ // typed inside a custom tab renderer's own controls (inputs etc.).
352
+ const index = this._tabs.findIndex((tab) => tab.value.element === event.target);
353
+ if (index === -1) {
354
+ return;
355
+ }
356
+ const isVertical = this._direction === 'vertical';
357
+ const nextKey = isVertical ? 'ArrowDown' : 'ArrowRight';
358
+ const prevKey = isVertical ? 'ArrowUp' : 'ArrowLeft';
359
+ const last = this._tabs.length - 1;
360
+ switch (event.key) {
361
+ case nextKey:
362
+ event.preventDefault();
363
+ this._focusTab(Math.min(index + 1, last));
364
+ break;
365
+ case prevKey:
366
+ event.preventDefault();
367
+ this._focusTab(Math.max(index - 1, 0));
368
+ break;
369
+ case 'Home':
370
+ event.preventDefault();
371
+ this._focusTab(0);
372
+ break;
373
+ case 'End':
374
+ event.preventDefault();
375
+ this._focusTab(last);
376
+ break;
377
+ case 'Enter':
378
+ case ' ':
379
+ // Manual activation of the focused tab.
380
+ event.preventDefault();
381
+ this.accessor.withOrigin('user', () => this._tabs[index].value.panel.api.setActive());
382
+ break;
383
+ case 'Delete':
384
+ case 'Backspace':
385
+ // Close the focused tab (Backspace covers macOS, where the
386
+ // primary delete key reports as Backspace).
387
+ event.preventDefault();
388
+ this._closeTab(index);
389
+ break;
390
+ }
391
+ }
392
+ /**
393
+ * Close the tab at `index` and move roving focus to a neighbouring tab so
394
+ * keyboard focus stays in the tablist.
395
+ */
396
+ _closeTab(index) {
397
+ var _a, _b, _c, _d, _e;
398
+ const tab = (_a = this._tabs[index]) === null || _a === void 0 ? void 0 : _a.value;
399
+ if (!tab) {
400
+ return;
401
+ }
402
+ // Resolve the post-close focus target before closing mutates the list:
403
+ // prefer the next tab, otherwise the previous.
404
+ const neighbourId = (_e = ((_c = (_b = this._tabs[index + 1]) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : (_d = this._tabs[index - 1]) === null || _d === void 0 ? void 0 : _d.value)) === null || _e === void 0 ? void 0 : _e.panel.id;
405
+ tab.panel.api.close();
406
+ if (neighbourId !== undefined) {
407
+ const nextIndex = this._tabs.findIndex((t) => t.value.panel.id === neighbourId);
408
+ if (nextIndex > -1) {
409
+ this._focusTab(nextIndex);
410
+ }
411
+ }
412
+ }
413
+ /** Move the roving focus to the tab at `index` (updates tabindex + DOM focus). */
414
+ _focusTab(index) {
415
+ for (let i = 0; i < this._tabs.length; i++) {
416
+ this._tabs[i].value.element.tabIndex = i === index ? 0 : -1;
417
+ }
418
+ this._tabs[index].value.element.focus();
419
+ }
420
+ /** Move DOM focus to the active tab — the entry point into the tablist. */
421
+ focusActiveTab() {
422
+ var _a;
423
+ if (this._tabs.length === 0) {
424
+ return;
425
+ }
426
+ const activeId = (_a = this.group.activePanel) === null || _a === void 0 ? void 0 : _a.id;
427
+ const activeIndex = activeId
428
+ ? this._tabs.findIndex((t) => t.value.panel.id === activeId)
429
+ : -1;
430
+ this._focusTab(activeIndex > -1 ? activeIndex : 0);
431
+ }
332
432
  setActivePanel(panel) {
333
433
  const isVertical = this._direction === 'vertical';
334
434
  let running = 0;
@@ -33,8 +33,10 @@ export interface ITabsContainer extends IDisposable {
33
33
  direction: DockviewHeaderDirection;
34
34
  delete(id: string): void;
35
35
  indexOf(id: string): number;
36
+ getTabId(panelId: string): string | undefined;
36
37
  setActive(isGroupActive: boolean): void;
37
38
  setActivePanel(panel: IDockviewPanel): void;
39
+ focusActiveTab(): void;
38
40
  isActive(tab: Tab): boolean;
39
41
  closePanel(panel: IDockviewPanel): void;
40
42
  openPanel(panel: IDockviewPanel, index?: number): void;
@@ -87,9 +89,11 @@ export declare class TabsContainer extends CompositeDisposable implements ITabsC
87
89
  setPrefixActionsElement(element: HTMLElement | undefined): void;
88
90
  isActive(tab: Tab): boolean;
89
91
  indexOf(id: string): number;
92
+ getTabId(panelId: string): string | undefined;
90
93
  setActive(_isGroupActive: boolean): void;
91
94
  delete(id: string): void;
92
95
  setActivePanel(panel: IDockviewPanel): void;
96
+ focusActiveTab(): void;
93
97
  openPanel(panel: IDockviewPanel, index?: number): void;
94
98
  closePanel(panel: IDockviewPanel): void;
95
99
  private updateClassnames;
@@ -198,6 +198,9 @@ export class TabsContainer extends CompositeDisposable {
198
198
  indexOf(id) {
199
199
  return this.tabs.indexOf(id);
200
200
  }
201
+ getTabId(panelId) {
202
+ return this.tabs.getTabId(panelId);
203
+ }
201
204
  setActive(_isGroupActive) {
202
205
  // noop
203
206
  }
@@ -208,6 +211,9 @@ export class TabsContainer extends CompositeDisposable {
208
211
  setActivePanel(panel) {
209
212
  this.tabs.setActivePanel(panel);
210
213
  }
214
+ focusActiveTab() {
215
+ this.tabs.focusActiveTab();
216
+ }
211
217
  openPanel(panel, index = this.tabs.size) {
212
218
  this.tabs.openPanel(panel, index);
213
219
  this.updateClassnames();
@@ -297,7 +303,7 @@ export class TabsContainer extends CompositeDisposable {
297
303
  const firstPanelId = tg.panelIds[0];
298
304
  if (firstPanelId) {
299
305
  const panel = this.group.panels.find((p) => p.id === firstPanelId);
300
- panel === null || panel === void 0 ? void 0 : panel.api.setActive();
306
+ this.accessor.withOrigin('user', () => panel === null || panel === void 0 ? void 0 : panel.api.setActive());
301
307
  }
302
308
  });
303
309
  el.appendChild(groupHeader);
@@ -323,7 +329,7 @@ export class TabsContainer extends CompositeDisposable {
323
329
  tg.expand();
324
330
  }
325
331
  tab.element.scrollIntoView();
326
- tab.panel.api.setActive();
332
+ this.accessor.withOrigin('user', () => tab.panel.api.setActive());
327
333
  });
328
334
  wrapper.appendChild(child);
329
335
  el.appendChild(wrapper);
@@ -9,9 +9,7 @@ export declare class VoidContainer extends CompositeDisposable {
9
9
  private readonly _element;
10
10
  private readonly dropTarget;
11
11
  private readonly pointerDropTarget;
12
- private readonly html5DragSource;
13
- private readonly pointerDragSource;
14
- private readonly panelTransfer;
12
+ private readonly dragSource;
15
13
  private readonly _onDrop;
16
14
  readonly onDrop: Event<DroptargetEvent>;
17
15
  private readonly _onDragStart;
@@ -20,5 +18,4 @@ export declare class VoidContainer extends CompositeDisposable {
20
18
  get element(): HTMLElement;
21
19
  constructor(accessor: DockviewComponent, group: DockviewGroupPanel);
22
20
  updateDragAndDropState(): void;
23
- private getFloatingOverlay;
24
21
  }
@@ -1,33 +1,24 @@
1
- import { getPanelData, LocalSelectionTransfer, PanelTransfer, } from '../../../dnd/dataTransfer';
2
- import { html5Backend, pointerBackend, } from '../../../dnd/backend';
1
+ import { getPanelData } from '../../../dnd/dataTransfer';
2
+ import { html5Backend, pointerBackend } from '../../../dnd/backend';
3
3
  import { addDisposableListener, Emitter, Event } from '../../../events';
4
- import { CompositeDisposable, Disposable, MutableDisposable, } from '../../../lifecycle';
5
- import { quasiPreventDefault, toggleClass } from '../../../dom';
6
- import { resolveDndCapabilities } from '../../dndCapabilities';
7
- // Floating-group redock via touch: require a deliberate long press so the
8
- // "move the float around" gesture doesn't double-trigger the redock ghost.
9
- // Infinity pressTolerance disables the pre-arm flick override; any motion
10
- // during the wait is treated as drag-the-float, not redock intent.
11
- const FLOATING_REDOCK_INITIATION_DELAY_MS = 500;
4
+ import { CompositeDisposable, Disposable } from '../../../lifecycle';
5
+ import { quasiPreventDefault } from '../../../dom';
6
+ import { GroupDragSource } from './groupDragSource';
12
7
  export class VoidContainer extends CompositeDisposable {
13
8
  get element() {
14
9
  return this._element;
15
10
  }
16
11
  constructor(accessor, group) {
17
- var _a, _b;
12
+ var _a, _b, _c, _d, _e, _f, _g;
18
13
  super();
19
14
  this.accessor = accessor;
20
15
  this.group = group;
21
- this.panelTransfer = LocalSelectionTransfer.getInstance();
22
16
  this._onDrop = new Emitter();
23
17
  this.onDrop = this._onDrop.event;
24
18
  this._onDragStart = new Emitter();
25
19
  this.onDragStart = this._onDragStart.event;
26
- const caps = resolveDndCapabilities(this.accessor.options);
27
20
  this._element = document.createElement('div');
28
21
  this._element.className = 'dv-void-container';
29
- this._element.draggable = caps.html5;
30
- toggleClass(this._element, 'dv-draggable', caps.html5 || caps.pointer);
31
22
  this.addDisposables(this._onDrop, this._onDragStart, addDisposableListener(this._element, 'pointerdown', () => {
32
23
  this.accessor.doSetGroupActive(this.group);
33
24
  }),
@@ -41,6 +32,18 @@ export class VoidContainer extends CompositeDisposable {
41
32
  quasiPreventDefault(e);
42
33
  }
43
34
  }, true));
35
+ // The drag-source (move-the-float disambiguation, redock ghost and
36
+ // group-level PanelTransfer) is shared with the floating title bar.
37
+ this.dragSource = new GroupDragSource({
38
+ element: this._element,
39
+ accessor: this.accessor,
40
+ group: this.group,
41
+ // The void container is the float's move handle only when there is
42
+ // no dedicated title bar. When a title bar moves the float (the
43
+ // overlay is `.dv-resize-container-with-titlebar`), the void
44
+ // container redocks with a plain drag, like a group in the grid.
45
+ isFloatingMoveHandle: () => !this._element.closest('.dv-resize-container-with-titlebar'),
46
+ });
44
47
  const canDisplayOverlay = (event, position) => {
45
48
  if (this.group.api.locked) {
46
49
  // Dropping on the void/header space adds the panel
@@ -58,147 +61,32 @@ export class VoidContainer extends CompositeDisposable {
58
61
  acceptedTargetZones: ['center'],
59
62
  canDisplayOverlay,
60
63
  getOverrideTarget: () => { var _a; return (_a = group.model.dropTargetContainer) === null || _a === void 0 ? void 0 : _a.model; },
64
+ overlayModel: (_b = (_a = this.accessor).resolveDropOverlayModel) === null || _b === void 0 ? void 0 : _b.call(_a, 'header_space', this.group),
61
65
  });
62
66
  this.pointerDropTarget = pointerBackend.createDropTarget(this._element, {
63
67
  acceptedTargetZones: ['center'],
64
68
  canDisplayOverlay,
65
69
  getOverrideTarget: () => { var _a; return (_a = group.model.dropTargetContainer) === null || _a === void 0 ? void 0 : _a.model; },
70
+ overlayModel: (_d = (_c = this.accessor).resolveDropOverlayModel) === null || _d === void 0 ? void 0 : _d.call(_c, 'header_space', this.group),
66
71
  });
67
- const buildMultiPanelsGhost = () => {
68
- const ghostEl = document.createElement('div');
69
- const style = window.getComputedStyle(this._element);
70
- const bgColor = style.getPropertyValue('--dv-activegroup-visiblepanel-tab-background-color');
71
- const color = style.getPropertyValue('--dv-activegroup-visiblepanel-tab-color');
72
- ghostEl.style.backgroundColor = bgColor;
73
- ghostEl.style.color = color;
74
- ghostEl.style.padding = '2px 8px';
75
- ghostEl.style.height = '24px';
76
- ghostEl.style.fontSize = '11px';
77
- ghostEl.style.lineHeight = '20px';
78
- ghostEl.style.borderRadius = '12px';
79
- ghostEl.style.whiteSpace = 'nowrap';
80
- ghostEl.style.boxSizing = 'border-box';
81
- // HTML5 setDragImage snapshots the element as appended to the
82
- // document; a default block-level div would stretch to the
83
- // body's width and render as a viewport-wide bar.
84
- ghostEl.style.display = 'inline-block';
85
- ghostEl.textContent = `Multiple Panels (${this.group.size})`;
86
- return ghostEl;
87
- };
88
- const buildGhostSpec = () => {
89
- const createGhost = this.accessor.options.createGroupDragGhostComponent;
90
- if (createGhost) {
91
- const renderer = createGhost(this.group);
92
- renderer.init({
93
- group: this.group,
94
- api: this.accessor.api,
95
- });
96
- return {
97
- element: renderer.element,
98
- offsetX: 30,
99
- offsetY: -10,
100
- dispose: renderer.dispose
101
- ? () => { var _a; return (_a = renderer.dispose) === null || _a === void 0 ? void 0 : _a.call(renderer); }
102
- : undefined,
103
- };
104
- }
105
- return {
106
- element: buildMultiPanelsGhost(),
107
- offsetX: 30,
108
- offsetY: -10,
109
- };
110
- };
111
- const sharedDragOptions = {
112
- getData: () => {
113
- this.panelTransfer.setData([new PanelTransfer(this.accessor.id, this.group.id, null)], PanelTransfer.prototype);
114
- return {
115
- dispose: () => {
116
- this.panelTransfer.clearData(PanelTransfer.prototype);
117
- },
118
- };
119
- },
120
- createGhost: buildGhostSpec,
121
- onDragStart: (event) => {
122
- this._onDragStart.fire(event);
123
- },
124
- };
125
- this.html5DragSource = html5Backend.createDragSource(this._element, Object.assign(Object.assign({}, sharedDragOptions), { disabled: !caps.html5, isCancelled: (event) => {
126
- // HTML5: floating groups need shift+drag as the explicit
127
- // detach gesture (otherwise click-and-drag conflicts with
128
- // moving the floating group itself).
129
- if (this.group.api.location.type === 'floating' &&
130
- !event.shiftKey) {
131
- return true;
132
- }
133
- if (this.group.api.location.type === 'edge' &&
134
- this.group.size === 0) {
135
- return true;
136
- }
137
- return false;
138
- } }));
139
- const isFloating = () => { var _a, _b, _c; return ((_c = (_b = (_a = this.group) === null || _a === void 0 ? void 0 : _a.api) === null || _b === void 0 ? void 0 : _b.location) === null || _c === void 0 ? void 0 : _c.type) === 'floating'; };
140
- this.pointerDragSource = pointerBackend.createDragSource(this._element, Object.assign(Object.assign({}, sharedDragOptions), { disabled: !caps.pointer, touchOnly: !caps.pointerHandlesMouse,
141
- // Floating groups share this element with the overlay's
142
- // move-the-float drag. Without a longer hold + tolerance
143
- // override, both gestures commit simultaneously and the
144
- // user sees the float follow their finger *and* a ghost.
145
- touchInitiationDelay: () => isFloating() ? FLOATING_REDOCK_INITIATION_DELAY_MS : 250, pressTolerance: () => (isFloating() ? Infinity : 8), isCancelled: () => {
146
- if (!resolveDndCapabilities(this.accessor.options).pointer) {
147
- return true;
148
- }
149
- // Pointer: long-press IS the deliberate gesture, so
150
- // floating groups don't need the shift gate.
151
- if (this.group.api.location.type === 'edge' &&
152
- this.group.size === 0) {
153
- return true;
154
- }
155
- return false;
156
- }, onDragStart: (event) => {
157
- var _a;
158
- // Redock just committed — abort any in-flight overlay
159
- // move so the float stops following the finger while
160
- // the ghost takes over.
161
- (_a = this.getFloatingOverlay()) === null || _a === void 0 ? void 0 : _a.cancelPendingDrag();
162
- this._onDragStart.fire(event);
163
- } }));
164
- // Mirror direction: once the overlay's move-the-float gesture has
165
- // actually moved something, cancel the pending redock arm so the
166
- // ghost doesn't appear mid-drag if the user holds past 500ms.
167
- const overlayMoveSub = new MutableDisposable();
168
- const refreshOverlayMoveSub = () => {
169
- const overlay = this.getFloatingOverlay();
170
- overlayMoveSub.value = overlay
171
- ? overlay.onDidStartMoving(() => {
172
- this.pointerDragSource.cancelPending();
173
- })
174
- : Disposable.NONE;
175
- };
176
- refreshOverlayMoveSub();
177
- this.addDisposables(overlayMoveSub);
178
- const locationChange = (_b = (_a = this.group) === null || _a === void 0 ? void 0 : _a.api) === null || _b === void 0 ? void 0 : _b.onDidLocationChange;
179
- if (locationChange) {
180
- this.addDisposables(locationChange(refreshOverlayMoveSub));
181
- }
182
72
  this.onWillShowOverlay = Event.any(this.dropTarget.onWillShowOverlay, this.pointerDropTarget.onWillShowOverlay);
183
- this.addDisposables(this.html5DragSource, this.dropTarget.onDrop((event) => {
73
+ this.addDisposables(this.dragSource, this.dragSource.onDragStart((event) => {
74
+ this._onDragStart.fire(event);
75
+ }), this.dropTarget.onDrop((event) => {
184
76
  this._onDrop.fire(event);
185
77
  }), this.pointerDropTarget.onDrop((event) => {
186
78
  this._onDrop.fire(event);
187
- }), this.dropTarget, this.pointerDropTarget, this.pointerDragSource);
79
+ }), this.dropTarget, this.pointerDropTarget,
80
+ // Re-apply the app-supplied overlay model when options change.
81
+ // `{}` resets to the built-in default (all fields optional).
82
+ (_g = (_f = (_e = this.accessor).onDidOptionsChange) === null || _f === void 0 ? void 0 : _f.call(_e, () => {
83
+ var _a, _b, _c;
84
+ const model = (_c = (_b = (_a = this.accessor).resolveDropOverlayModel) === null || _b === void 0 ? void 0 : _b.call(_a, 'header_space', this.group)) !== null && _c !== void 0 ? _c : {};
85
+ this.dropTarget.setOverlayModel(model);
86
+ this.pointerDropTarget.setOverlayModel(model);
87
+ })) !== null && _g !== void 0 ? _g : Disposable.NONE);
188
88
  }
189
89
  updateDragAndDropState() {
190
- const caps = resolveDndCapabilities(this.accessor.options);
191
- this._element.draggable = caps.html5;
192
- toggleClass(this._element, 'dv-draggable', caps.html5 || caps.pointer);
193
- this.html5DragSource.setDisabled(!caps.html5);
194
- this.pointerDragSource.setDisabled(!caps.pointer);
195
- this.pointerDragSource.setTouchOnly(!caps.pointerHandlesMouse);
196
- }
197
- getFloatingOverlay() {
198
- var _a, _b;
199
- if (!this.group) {
200
- return undefined;
201
- }
202
- return (_b = (_a = this.accessor.floatingGroups) === null || _a === void 0 ? void 0 : _a.find((fg) => fg.group === this.group)) === null || _b === void 0 ? void 0 : _b.overlay;
90
+ this.dragSource.updateDragAndDropState();
203
91
  }
204
92
  }