dockview-core 6.6.0 → 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 -993
  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 +3199 -1251
  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 +3198 -1250
  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 +1421 -717
  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 +3234 -1286
  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 +3189 -1252
  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
@@ -1,14 +1,45 @@
1
1
  import { Overlay } from '../overlay/overlay';
2
2
  import { CompositeDisposable } from '../lifecycle';
3
+ import { Gridview } from '../gridview/gridview';
3
4
  import { AnchoredBox } from '../types';
4
5
  import { DockviewGroupPanel, IDockviewGroupPanel } from './dockviewGroupPanel';
5
6
  export interface IDockviewFloatingGroupPanel {
6
7
  readonly group: IDockviewGroupPanel;
7
8
  position(bounds: Partial<AnchoredBox>): void;
8
9
  }
10
+ /**
11
+ * The subset of the dedicated floating title bar this panel needs to keep in
12
+ * sync. Declared structurally to avoid a circular import on `FloatingTitleBar`.
13
+ */
14
+ export interface IAnchorTrackingTitleBar {
15
+ setGroup(group: DockviewGroupPanel): void;
16
+ }
9
17
  export declare class DockviewFloatingGroupPanel extends CompositeDisposable implements IDockviewFloatingGroupPanel {
10
- readonly group: DockviewGroupPanel;
11
18
  readonly overlay: Overlay;
12
- constructor(group: DockviewGroupPanel, overlay: Overlay);
19
+ /**
20
+ * The floating window hosts its own gridview so it can hold a nested
21
+ * splitview layout of groups, not just a single group.
22
+ */
23
+ readonly gridview: Gridview;
24
+ private _group;
25
+ private _titleBar;
26
+ /**
27
+ * The window's representative/anchor group. A floating window can host a
28
+ * nested layout of several groups; the anchor is used for back-compat
29
+ * single-group APIs and is reassigned if it leaves the window.
30
+ */
31
+ get group(): DockviewGroupPanel;
32
+ /**
33
+ * Register the dedicated title bar (if any) so anchor reassignment keeps
34
+ * its drag handle pointed at a group that still lives in this window.
35
+ */
36
+ setTitleBar(titleBar: IAnchorTrackingTitleBar | undefined): void;
37
+ setAnchorGroup(group: DockviewGroupPanel): void;
38
+ constructor(group: DockviewGroupPanel, overlay: Overlay,
39
+ /**
40
+ * The floating window hosts its own gridview so it can hold a nested
41
+ * splitview layout of groups, not just a single group.
42
+ */
43
+ gridview: Gridview);
13
44
  position(bounds: Partial<AnchoredBox>): void;
14
45
  }
@@ -1,10 +1,42 @@
1
1
  import { CompositeDisposable } from '../lifecycle';
