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
  }
@@ -19,13 +19,49 @@ exports.DockviewFloatingGroupPanel = void 0;
19
19
  var lifecycle_1 = require("../lifecycle");
20
20
  var DockviewFloatingGroupPanel = /** @class */ (function (_super) {
21
21
  __extends(DockviewFloatingGroupPanel, _super);
22
- function DockviewFloatingGroupPanel(group, overlay) {
22
+ function DockviewFloatingGroupPanel(group, overlay,
23
+ /**
24
+ * The floating window hosts its own gridview so it can hold a nested
25
+ * splitview layout of groups, not just a single group.
26
+ */
27
+ gridview) {
23
28
  var _this = _super.call(this) || this;
24
- _this.group = group;
25
29
  _this.overlay = overlay;
26
- _this.addDisposables(overlay);
30
+ _this.gridview = gridview;
31
+ _this._group = group;
32
+ _this.addDisposables(overlay, {
33
+ // The gridview owns the floating window's DOM subtree (mounted as
34
+ // the overlay's content). Disposing it tears down the splitview;
35
+ // it does NOT dispose the leaf views (groups) — their lifecycle is
36
+ // owned by the component's `_groups` map.
37
+ dispose: function () { return _this.gridview.dispose(); },
38
+ });
27
39
  return _this;
28
40
  }
41
+ Object.defineProperty(DockviewFloatingGroupPanel.prototype, "group", {
42
+ /**
43
+ * The window's representative/anchor group. A floating window can host a
44
+ * nested layout of several groups; the anchor is used for back-compat
45
+ * single-group APIs and is reassigned if it leaves the window.
46
+ */
47
+ get: function () {
48
+ return this._group;
49
+ },
50
+ enumerable: false,
51
+ configurable: true
52
+ });
53
+ /**
54
+ * Register the dedicated title bar (if any) so anchor reassignment keeps
55
+ * its drag handle pointed at a group that still lives in this window.
56
+ */
57
+ DockviewFloatingGroupPanel.prototype.setTitleBar = function (titleBar) {
58
+ this._titleBar = titleBar;
59
+ };
60
+ DockviewFloatingGroupPanel.prototype.setAnchorGroup = function (group) {
61
+ var _a;
62
+ this._group = group;
63
+ (_a = this._titleBar) === null || _a === void 0 ? void 0 : _a.setGroup(group);
64
+ };
29
65
  DockviewFloatingGroupPanel.prototype.position = function (bounds) {
30
66
  this.overlay.setBounds(bounds);
31
67
  };
@@ -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;
@@ -143,9 +143,6 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
143
143
  _this.groupPanel = groupPanel;
144
144
  _this._isGroupActive = false;
145
145
  _this._locked = false;
146
- _this._rightHeaderActionsDisposable = new lifecycle_1.MutableDisposable();
147
- _this._leftHeaderActionsDisposable = new lifecycle_1.MutableDisposable();
148
- _this._prefixHeaderActionsDisposable = new lifecycle_1.MutableDisposable();
149
146
  _this._location = { type: 'grid' };
150
147
  _this.mostRecentlyUsed = [];
151
148
  _this._overwriteRenderContainer = null;
@@ -180,8 +177,8 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
180
177
  _this.onDidRemovePanel = _this._onDidRemovePanel.event;
181
178
  _this._onDidActivePanelChange = new events_1.Emitter();
182
179
  _this.onDidActivePanelChange = _this._onDidActivePanelChange.event;
183
- _this._onUnhandledDragOverEvent = new events_1.Emitter();
184
- _this.onUnhandledDragOverEvent = _this._onUnhandledDragOverEvent.event;
180
+ _this._onUnhandledDragOver = new events_1.Emitter();
181
+ _this.onUnhandledDragOver = _this._onUnhandledDragOver.event;
185
182
  _this._tabGroups = [];
186
183
  _this._tabGroupMap = new Map();
187
184
  _this._panelToTabGroup = new Map();
@@ -200,6 +197,9 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
200
197
  _this._onDidTabGroupCollapsedChange = new events_1.Emitter();
201
198
  _this.onDidTabGroupCollapsedChange = _this._onDidTabGroupCollapsedChange.event;
202
199
  (0, dom_1.toggleClass)(_this.container, 'dv-groupview', true);
200
+ // Each group is a navigable region, labelled by its active panel
201
+ // (see `updateAccessibleLabel`, driven on activation / title change).
202
+ _this.container.setAttribute('role', 'region');
203
203
  _this._api = new component_api_1.DockviewApi(_this.accessor);
204
204
  _this.tabsContainer = new tabsContainer_1.TabsContainer(_this.accessor, _this.groupPanel);
205
205
  _this.contentContainer = new content_1.ContentContainer(_this.accessor, _this);
@@ -208,7 +208,12 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
208
208
  _this.locked = (_a = options.locked) !== null && _a !== void 0 ? _a : false;
209
209
  _this.headerPosition =
210
210
  (_b = options.headerPosition) !== null && _b !== void 0 ? _b : accessor.defaultHeaderPosition;
211
- _this.addDisposables(_this._onTabDragStart, _this._onGroupDragStart, _this._onWillShowOverlay, _this._rightHeaderActionsDisposable, _this._leftHeaderActionsDisposable, _this._prefixHeaderActionsDisposable, _this.tabsContainer.onTabDragStart(function (event) {
211
+ _this.addDisposables(
212
+ // Keep the region's accessible name in sync when the active
213
+ // panel's title changes (no-op when a non-active title changes).
214
+ _this._onDidPanelTitleChange.event(function () {
215
+ return _this.updateAccessibleLabel();
216
+ }), _this._onTabDragStart, _this._onGroupDragStart, _this._onWillShowOverlay, _this.tabsContainer.onTabDragStart(function (event) {
212
217
  _this._onTabDragStart.fire(event);
213
218
  }), _this.tabsContainer.onGroupDragStart(function (event) {
214
219
  _this._onGroupDragStart.fire(event);
@@ -285,7 +290,7 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
285
290
  group: _this.groupPanel,
286
291
  getData: dataTransfer_1.getPanelData,
287
292
  }));
288
- }), _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(function () {
293
+ }), _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(function () {
289
294
  _this._scheduleTabGroupUpdate();
290
295
  }), _this._onDidDestroyTabGroup.event(function () {
291
296
  _this._scheduleTabGroupUpdate();
@@ -321,6 +326,22 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
321
326
  enumerable: false,
322
327
  configurable: true
323
328
  });
329
+ Object.defineProperty(DockviewGroupPanelModel.prototype, "contentContainerId", {
330
+ /** DOM id of the content container (the group's tabpanel), referenced by each tab's `aria-controls`. */
331
+ get: function () {
332
+ return this.contentContainer.element.id;
333
+ },
334
+ enumerable: false,
335
+ configurable: true
336
+ });
337
+ Object.defineProperty(DockviewGroupPanelModel.prototype, "contentDropTarget", {
338
+ /** The group's content drop target — lets keyboard docking preview a drop here. */
339
+ get: function () {
340
+ return this.contentContainer.dropTarget;
341
+ },
342
+ enumerable: false,
343
+ configurable: true
344
+ });
324
345
  Object.defineProperty(DockviewGroupPanelModel.prototype, "locked", {
325
346
  get: function () {
326
347
  return this._locked;
@@ -402,11 +423,7 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
402
423
  if ((_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.layout) {
403
424
  this._activePanel.layout(this._width, this._height);
404
425
  }
405
- if (this._leftHeaderActions ||
406
- this._rightHeaderActions ||
407
- this._prefixHeaderActions) {
408
- this.updateHeaderActions();
409
- }
426
+ this.updateHeaderActions();
410
427
  },
411
428
  enumerable: false,
412
429
  configurable: true
@@ -431,14 +448,15 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
431
448
  applyZones(['top', 'bottom', 'left', 'right', 'center']);
432
449
  break;
433
450
  case 'floating':
434
- applyZones(['center']);
435
- applyZones(value
436
- ? ['center']
437
- : ['top', 'bottom', 'left', 'right', 'center']);
451
+ // Floating windows host their own nested gridview, so an edge
452
+ // drop splits the window's layout just like the main grid.
453
+ applyZones(['top', 'bottom', 'left', 'right', 'center']);
438
454
  (0, dom_1.toggleClass)(this.container, 'dv-groupview-floating', true);
439
455
  break;
440
456
  case 'popout':
441
- applyZones(['center']);
457
+ // Popout windows host their own nested gridview, so an edge
458
+ // drop splits the window's layout just like the main grid.
459
+ applyZones(['top', 'bottom', 'left', 'right', 'center']);
442
460
  (0, dom_1.toggleClass)(this.container, 'dv-groupview-popout', true);
443
461
  break;
444
462
  case 'edge':
@@ -466,7 +484,25 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
466
484
  }
467
485
  });
468
486
  };
487
+ /**
488
+ * Bracket a tab-group mutation as a layout transaction. `accessor` is
489
+ * always a full {@link DockviewComponent} in production; the optional-call
490
+ * fallback keeps partial test doubles (which omit `mutation`) working.
491
+ * When nested inside a larger operation (a drag-driven move, fromJSON
492
+ * restore) the component's depth counter folds it into the outer one.
493
+ */
494
+ DockviewGroupPanelModel.prototype._bracketTabGroupMutation = function (func) {
495
+ return this.accessor.mutation
496
+ ? this.accessor.mutation('tab-group', func)
497
+ : func();
498
+ };
469
499
  DockviewGroupPanelModel.prototype.createTabGroup = function (options) {
500
+ var _this = this;
501
+ return this._bracketTabGroupMutation(function () {
502
+ return _this._doCreateTabGroup(options);
503
+ });
504
+ };
505
+ DockviewGroupPanelModel.prototype._doCreateTabGroup = function (options) {
470
506
  var _this = this;
471
507
  var _a;
472
508
  var id = (_a = options === null || options === void 0 ? void 0 : options.id) !== null && _a !== void 0 ? _a : "tg-".concat(this.id, "-").concat(this._tabGroupIdCounter++);
@@ -497,31 +533,35 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
497
533
  return tabGroup;
498
534
  };
499
535
  DockviewGroupPanelModel.prototype.dissolveTabGroup = function (tabGroupId) {
500
- var e_2, _a;
536
+ var _this = this;
501
537
  var tabGroup = this._tabGroupMap.get(tabGroupId);
502
538
  if (!tabGroup) {
503
539
  return;
504
540
  }
505
- // Remove all panels from the group (they stay in the flat panel list)
506
- var panelIds = __spreadArray([], __read(tabGroup.panelIds), false);
507
- try {
508
- for (var panelIds_1 = __values(panelIds), panelIds_1_1 = panelIds_1.next(); !panelIds_1_1.done; panelIds_1_1 = panelIds_1.next()) {
509
- var panelId = panelIds_1_1.value;
510
- tabGroup.removePanel(panelId);
511
- this._panelToTabGroup.delete(panelId);
512
- this._onDidRemovePanelFromTabGroup.fire({ tabGroup: tabGroup, panelId: panelId });
513
- }
514
- }
515
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
516
- finally {
541
+ this._bracketTabGroupMutation(function () {
542
+ var e_2, _a;
543
+ // Remove all panels from the group (they stay in the flat panel list)
544
+ var panelIds = __spreadArray([], __read(tabGroup.panelIds), false);
517
545
  try {
518
- if (panelIds_1_1 && !panelIds_1_1.done && (_a = panelIds_1.return)) _a.call(panelIds_1);
546
+ for (var panelIds_1 = __values(panelIds), panelIds_1_1 = panelIds_1.next(); !panelIds_1_1.done; panelIds_1_1 = panelIds_1.next()) {
547
+ var panelId = panelIds_1_1.value;
548
+ tabGroup.removePanel(panelId);
549
+ _this._panelToTabGroup.delete(panelId);
550
+ _this._onDidRemovePanelFromTabGroup.fire({ tabGroup: tabGroup, panelId: panelId });
551
+ }
519
552
  }
520
- finally { if (e_2) throw e_2.error; }
521
- }
522
- tabGroup.dispose();
553
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
554
+ finally {
555
+ try {
556
+ if (panelIds_1_1 && !panelIds_1_1.done && (_a = panelIds_1.return)) _a.call(panelIds_1);
557
+ }
558
+ finally { if (e_2) throw e_2.error; }
559
+ }
560
+ tabGroup.dispose();
561
+ });
523
562
  };
524
563
  DockviewGroupPanelModel.prototype.addPanelToTabGroup = function (tabGroupId, panelId, index) {
564
+ var _this = this;
525
565
  var tabGroup = this._tabGroupMap.get(tabGroupId);
526
566
  if (!tabGroup) {
527
567
  return;
@@ -532,18 +572,20 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
532
572
  }
533
573
  // Remove from any existing group first
534
574
  var existingGroup = this.getTabGroupForPanel(panelId);
535
- if (existingGroup) {
536
- if (existingGroup.id === tabGroupId) {
537
- return; // already in this group
538
- }
539
- this.removePanelFromTabGroup(panelId);
575
+ if (existingGroup && existingGroup.id === tabGroupId) {
576
+ return; // already in this group — no mutation
540
577
  }
541
- tabGroup.addPanel(panelId, index);
542
- this._panelToTabGroup.set(panelId, tabGroup);
543
- // Enforce contiguity: move the panel in the flat _panels array
544
- // to the correct global position matching its group-local index
545
- this._enforceContiguity(tabGroup, panelId);
546
- this._onDidAddPanelToTabGroup.fire({ tabGroup: tabGroup, panelId: panelId });
578
+ this._bracketTabGroupMutation(function () {
579
+ if (existingGroup) {
580
+ _this.removePanelFromTabGroup(panelId);
581
+ }
582
+ tabGroup.addPanel(panelId, index);
583
+ _this._panelToTabGroup.set(panelId, tabGroup);
584
+ // Enforce contiguity: move the panel in the flat _panels array
585
+ // to the correct global position matching its group-local index
586
+ _this._enforceContiguity(tabGroup, panelId);
587
+ _this._onDidAddPanelToTabGroup.fire({ tabGroup: tabGroup, panelId: panelId });
588
+ });
547
589
  };
548
590
  /**
549
591
  * Move a panel to a new index within its tab group.
@@ -714,17 +756,20 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
714
756
  return this._panels.length;
715
757
  };
716
758
  DockviewGroupPanelModel.prototype.removePanelFromTabGroup = function (panelId) {
759
+ var _this = this;
717
760
  var tabGroup = this._findTabGroupForPanel(panelId);
718
761
  if (!tabGroup) {
719
762
  return;
720
763
  }
721
- tabGroup.removePanel(panelId);
722
- this._panelToTabGroup.delete(panelId);
723
- this._onDidRemovePanelFromTabGroup.fire({ tabGroup: tabGroup, panelId: panelId });
724
- // Auto-destroy empty groups
725
- if (tabGroup.isEmpty) {
726
- tabGroup.dispose();
727
- }
764
+ this._bracketTabGroupMutation(function () {
765
+ tabGroup.removePanel(panelId);
766
+ _this._panelToTabGroup.delete(panelId);
767
+ _this._onDidRemovePanelFromTabGroup.fire({ tabGroup: tabGroup, panelId: panelId });
768
+ // Auto-destroy empty groups
769
+ if (tabGroup.isEmpty) {
770
+ tabGroup.dispose();
771
+ }
772
+ });
728
773
  };
729
774
  DockviewGroupPanelModel.prototype.getTabGroups = function () {
730
775
  return this._tabGroups;
@@ -911,6 +956,9 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
911
956
  DockviewGroupPanelModel.prototype.focusContent = function () {
912
957
  this.contentContainer.element.focus();
913
958
  };
959
+ DockviewGroupPanelModel.prototype.focusActiveTab = function () {
960
+ this.tabsContainer.focusActiveTab();
961
+ };
914
962
  Object.defineProperty(DockviewGroupPanelModel.prototype, "renderContainer", {
915
963
  get: function () {
916
964
  var _a;
@@ -957,54 +1005,20 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
957
1005
  this.updateHeaderActions();
958
1006
  };
959
1007
  DockviewGroupPanelModel.prototype.updateHeaderActions = function () {
960
- if (this.accessor.options.createRightHeaderActionComponent) {
961
- this._rightHeaderActions =
962
- this.accessor.options.createRightHeaderActionComponent(this.groupPanel);
963
- this._rightHeaderActionsDisposable.value = this._rightHeaderActions;
964
- this._rightHeaderActions.init({
965
- containerApi: this._api,
966
- api: this.groupPanel.api,
967
- group: this.groupPanel,
968
- });
969
- this.tabsContainer.setRightActionsElement(this._rightHeaderActions.element);
970
- }
971
- else {
972
- this._rightHeaderActions = undefined;
973
- this._rightHeaderActionsDisposable.dispose();
974
- this.tabsContainer.setRightActionsElement(undefined);
975
- }
976
- if (this.accessor.options.createLeftHeaderActionComponent) {
977
- this._leftHeaderActions =
978
- this.accessor.options.createLeftHeaderActionComponent(this.groupPanel);
979
- this._leftHeaderActionsDisposable.value = this._leftHeaderActions;
980
- this._leftHeaderActions.init({
981
- containerApi: this._api,
982
- api: this.groupPanel.api,
983
- group: this.groupPanel,
984
- });
985
- this.tabsContainer.setLeftActionsElement(this._leftHeaderActions.element);
986
- }
987
- else {
988
- this._leftHeaderActions = undefined;
989
- this._leftHeaderActionsDisposable.dispose();
990
- this.tabsContainer.setLeftActionsElement(undefined);
991
- }
992
- if (this.accessor.options.createPrefixHeaderActionComponent) {
993
- this._prefixHeaderActions =
994
- this.accessor.options.createPrefixHeaderActionComponent(this.groupPanel);
995
- this._prefixHeaderActionsDisposable.value =
996
- this._prefixHeaderActions;
997
- this._prefixHeaderActions.init({
998
- containerApi: this._api,
999
- api: this.groupPanel.api,
1000
- group: this.groupPanel,
1001
- });
1002
- this.tabsContainer.setPrefixActionsElement(this._prefixHeaderActions.element);
1003
- }
1004
- else {
1005
- this._prefixHeaderActions = undefined;
1006
- this._prefixHeaderActionsDisposable.dispose();
1007
- this.tabsContainer.setPrefixActionsElement(undefined);
1008
+ var _a;
1009
+ (_a = this.accessor.headerActionsService) === null || _a === void 0 ? void 0 : _a.refresh(this.groupPanel);
1010
+ };
1011
+ DockviewGroupPanelModel.prototype.attachHeaderAction = function (slot, element) {
1012
+ switch (slot) {
1013
+ case 'left':
1014
+ this.tabsContainer.setLeftActionsElement(element);
1015
+ break;
1016
+ case 'right':
1017
+ this.tabsContainer.setRightActionsElement(element);
1018
+ break;
1019
+ case 'prefix':
1020
+ this.tabsContainer.setPrefixActionsElement(element);
1021
+ break;
1008
1022
  }
1009
1023
  };
1010
1024
  DockviewGroupPanelModel.prototype.rerender = function (panel) {
@@ -1272,12 +1286,15 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
1272
1286
  this._onDidAddPanel.fire({ panel: panel });
1273
1287
  };
1274
1288
  DockviewGroupPanelModel.prototype.doSetActivePanel = function (panel) {
1289
+ var _a, _b, _c;
1275
1290
  if (this._activePanel === panel) {
1276
1291
  return;
1277
1292
  }
1278
1293
  this._activePanel = panel;
1279
1294
  if (panel) {
1280
1295
  this.tabsContainer.setActivePanel(panel);
1296
+ // Point the tabpanel's `aria-labelledby` at the now-active tab.
1297
+ this.contentContainer.setLabelledBy(this.tabsContainer.getTabId(panel.id));
1281
1298
  this.contentContainer.openPanel(panel);
1282
1299
  panel.layout(this._width, this._height);
1283
1300
  this.updateMru(panel);
@@ -1285,8 +1302,23 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
1285
1302
  this.contentContainer.refreshFocusState();
1286
1303
  this._onDidActivePanelChange.fire({
1287
1304
  panel: panel,
1305
+ // `currentOrigin` is always present on the real component;
1306
+ // default to 'user' for minimal test accessors.
1307
+ origin: (_c = (_b = (_a = this.accessor).currentOrigin) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : 'user',
1288
1308
  });
1289
1309
  }
1310
+ this.updateAccessibleLabel();
1311
+ };
1312
+ /** Label the group region with its active panel's title (the WAI-ARIA region name). */
1313
+ DockviewGroupPanelModel.prototype.updateAccessibleLabel = function () {
1314
+ var _a;
1315
+ var title = (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.title;
1316
+ if (title) {
1317
+ this.container.setAttribute('aria-label', title);
1318
+ }
1319
+ else {
1320
+ this.container.removeAttribute('aria-label');
1321
+ }
1290
1322
  };
1291
1323
  DockviewGroupPanelModel.prototype.updateMru = function (panel) {
1292
1324
  if (this.mostRecentlyUsed.includes(panel)) {
@@ -1321,7 +1353,7 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
1321
1353
  };
1322
1354
  DockviewGroupPanelModel.prototype.canDisplayOverlay = function (event, position, target) {
1323
1355
  var firedEvent = new options_1.DockviewUnhandledDragOverEvent(event, target, position, dataTransfer_1.getPanelData, this.accessor.getPanel(this.id));
1324
- this._onUnhandledDragOverEvent.fire(firedEvent);
1356
+ this._onUnhandledDragOver.fire(firedEvent);
1325
1357
  return firedEvent.isAccepted;
1326
1358
  };
1327
1359
  DockviewGroupPanelModel.prototype.handleDropEvent = function (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;