2
2
  export class DockviewFloatingGroupPanel extends CompositeDisposable {
3
- constructor(group, overlay) {
3
+ /**
4
+ * The window's representative/anchor group. A floating window can host a
5
+ * nested layout of several groups; the anchor is used for back-compat
6
+ * single-group APIs and is reassigned if it leaves the window.
7
+ */
8
+ get group() {
9
+ return this._group;
10
+ }
11
+ /**
12
+ * Register the dedicated title bar (if any) so anchor reassignment keeps
13
+ * its drag handle pointed at a group that still lives in this window.
14
+ */
15
+ setTitleBar(titleBar) {
16
+ this._titleBar = titleBar;
17
+ }
18
+ setAnchorGroup(group) {
19
+ var _a;
20
+ this._group = group;
21
+ (_a = this._titleBar) === null || _a === void 0 ? void 0 : _a.setGroup(group);
22
+ }
23
+ constructor(group, overlay,
24
+ /**
25
+ * The floating window hosts its own gridview so it can hold a nested
26
+ * splitview layout of groups, not just a single group.
27
+ */
28
+ gridview) {
4
29
  super();
5
- this.group = group;
6
30
  this.overlay = overlay;
7
- this.addDisposables(overlay);
31
+ this.gridview = gridview;
32
+ this._group = group;
33
+ this.addDisposables(overlay, {
34
+ // The gridview owns the floating window's DOM subtree (mounted as
35
+ // the overlay's content). Disposing it tears down the splitview;
36
+ // it does NOT dispose the leaf views (groups) — their lifecycle is
37
+ // owned by the component's `_groups` map.
38
+ dispose: () => this.gridview.dispose(),
39
+ });
8
40
  }
9
41
  position(bounds) {
10
42
  this.overlay.setBounds(bounds);
@@ -11,7 +11,6 @@ export interface IDockviewGroupPanel extends IGridviewPanel<DockviewGroupPanelAp
11
11
  readonly panels: IDockviewPanel[];
12
12
  readonly activePanel: IDockviewPanel | undefined;
13
13
  }
14
- export type IDockviewGroupPanelPublic = IDockviewGroupPanel;
15
14
  export declare class DockviewGroupPanel extends GridviewPanel<DockviewGroupPanelApiImpl> implements IDockviewGroupPanel {
16
15
  private readonly _model;
17
16
  private _explicitConstraints;
@@ -1,7 +1,7 @@
1
1
  import { DockviewApi } from '../api/component.api';
2
2
  import { PanelTransfer } from '../dnd/dataTransfer';
3
- import { Position } from '../dnd/droptarget';
4
- import { DockviewComponent } from './dockviewComponent';
3
+ import { Droptarget, Position } from '../dnd/droptarget';
4
+ import { DockviewComponent, DockviewOrigin } from './dockviewComponent';
5
5
  import { DockviewEvent, Event } from '../events';
6
6
  import { DockviewGroupDropLocation, DockviewWillShowOverlayLocationEvent } from './events';
7
7
  import { IViewSize } from '../gridview/gridview';
@@ -13,7 +13,7 @@ import { IDockviewPanel } from './dockviewPanel';
13
13
  import { DockviewDndOverlayEvent, DockviewHeaderDirection, DockviewHeaderPosition } from './options';
14
14
  import { OverlayRenderContainer } from '../overlay/overlayRenderContainer';
15
15
  import { TitleEvent } from '../api/dockviewPanelApi';
16
- import { Contraints } from '../gridview/gridviewPanel';
16
+ import { Constraints } from '../gridview/gridviewPanel';
17
17
  import { DropTargetAnchorContainer } from '../dnd/dropTargetAnchorContainer';
18
18
  import { ITabGroup, SerializedTabGroup, TabGroupOptions } from './tabGroup';
19
19
  import { EdgeGroupPosition } from './dockviewShell';
@@ -29,7 +29,7 @@ interface CoreGroupOptions {
29
29
  hideHeader?: boolean;
30
30
  headerPosition?: 'top' | 'bottom' | 'left' | 'right';
31
31
  skipSetActive?: boolean;
32
- constraints?: Partial<Contraints>;
32
+ constraints?: Partial<Constraints>;
33
33
  initialWidth?: number;
34
34
  initialHeight?: number;
35
35
  }
@@ -47,6 +47,15 @@ export interface GroupPanelViewState extends CoreGroupOptions {
47
47
  export interface DockviewGroupChangeEvent {
48
48
  readonly panel: IDockviewPanel;
49
49
  }
50
+ /**
51
+ * Payload for the group-level `onDidActivePanelChange`. Extends
52
+ * {@link DockviewGroupChangeEvent} with the {@link DockviewOrigin} so it mirrors
53
+ * the component-level `DockviewActivePanelChangeEvent` — both report whether the
54
+ * change came from a user gesture or an API call.
55
+ */
56
+ export interface DockviewGroupActivePanelChangeEvent extends DockviewGroupChangeEvent {
57
+ readonly origin: DockviewOrigin;
58
+ }
50
59
  export interface CreateTabGroupOptions extends TabGroupOptions {
51
60
  id?: string;
52
61
  }
@@ -100,7 +109,7 @@ export interface IDockviewGroupPanelModel extends IPanel {
100
109
  readonly onWillDrop: Event<DockviewWillDropEvent>;
101
110
  readonly onDidAddPanel: Event<DockviewGroupChangeEvent>;
102
111
  readonly onDidRemovePanel: Event<DockviewGroupChangeEvent>;
103
- readonly onDidActivePanelChange: Event<DockviewGroupChangeEvent>;
112
+ readonly onDidActivePanelChange: Event<DockviewGroupActivePanelChangeEvent>;
104
113
  readonly onMove: Event<GroupMoveEvent>;
105
114
  locked: DockviewGroupPanelLocked;
106
115
  headerPosition: DockviewHeaderPosition;
@@ -127,6 +136,8 @@ export interface IDockviewGroupPanelModel extends IPanel {
127
136
  suppressRoll?: boolean;
128
137
  }): void;
129
138
  canDisplayOverlay(event: DragEvent | PointerEvent, position: Position, target: DockviewGroupDropLocation): boolean;
139
+ updateHeaderActions(): void;
140
+ attachHeaderAction(slot: 'left' | 'right' | 'prefix', element: HTMLElement | undefined): void;
130
141
  }
131
142
  export type DockviewGroupLocation = {
132
143
  type: 'grid';
@@ -152,12 +163,6 @@ export declare class DockviewGroupPanelModel extends CompositeDisposable impleme
152
163
  private watermark?;
153
164
  private _isGroupActive;
154
165
  private _locked;
155
- private _rightHeaderActions;
156
- private _leftHeaderActions;
157
- private _prefixHeaderActions;
158
- private readonly _rightHeaderActionsDisposable;
159
- private readonly _leftHeaderActionsDisposable;
160
- private readonly _prefixHeaderActionsDisposable;
161
166
  private _headerPosition;
162
167
  private _location;
163
168
  private mostRecentlyUsed;
@@ -192,9 +197,9 @@ export declare class DockviewGroupPanelModel extends CompositeDisposable impleme
192
197
  private readonly _onDidRemovePanel;
193
198
  readonly onDidRemovePanel: Event<DockviewGroupChangeEvent>;
194
199
  private readonly _onDidActivePanelChange;
195
- readonly onDidActivePanelChange: Event<DockviewGroupChangeEvent>;
196
- private readonly _onUnhandledDragOverEvent;
197
- readonly onUnhandledDragOverEvent: Event<DockviewDndOverlayEvent>;
200
+ readonly onDidActivePanelChange: Event<DockviewGroupActivePanelChangeEvent>;
201
+ private readonly _onUnhandledDragOver;
202
+ readonly onUnhandledDragOver: Event<DockviewDndOverlayEvent>;
198
203
  private readonly _tabGroups;
199
204
  private readonly _tabGroupMap;
200
205
  private readonly _panelToTabGroup;
@@ -230,6 +235,10 @@ export declare class DockviewGroupPanelModel extends CompositeDisposable impleme
230
235
  get tabGroups(): readonly ITabGroup[];
231
236
  get element(): HTMLElement;
232
237
  get activePanel(): IDockviewPanel | undefined;
238
+ /** DOM id of the content container (the group's tabpanel), referenced by each tab's `aria-controls`. */
239
+ get contentContainerId(): string;
240
+ /** The group's content drop target — lets keyboard docking preview a drop here. */
241
+ get contentDropTarget(): Droptarget;
233
242
  get locked(): DockviewGroupPanelLocked;
234
243
  set locked(value: DockviewGroupPanelLocked);
235
244
  get isActive(): boolean;
@@ -245,7 +254,16 @@ export declare class DockviewGroupPanelModel extends CompositeDisposable impleme
245
254
  set location(value: DockviewGroupLocation);
246
255
  constructor(container: HTMLElement, accessor: DockviewComponent, id: string, options: GroupOptions, groupPanel: DockviewGroupPanel);
247
256
  private _scheduleTabGroupUpdate;
257
+ /**
258
+ * Bracket a tab-group mutation as a layout transaction. `accessor` is
259
+ * always a full {@link DockviewComponent} in production; the optional-call
260
+ * fallback keeps partial test doubles (which omit `mutation`) working.
261
+ * When nested inside a larger operation (a drag-driven move, fromJSON
262
+ * restore) the component's depth counter folds it into the outer one.
263
+ */
264
+ private _bracketTabGroupMutation;
248
265
  createTabGroup(options?: CreateTabGroupOptions): ITabGroup;
266
+ private _doCreateTabGroup;
249
267
  dissolveTabGroup(tabGroupId: string): void;
250
268
  addPanelToTabGroup(tabGroupId: string, panelId: string, index?: number): void;
251
269
  /**
@@ -285,12 +303,14 @@ export declare class DockviewGroupPanelModel extends CompositeDisposable impleme
285
303
  /** Restore tab groups from serialized data (used by fromJSON) */
286
304
  restoreTabGroups(serializedGroups: SerializedTabGroup[]): void;
287
305
  focusContent(): void;
306
+ focusActiveTab(): void;
288
307
  set renderContainer(value: OverlayRenderContainer | null);
289
308
  get renderContainer(): OverlayRenderContainer;
290
309
  set dropTargetContainer(value: DropTargetAnchorContainer | null);
291
310
  get dropTargetContainer(): DropTargetAnchorContainer | null;
292
311
  initialize(): void;
293
312
  updateHeaderActions(): void;
313
+ attachHeaderAction(slot: 'left' | 'right' | 'prefix', element: HTMLElement | undefined): void;
294
314
  rerender(panel: IDockviewPanel): void;
295
315
  indexOf(panel: IDockviewPanel): number;
296
316
  toJSON(): GroupPanelViewState;
@@ -326,6 +346,8 @@ export declare class DockviewGroupPanelModel extends CompositeDisposable impleme
326
346
  private doRemovePanel;
327
347
  private doAddPanel;
328
348
  private doSetActivePanel;
349
+ /** Label the group region with its active panel's title (the WAI-ARIA region name). */
350
+ private updateAccessibleLabel;
329
351
  private updateMru;
330
352
  private updateContainer;
331
353
  canDisplayOverlay(event: DragEvent | PointerEvent, position: Position, target: DockviewGroupDropLocation): boolean;
@@ -3,7 +3,7 @@ import { getPanelData } from '../dnd/dataTransfer';
3
3
  import { addClasses, isAncestor, removeClasses, toggleClass } from '../dom';
4
4
  import { addDisposableListener, DockviewEvent, Emitter, } from '../events';
5
5
  import { DockviewWillShowOverlayLocationEvent, } from './events';
6
- import { CompositeDisposable, MutableDisposable, } from '../lifecycle';
6
+ import { CompositeDisposable } from '../lifecycle';
7
7
  import { ContentContainer, } from './components/panel/content';
8
8
  import { TabsContainer, } from './components/titlebar/tabsContainer';
9
9
  import { DockviewUnhandledDragOverEvent, } from './options';
@@ -55,6 +55,14 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
55
55
  get activePanel() {
56
56
  return this._activePanel;
57
57
  }
58
+ /** DOM id of the content container (the group's tabpanel), referenced by each tab's `aria-controls`. */
59
+ get contentContainerId() {
60
+ return this.contentContainer.element.id;
61
+ }
62
+ /** The group's content drop target — lets keyboard docking preview a drop here. */
63
+ get contentDropTarget() {
64
+ return this.contentContainer.dropTarget;
65
+ }
58
66
  get locked() {
59
67
  return this._locked;
60
68
  }
@@ -103,11 +111,7 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
103
111
  if ((_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.layout) {
104
112
  this._activePanel.layout(this._width, this._height);
105
113
  }
106
- if (this._leftHeaderActions ||
107
- this._rightHeaderActions ||
108
- this._prefixHeaderActions) {
109
- this.updateHeaderActions();
110
- }
114
+ this.updateHeaderActions();
111
115
  }
112
116
  get location() {
113
117
  return this._location;
@@ -127,14 +131,15 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
127
131
  applyZones(['top', 'bottom', 'left', 'right', 'center']);
128
132
  break;
129
133
  case 'floating':
130
- applyZones(['center']);
131
- applyZones(value
132
- ? ['center']
133
- : ['top', 'bottom', 'left', 'right', 'center']);
134
+ // Floating windows host their own nested gridview, so an edge
135
+ // drop splits the window's layout just like the main grid.
136
+ applyZones(['top', 'bottom', 'left', 'right', 'center']);
134
137
  toggleClass(this.container, 'dv-groupview-floating', true);
135
138
  break;
136
139
  case 'popout':
137
- applyZones(['center']);
140
+ // Popout windows host their own nested gridview, so an edge
141
+ // drop splits the window's layout just like the main grid.
142
+ applyZones(['top', 'bottom', 'left', 'right', 'center']);
138
143
  toggleClass(this.container, 'dv-groupview-popout', true);
139
144
  break;
140
145
  case 'edge':
@@ -156,9 +161,6 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
156
161
  this.groupPanel = groupPanel;
157
162
  this._isGroupActive = false;
158
163
  this._locked = false;
159
- this._rightHeaderActionsDisposable = new MutableDisposable();
160
- this._leftHeaderActionsDisposable = new MutableDisposable();
161
- this._prefixHeaderActionsDisposable = new MutableDisposable();
162
164
  this._location = { type: 'grid' };
163
165
  this.mostRecentlyUsed = [];
164
166
  this._overwriteRenderContainer = null;
@@ -193,8 +195,8 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
193
195
  this.onDidRemovePanel = this._onDidRemovePanel.event;
194
196
  this._onDidActivePanelChange = new Emitter();
195
197
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
196
- this._onUnhandledDragOverEvent = new Emitter();
197
- this.onUnhandledDragOverEvent = this._onUnhandledDragOverEvent.event;
198
+ this._onUnhandledDragOver = new Emitter();
199
+ this.onUnhandledDragOver = this._onUnhandledDragOver.event;
198
200
  this._tabGroups = [];
199
201
  this._tabGroupMap = new Map();
200
202
  this._panelToTabGroup = new Map();
@@ -213,6 +215,9 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
213
215
  this._onDidTabGroupCollapsedChange = new Emitter();
214
216
  this.onDidTabGroupCollapsedChange = this._onDidTabGroupCollapsedChange.event;
215
217
  toggleClass(this.container, 'dv-groupview', true);
218
+ // Each group is a navigable region, labelled by its active panel
219
+ // (see `updateAccessibleLabel`, driven on activation / title change).
220
+ this.container.setAttribute('role', 'region');
216
221
  this._api = new DockviewApi(this.accessor);
217
222
  this.tabsContainer = new TabsContainer(this.accessor, this.groupPanel);
218
223
  this.contentContainer = new ContentContainer(this.accessor, this);
@@ -221,7 +226,10 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
221
226
  this.locked = (_a = options.locked) !== null && _a !== void 0 ? _a : false;
222
227
  this.headerPosition =
223
228
  (_b = options.headerPosition) !== null && _b !== void 0 ? _b : accessor.defaultHeaderPosition;
224
- this.addDisposables(this._onTabDragStart, this._onGroupDragStart, this._onWillShowOverlay, this._rightHeaderActionsDisposable, this._leftHeaderActionsDisposable, this._prefixHeaderActionsDisposable, this.tabsContainer.onTabDragStart((event) => {
229
+ this.addDisposables(
230
+ // Keep the region's accessible name in sync when the active
231
+ // panel's title changes (no-op when a non-active title changes).
232
+ this._onDidPanelTitleChange.event(() => this.updateAccessibleLabel()), this._onTabDragStart, this._onGroupDragStart, this._onWillShowOverlay, this.tabsContainer.onTabDragStart((event) => {
225
233
  this._onTabDragStart.fire(event);
226
234
  }), this.tabsContainer.onGroupDragStart((event) => {
227
235
  this._onGroupDragStart.fire(event);
@@ -284,7 +292,7 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
284
292
  group: this.groupPanel,
285
293
  getData: getPanelData,
286
294
  }));
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(() => {
295
+ }), this._onMove, this._onDidChange, this._onDidDrop, this._onWillDrop, this._onDidAddPanel, this._onDidRemovePanel, this._onDidActivePanelChange, this._onUnhandledDragOver, this._onDidPanelTitleChange, this._onDidPanelParametersChange, this._onDidCreateTabGroup, this._onDidDestroyTabGroup, this._onDidAddPanelToTabGroup, this._onDidRemovePanelFromTabGroup, this._onDidTabGroupChange, this._onDidTabGroupCollapsedChange, this._onDidCreateTabGroup.event(() => {
288
296
  this._scheduleTabGroupUpdate();
289
297
  }), this._onDidDestroyTabGroup.event(() => {
290
298
  this._scheduleTabGroupUpdate();
@@ -310,7 +318,22 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
310
318
  }
311
319
  });
312
320
  }
321
+ /**
322
+ * Bracket a tab-group mutation as a layout transaction. `accessor` is
323
+ * always a full {@link DockviewComponent} in production; the optional-call
324
+ * fallback keeps partial test doubles (which omit `mutation`) working.
325
+ * When nested inside a larger operation (a drag-driven move, fromJSON
326
+ * restore) the component's depth counter folds it into the outer one.
327
+ */
328
+ _bracketTabGroupMutation(func) {
329
+ return this.accessor.mutation
330
+ ? this.accessor.mutation('tab-group', func)
331
+ : func();
332
+ }
313
333
  createTabGroup(options) {
334
+ return this._bracketTabGroupMutation(() => this._doCreateTabGroup(options));
335
+ }
336
+ _doCreateTabGroup(options) {
314
337
  var _a;
315
338
  const id = (_a = options === null || options === void 0 ? void 0 : options.id) !== null && _a !== void 0 ? _a : `tg-${this.id}-${this._tabGroupIdCounter++}`;
316
339
  const tabGroup = new TabGroup(id, {
@@ -344,14 +367,16 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
344
367
  if (!tabGroup) {
345
368
  return;
346
369
  }
347
- // Remove all panels from the group (they stay in the flat panel list)
348
- const panelIds = [...tabGroup.panelIds];
349
- for (const panelId of panelIds) {
350
- tabGroup.removePanel(panelId);
351
- this._panelToTabGroup.delete(panelId);
352
- this._onDidRemovePanelFromTabGroup.fire({ tabGroup, panelId });
353
- }
354
- tabGroup.dispose();
370
+ this._bracketTabGroupMutation(() => {
371
+ // Remove all panels from the group (they stay in the flat panel list)
372
+ const panelIds = [...tabGroup.panelIds];
373
+ for (const panelId of panelIds) {
374
+ tabGroup.removePanel(panelId);
375
+ this._panelToTabGroup.delete(panelId);
376
+ this._onDidRemovePanelFromTabGroup.fire({ tabGroup, panelId });
377
+ }
378
+ tabGroup.dispose();
379
+ });
355
380
  }
356
381
  addPanelToTabGroup(tabGroupId, panelId, index) {
357
382
  const tabGroup = this._tabGroupMap.get(tabGroupId);
@@ -364,18 +389,20 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
364
389
  }
365
390
  // Remove from any existing group first
366
391
  const existingGroup = this.getTabGroupForPanel(panelId);
367
- if (existingGroup) {
368
- if (existingGroup.id === tabGroupId) {
369
- return; // already in this group
370
- }
371
- this.removePanelFromTabGroup(panelId);
392
+ if (existingGroup && existingGroup.id === tabGroupId) {
393
+ return; // already in this group — no mutation
372
394
  }
373
- tabGroup.addPanel(panelId, index);
374
- this._panelToTabGroup.set(panelId, tabGroup);
375
- // Enforce contiguity: move the panel in the flat _panels array
376
- // to the correct global position matching its group-local index
377
- this._enforceContiguity(tabGroup, panelId);
378
- this._onDidAddPanelToTabGroup.fire({ tabGroup, panelId });
395
+ this._bracketTabGroupMutation(() => {
396
+ if (existingGroup) {
397
+ this.removePanelFromTabGroup(panelId);
398
+ }
399
+ tabGroup.addPanel(panelId, index);
400
+ this._panelToTabGroup.set(panelId, tabGroup);
401
+ // Enforce contiguity: move the panel in the flat _panels array
402
+ // to the correct global position matching its group-local index
403
+ this._enforceContiguity(tabGroup, panelId);
404
+ this._onDidAddPanelToTabGroup.fire({ tabGroup, panelId });
405
+ });
379
406
  }
380
407
  /**
381
408
  * Move a panel to a new index within its tab group.
@@ -523,13 +550,15 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
523
550
  if (!tabGroup) {
524
551
  return;
525
552
  }
526
- tabGroup.removePanel(panelId);
527
- this._panelToTabGroup.delete(panelId);
528
- this._onDidRemovePanelFromTabGroup.fire({ tabGroup, panelId });
529
- // Auto-destroy empty groups
530
- if (tabGroup.isEmpty) {
531
- tabGroup.dispose();
532
- }
553
+ this._bracketTabGroupMutation(() => {
554
+ tabGroup.removePanel(panelId);
555
+ this._panelToTabGroup.delete(panelId);
556
+ this._onDidRemovePanelFromTabGroup.fire({ tabGroup, panelId });
557
+ // Auto-destroy empty groups
558
+ if (tabGroup.isEmpty) {
559
+ tabGroup.dispose();
560
+ }
561
+ });
533
562
  }
534
563
  getTabGroups() {
535
564
  return this._tabGroups;
@@ -669,6 +698,9 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
669
698
  focusContent() {
670
699
  this.contentContainer.element.focus();
671
700
  }
701
+ focusActiveTab() {
702
+ this.tabsContainer.focusActiveTab();
703
+ }
672
704
  set renderContainer(value) {
673
705
  this.panels.forEach((panel) => {
674
706
  this.renderContainer.detatch(panel);
@@ -705,54 +737,20 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
705
737
  this.updateHeaderActions();
706
738
  }
707
739
  updateHeaderActions() {
708
- if (this.accessor.options.createRightHeaderActionComponent) {
709
- this._rightHeaderActions =
710
- this.accessor.options.createRightHeaderActionComponent(this.groupPanel);
711
- this._rightHeaderActionsDisposable.value = this._rightHeaderActions;
712
- this._rightHeaderActions.init({
713
- containerApi: this._api,
714
- api: this.groupPanel.api,
715
- group: this.groupPanel,
716
- });
717
- this.tabsContainer.setRightActionsElement(this._rightHeaderActions.element);
718
- }
719
- else {
720
- this._rightHeaderActions = undefined;
721
- this._rightHeaderActionsDisposable.dispose();
722
- this.tabsContainer.setRightActionsElement(undefined);
723
- }
724
- if (this.accessor.options.createLeftHeaderActionComponent) {
725
- this._leftHeaderActions =
726
- this.accessor.options.createLeftHeaderActionComponent(this.groupPanel);
727
- this._leftHeaderActionsDisposable.value = this._leftHeaderActions;
728
- this._leftHeaderActions.init({
729
- containerApi: this._api,
730
- api: this.groupPanel.api,
731
- group: this.groupPanel,
732
- });
733
- this.tabsContainer.setLeftActionsElement(this._leftHeaderActions.element);
734
- }
735
- else {
736
- this._leftHeaderActions = undefined;
737
- this._leftHeaderActionsDisposable.dispose();
738
- this.tabsContainer.setLeftActionsElement(undefined);
739
- }
740
- if (this.accessor.options.createPrefixHeaderActionComponent) {
741
- this._prefixHeaderActions =
742
- this.accessor.options.createPrefixHeaderActionComponent(this.groupPanel);
743
- this._prefixHeaderActionsDisposable.value =
744
- this._prefixHeaderActions;
745
- this._prefixHeaderActions.init({
746
- containerApi: this._api,
747
- api: this.groupPanel.api,
748
- group: this.groupPanel,
749
- });
750
- this.tabsContainer.setPrefixActionsElement(this._prefixHeaderActions.element);
751
- }
752
- else {
753
- this._prefixHeaderActions = undefined;
754
- this._prefixHeaderActionsDisposable.dispose();
755
- this.tabsContainer.setPrefixActionsElement(undefined);
740
+ var _a;
741
+ (_a = this.accessor.headerActionsService) === null || _a === void 0 ? void 0 : _a.refresh(this.groupPanel);
742
+ }
743
+ attachHeaderAction(slot, element) {
744
+ switch (slot) {
745
+ case 'left':
746
+ this.tabsContainer.setLeftActionsElement(element);
747
+ break;
748
+ case 'right':
749
+ this.tabsContainer.setRightActionsElement(element);
750
+ break;
751
+ case 'prefix':
752
+ this.tabsContainer.setPrefixActionsElement(element);
753
+ break;
756
754
  }
757
755
  }
758
756
  rerender(panel) {
@@ -998,12 +996,15 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
998
996
  this._onDidAddPanel.fire({ panel });
999
997
  }
1000
998
  doSetActivePanel(panel) {
999
+ var _a, _b, _c;
1001
1000
  if (this._activePanel === panel) {
1002
1001
  return;
1003
1002
  }
1004
1003
  this._activePanel = panel;
1005
1004
  if (panel) {
1006
1005
  this.tabsContainer.setActivePanel(panel);
1006
+ // Point the tabpanel's `aria-labelledby` at the now-active tab.
1007
+ this.contentContainer.setLabelledBy(this.tabsContainer.getTabId(panel.id));
1007
1008
  this.contentContainer.openPanel(panel);
1008
1009
  panel.layout(this._width, this._height);
1009
1010
  this.updateMru(panel);
@@ -1011,8 +1012,23 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
1011
1012
  this.contentContainer.refreshFocusState();
1012
1013
  this._onDidActivePanelChange.fire({
1013
1014
  panel,
1015
+ // `currentOrigin` is always present on the real component;
1016
+ // default to 'user' for minimal test accessors.
1017
+ origin: (_c = (_b = (_a = this.accessor).currentOrigin) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : 'user',
1014
1018
  });
1015
1019
  }
1020
+ this.updateAccessibleLabel();
1021
+ }
1022
+ /** Label the group region with its active panel's title (the WAI-ARIA region name). */
1023
+ updateAccessibleLabel() {
1024
+ var _a;
1025
+ const title = (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.title;
1026
+ if (title) {
1027
+ this.container.setAttribute('aria-label', title);
1028
+ }
1029
+ else {
1030
+ this.container.removeAttribute('aria-label');
1031
+ }
1016
1032
  }
1017
1033
  updateMru(panel) {
1018
1034
  if (this.mostRecentlyUsed.includes(panel)) {
@@ -1046,7 +1062,7 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
1046
1062
  }
1047
1063
  canDisplayOverlay(event, position, target) {
1048
1064
  const firedEvent = new DockviewUnhandledDragOverEvent(event, target, position, getPanelData, this.accessor.getPanel(this.id));
1049
- this._onUnhandledDragOverEvent.fire(firedEvent);
1065
+ this._onUnhandledDragOver.fire(firedEvent);
1050
1066
  return firedEvent.isAccepted;
1051
1067
  }
1052
1068
  handleDropEvent(type, event, position, index) {
@@ -7,7 +7,7 @@ import { IPanel, PanelUpdateEvent, Parameters } from '../panel/types';
7
7
  import { IDockviewPanelModel } from './dockviewPanelModel';
8
8
  import { DockviewComponent } from './dockviewComponent';
9
9
  import { DockviewPanelRenderer } from '../overlay/overlayRenderContainer';
10
- import { Contraints } from '../gridview/gridviewPanel';
10
+ import { Constraints } from '../gridview/gridviewPanel';
11
11
  export interface IDockviewPanel extends IDisposable, IPanel {
12
12
  readonly view: IDockviewPanelModel;
13
13
  readonly group: DockviewGroupPanel;
@@ -52,7 +52,7 @@ export declare class DockviewPanel extends CompositeDisposable implements IDockv
52
52
  get maximumHeight(): number | undefined;
53
53
  constructor(id: string, component: string, tabComponent: string | undefined, accessor: DockviewComponent, containerApi: DockviewApi, group: DockviewGroupPanel, view: IDockviewPanelModel, options: {
54
54
  renderer?: DockviewPanelRenderer;
55
- } & Partial<Contraints>);
55
+ } & Partial<Constraints>);
56
56
  init(params: IGroupPanelInitParameters): void;
57
57
  focus(): void;
58
58
  toJSON(): GroupviewPanelState;
@@ -0,0 +1,38 @@
1
+ import { IDisposable } from '../lifecycle';
2
+ import { DockviewGroupPanel } from './dockviewGroupPanel';
3
+ import { EdgeGroupPosition } from './dockviewShell';
4
+ /**
5
+ * EdgeGroupService is a pure registry: it tracks which positions are
6
+ * occupied and owns each edge group's per-instance cleanup disposable.
7
+ *
8
+ * The ShellManager (layout infrastructure) and the addEdgeGroup
9
+ * orchestration remain on DockviewComponent.
10
+ */
11
+ export interface IEdgeGroupServiceHost {
12
+ }
13
+ export interface IEdgeGroupService extends IDisposable {
14
+ add(position: EdgeGroupPosition, group: DockviewGroupPanel, autoCollapseDisposable: IDisposable): void;
15
+ remove(position: EdgeGroupPosition): void;
16
+ get(position: EdgeGroupPosition): DockviewGroupPanel | undefined;
17
+ has(position: EdgeGroupPosition): boolean;
18
+ hasAny(): boolean;
19
+ entries(): IterableIterator<[EdgeGroupPosition, DockviewGroupPanel]>;
20
+ includes(group: DockviewGroupPanel): boolean;
21
+ findPositionOf(group: DockviewGroupPanel): EdgeGroupPosition | undefined;
22
+ disposeAll(): void;
23
+ }
24
+ export declare class EdgeGroupService implements IEdgeGroupService {
25
+ private readonly _edgeGroups;
26
+ private readonly _edgeGroupDisposables;
27
+ add(position: EdgeGroupPosition, group: DockviewGroupPanel, autoCollapseDisposable: IDisposable): void;
28
+ remove(position: EdgeGroupPosition): void;
29
+ get(position: EdgeGroupPosition): DockviewGroupPanel | undefined;
30
+ has(position: EdgeGroupPosition): boolean;
31
+ hasAny(): boolean;
32
+ entries(): IterableIterator<[EdgeGroupPosition, DockviewGroupPanel]>;
33
+ includes(group: DockviewGroupPanel): boolean;
34
+ findPositionOf(group: DockviewGroupPanel): EdgeGroupPosition | undefined;
35
+ disposeAll(): void;
36
+ dispose(): void;
37
+ }
38
+ export declare const EdgeGroupModule: import("./modules").DockviewModule<IEdgeGroupServiceHost>;