dockview-core 4.11.0 → 4.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/cjs/api/component.api.d.ts +5 -3
  2. package/dist/cjs/api/component.api.js +2 -2
  3. package/dist/cjs/api/dockviewGroupPanelApi.d.ts +3 -1
  4. package/dist/cjs/api/dockviewGroupPanelApi.js +24 -1
  5. package/dist/cjs/dockview/components/panel/content.d.ts +7 -0
  6. package/dist/cjs/dockview/components/panel/content.js +11 -0
  7. package/dist/cjs/dockview/components/titlebar/tabs.d.ts +2 -2
  8. package/dist/cjs/dockview/components/titlebar/tabs.js +1 -1
  9. package/dist/cjs/dockview/components/titlebar/tabsContainer.d.ts +3 -3
  10. package/dist/cjs/dockview/components/titlebar/tabsContainer.js +1 -1
  11. package/dist/cjs/dockview/dockviewComponent.d.ts +10 -4
  12. package/dist/cjs/dockview/dockviewComponent.js +167 -85
  13. package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts +2 -2
  14. package/dist/cjs/dockview/dockviewGroupPanelModel.js +4 -1
  15. package/dist/cjs/dockview/dockviewPanel.d.ts +6 -4
  16. package/dist/cjs/dockview/dockviewPanel.js +12 -0
  17. package/dist/cjs/dockview/events.d.ts +4 -4
  18. package/dist/cjs/dockview/events.js +14 -14
  19. package/dist/cjs/index.d.ts +2 -1
  20. package/dist/cjs/index.js +7 -2
  21. package/dist/cjs/overlay/overlay.js +25 -14
  22. package/dist/cjs/splitview/splitview.js +2 -0
  23. package/dist/dockview-core.amd.js +172 -54
  24. package/dist/dockview-core.amd.js.map +1 -1
  25. package/dist/dockview-core.amd.min.js +2 -2
  26. package/dist/dockview-core.amd.min.js.map +1 -1
  27. package/dist/dockview-core.amd.min.noStyle.js +2 -2
  28. package/dist/dockview-core.amd.min.noStyle.js.map +1 -1
  29. package/dist/dockview-core.amd.noStyle.js +172 -54
  30. package/dist/dockview-core.amd.noStyle.js.map +1 -1
  31. package/dist/dockview-core.cjs.js +172 -54
  32. package/dist/dockview-core.cjs.js.map +1 -1
  33. package/dist/dockview-core.esm.js +172 -55
  34. package/dist/dockview-core.esm.js.map +1 -1
  35. package/dist/dockview-core.esm.min.js +2 -2
  36. package/dist/dockview-core.esm.min.js.map +1 -1
  37. package/dist/dockview-core.js +172 -54
  38. package/dist/dockview-core.js.map +1 -1
  39. package/dist/dockview-core.min.js +2 -2
  40. package/dist/dockview-core.min.js.map +1 -1
  41. package/dist/dockview-core.min.noStyle.js +2 -2
  42. package/dist/dockview-core.min.noStyle.js.map +1 -1
  43. package/dist/dockview-core.noStyle.js +172 -54
  44. package/dist/dockview-core.noStyle.js.map +1 -1
  45. package/dist/esm/api/component.api.d.ts +5 -3
  46. package/dist/esm/api/component.api.js +2 -2
  47. package/dist/esm/api/dockviewGroupPanelApi.d.ts +3 -1
  48. package/dist/esm/api/dockviewGroupPanelApi.js +13 -1
  49. package/dist/esm/dockview/components/panel/content.d.ts +7 -0
  50. package/dist/esm/dockview/components/panel/content.js +11 -0
  51. package/dist/esm/dockview/components/titlebar/tabs.d.ts +2 -2
  52. package/dist/esm/dockview/components/titlebar/tabs.js +2 -2
  53. package/dist/esm/dockview/components/titlebar/tabsContainer.d.ts +3 -3
  54. package/dist/esm/dockview/components/titlebar/tabsContainer.js +2 -2
  55. package/dist/esm/dockview/dockviewComponent.d.ts +10 -4
  56. package/dist/esm/dockview/dockviewComponent.js +99 -33
  57. package/dist/esm/dockview/dockviewGroupPanelModel.d.ts +2 -2
  58. package/dist/esm/dockview/dockviewGroupPanelModel.js +5 -2
  59. package/dist/esm/dockview/dockviewPanel.d.ts +6 -4
  60. package/dist/esm/dockview/dockviewPanel.js +12 -0
  61. package/dist/esm/dockview/events.d.ts +4 -4
  62. package/dist/esm/dockview/events.js +1 -1
  63. package/dist/esm/index.d.ts +2 -1
  64. package/dist/esm/index.js +2 -1
  65. package/dist/esm/overlay/overlay.js +26 -15
  66. package/dist/esm/splitview/splitview.js +2 -0
  67. package/package.json +1 -1
@@ -16,7 +16,7 @@ import { PaneviewDidDropEvent } from '../paneview/draggablePaneviewPanel';
16
16
  import { GroupDragEvent, TabDragEvent } from '../dockview/components/titlebar/tabsContainer';
17
17
  import { Box } from '../types';
18
18
  import { DockviewDidDropEvent, DockviewWillDropEvent } from '../dockview/dockviewGroupPanelModel';
19
- import { WillShowOverlayLocationEvent } from '../dockview/events';
19
+ import { DockviewWillShowOverlayLocationEvent } from '../dockview/events';
20
20
  import { PaneviewComponentOptions, PaneviewDndOverlayEvent } from '../paneview/options';
21
21
  import { SplitviewComponentOptions } from '../splitview/options';
22
22
  import { GridviewComponentOptions } from '../gridview/options';
@@ -403,7 +403,7 @@ export declare class DockviewApi implements CommonApi<SerializedDockview> {
403
403
  * Calling `event.preventDefault()` will prevent the overlay being shown and prevent
404
404
  * the any subsequent drop event.
405
405
  */
406
- get onWillShowOverlay(): Event<WillShowOverlayLocationEvent>;
406
+ get onWillShowOverlay(): Event<DockviewWillShowOverlayLocationEvent>;
407
407
  /**
408
408
  * Invoked before a group is dragged.
409
409
  *
@@ -481,7 +481,9 @@ export declare class DockviewApi implements CommonApi<SerializedDockview> {
481
481
  /**
482
482
  * Create a component from a serialized object.
483
483
  */
484
- fromJSON(data: SerializedDockview): void;
484
+ fromJSON(data: SerializedDockview, options?: {
485
+ reuseExistingPanels: boolean;
486
+ }): void;
485
487
  /**
486
488
  * Create a serialized object of the current component.
487
489
  */
@@ -667,8 +667,8 @@ export class DockviewApi {
667
667
  /**
668
668
  * Create a component from a serialized object.
669
669
  */
670
- fromJSON(data) {
671
- this.component.fromJSON(data);
670
+ fromJSON(data, options) {
671
+ this.component.fromJSON(data, options);
672
672
  }
673
673
  /**
674
674
  * Create a serialized object of the current component.
@@ -3,7 +3,7 @@ import { DockviewComponent } from '../dockview/dockviewComponent';
3
3
  import { DockviewGroupPanel } from '../dockview/dockviewGroupPanel';
4
4
  import { DockviewGroupChangeEvent, DockviewGroupLocation } from '../dockview/dockviewGroupPanelModel';
5
5
  import { Emitter, Event } from '../events';
6
- import { GridviewPanelApi, GridviewPanelApiImpl } from './gridviewPanelApi';
6
+ import { GridviewPanelApi, GridviewPanelApiImpl, SizeEvent } from './gridviewPanelApi';
7
7
  export interface DockviewGroupMoveParams {
8
8
  group?: DockviewGroupPanel;
9
9
  position?: Position;
@@ -36,12 +36,14 @@ export interface DockviewGroupPanelFloatingChangeEvent {
36
36
  export declare class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
37
37
  private readonly accessor;
38
38
  private _group;
39
+ private _pendingSize;
39
40
  readonly _onDidLocationChange: Emitter<DockviewGroupPanelFloatingChangeEvent>;
40
41
  readonly onDidLocationChange: Event<DockviewGroupPanelFloatingChangeEvent>;
41
42
  readonly _onDidActivePanelChange: Emitter<DockviewGroupChangeEvent>;
42
43
  readonly onDidActivePanelChange: Event<DockviewGroupChangeEvent>;
43
44
  get location(): DockviewGroupLocation;
44
45
  constructor(id: string, accessor: DockviewComponent);
46
+ setSize(event: SizeEvent): void;
45
47
  close(): void;
46
48
  getWindow(): Window;
47
49
  moveTo(options: DockviewGroupMoveParams): void;
@@ -16,7 +16,19 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
16
16
  this.onDidLocationChange = this._onDidLocationChange.event;
17
17
  this._onDidActivePanelChange = new Emitter();
18
18
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
19
- this.addDisposables(this._onDidLocationChange, this._onDidActivePanelChange);
19
+ this.addDisposables(this._onDidLocationChange, this._onDidActivePanelChange, this._onDidVisibilityChange.event((event) => {
20
+ // When becoming visible, apply any pending size change
21
+ if (event.isVisible && this._pendingSize) {
22
+ super.setSize(this._pendingSize);
23
+ this._pendingSize = undefined;
24
+ }
25
+ }));
26
+ }
27
+ setSize(event) {
28
+ // Always store the requested size
29
+ this._pendingSize = Object.assign({}, event);
30
+ // Apply the size change immediately
31
+ super.setSize(event);
20
32
  }
21
33
  close() {
22
34
  if (!this._group) {
@@ -17,6 +17,7 @@ export interface IContentContainer extends IDisposable {
17
17
  renderPanel(panel: IDockviewPanel, options: {
18
18
  asActive: boolean;
19
19
  }): void;
20
+ refreshFocusState(): void;
20
21
  }
21
22
  export declare class ContentContainer extends CompositeDisposable implements IContentContainer {
22
23
  private readonly accessor;
@@ -24,6 +25,7 @@ export declare class ContentContainer extends CompositeDisposable implements ICo
24
25
  private readonly _element;
25
26
  private panel;
26
27
  private readonly disposable;
28
+ private focusTracker;
27
29
  private readonly _onDidFocus;
28
30
  readonly onDidFocus: Event<void>;
29
31
  private readonly _onDidBlur;
@@ -40,4 +42,9 @@ export declare class ContentContainer extends CompositeDisposable implements ICo
40
42
  layout(_width: number, _height: number): void;
41
43
  closePanel(): void;
42
44
  dispose(): void;
45
+ /**
46
+ * Refresh the focus tracker state to handle cases where focus state
47
+ * gets out of sync due to programmatic panel activation
48
+ */
49
+ refreshFocusState(): void;
43
50
  }
@@ -92,6 +92,7 @@ export class ContentContainer extends CompositeDisposable {
92
92
  }
93
93
  if (doRender) {
94
94
  const focusTracker = trackFocus(container);
95
+ this.focusTracker = focusTracker;
95
96
  const disposable = new CompositeDisposable();
96
97
  disposable.addDisposables(focusTracker, focusTracker.onDidFocus(() => this._onDidFocus.fire()), focusTracker.onDidBlur(() => this._onDidBlur.fire()));
97
98
  this.disposable.value = disposable;
@@ -119,4 +120,14 @@ export class ContentContainer extends CompositeDisposable {
119
120
  this.disposable.dispose();
120
121
  super.dispose();
121
122
  }
123
+ /**
124
+ * Refresh the focus tracker state to handle cases where focus state
125
+ * gets out of sync due to programmatic panel activation
126
+ */
127
+ refreshFocusState() {
128
+ var _a;
129
+ if ((_a = this.focusTracker) === null || _a === void 0 ? void 0 : _a.refreshState) {
130
+ this.focusTracker.refreshState();
131
+ }
132
+ }
122
133
  }
@@ -2,7 +2,7 @@ import { Event } from '../../../events';
2
2
  import { CompositeDisposable } from '../../../lifecycle';
3
3
  import { DockviewComponent } from '../../dockviewComponent';
4
4
  import { DockviewGroupPanel } from '../../dockviewGroupPanel';
5
- import { WillShowOverlayLocationEvent } from '../../events';
5
+ import { DockviewWillShowOverlayLocationEvent } from '../../events';
6
6
  import { IDockviewPanel } from '../../dockviewPanel';
7
7
  import { Tab } from '../tab/tab';
8
8
  import { TabDragEvent, TabDropIndexEvent } from './tabsContainer';
@@ -20,7 +20,7 @@ export declare class Tabs extends CompositeDisposable {
20
20
  private readonly _onDrop;
21
21
  readonly onDrop: Event<TabDropIndexEvent>;
22
22
  private readonly _onWillShowOverlay;
23
- readonly onWillShowOverlay: Event<WillShowOverlayLocationEvent>;
23
+ readonly onWillShowOverlay: Event<DockviewWillShowOverlayLocationEvent>;
24
24
  private readonly _onOverflowTabsChange;
25
25
  readonly onOverflowTabsChange: Event<{
26
26
  tabs: string[];
@@ -3,7 +3,7 @@ import { isChildEntirelyVisibleWithinParent, OverflowObserver, } from '../../../
3
3
  import { addDisposableListener, Emitter } from '../../../events';
4
4
  import { CompositeDisposable, Disposable, MutableDisposable, } from '../../../lifecycle';
5
5
  import { Scrollbar } from '../../../scrollbar';
6
- import { WillShowOverlayLocationEvent } from '../../events';
6
+ import { DockviewWillShowOverlayLocationEvent } from '../../events';
7
7
  import { Tab } from '../tab/tab';
8
8
  export class Tabs extends CompositeDisposable {
9
9
  get showTabsOverflowControl() {
@@ -145,7 +145,7 @@ export class Tabs extends CompositeDisposable {
145
145
  index: this._tabs.findIndex((x) => x.value === tab),
146
146
  });
147
147
  }), tab.onWillShowOverlay((event) => {
148
- this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
148
+ this._onWillShowOverlay.fire(new DockviewWillShowOverlayLocationEvent(event, {
149
149
  kind: 'tab',
150
150
  panel: this.group.activePanel,
151
151
  api: this.accessor.api,
@@ -4,7 +4,7 @@ import { Tab } from '../tab/tab';
4
4
  import { DockviewGroupPanel } from '../../dockviewGroupPanel';
5
5
  import { IDockviewPanel } from '../../dockviewPanel';
6
6
  import { DockviewComponent } from '../../dockviewComponent';
7
- import { WillShowOverlayLocationEvent } from '../../events';
7
+ import { DockviewWillShowOverlayLocationEvent } from '../../events';
8
8
  export interface TabDropIndexEvent {
9
9
  readonly event: DragEvent;
10
10
  readonly index: number;
@@ -24,7 +24,7 @@ export interface ITabsContainer extends IDisposable {
24
24
  readonly onDrop: Event<TabDropIndexEvent>;
25
25
  readonly onTabDragStart: Event<TabDragEvent>;
26
26
  readonly onGroupDragStart: Event<GroupDragEvent>;
27
- readonly onWillShowOverlay: Event<WillShowOverlayLocationEvent>;
27
+ readonly onWillShowOverlay: Event<DockviewWillShowOverlayLocationEvent>;
28
28
  hidden: boolean;
29
29
  delete(id: string): void;
30
30
  indexOf(id: string): number;
@@ -62,7 +62,7 @@ export declare class TabsContainer extends CompositeDisposable implements ITabsC
62
62
  private readonly _onGroupDragStart;
63
63
  readonly onGroupDragStart: Event<GroupDragEvent>;
64
64
  private readonly _onWillShowOverlay;
65
- readonly onWillShowOverlay: Event<WillShowOverlayLocationEvent>;
65
+ readonly onWillShowOverlay: Event<DockviewWillShowOverlayLocationEvent>;
66
66
  get panels(): string[];
67
67
  get size(): number;
68
68
  get hidden(): boolean;
@@ -2,7 +2,7 @@ import { CompositeDisposable, Disposable, MutableDisposable, } from '../../../li
2
2
  import { addDisposableListener, Emitter } from '../../../events';
3
3
  import { VoidContainer } from './voidContainer';
4
4
  import { findRelativeZIndexParent, toggleClass } from '../../../dom';
5
- import { WillShowOverlayLocationEvent } from '../../events';
5
+ import { DockviewWillShowOverlayLocationEvent } from '../../events';
6
6
  import { getPanelData } from '../../../dnd/dataTransfer';
7
7
  import { Tabs } from './tabs';
8
8
  import { createDropdownElementHandle, } from './tabOverflowControl';
@@ -74,7 +74,7 @@ export class TabsContainer extends CompositeDisposable {
74
74
  index: this.tabs.size,
75
75
  });
76
76
  }), this.voidContainer.onWillShowOverlay((event) => {
77
- this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
77
+ this._onWillShowOverlay.fire(new DockviewWillShowOverlayLocationEvent(event, {
78
78
  kind: 'header_space',
79
79
  panel: this.group.activePanel,
80
80
  api: this.accessor.api,
@@ -8,7 +8,7 @@ import { BaseGrid, IBaseGrid } from '../gridview/baseComponentGridview';
8
8
  import { DockviewApi } from '../api/component.api';
9
9
  import { Orientation } from '../splitview/splitview';
10
10
  import { GroupOptions, GroupPanelViewState, DockviewDidDropEvent, DockviewWillDropEvent } from './dockviewGroupPanelModel';
11
- import { WillShowOverlayLocationEvent } from './events';
11
+ import { DockviewWillShowOverlayLocationEvent } from './events';
12
12
  import { DockviewGroupPanel } from './dockviewGroupPanel';
13
13
  import { Parameters } from '../panel/types';
14
14
  import { DockviewFloatingGroupPanel } from './dockviewFloatingGroupPanel';
@@ -94,6 +94,7 @@ type MoveGroupOrPanelOptions = {
94
94
  index?: number;
95
95
  };
96
96
  skipSetActive?: boolean;
97
+ keepEmptyGroups?: boolean;
97
98
  };
98
99
  export interface FloatingGroupOptions {
99
100
  x?: number;
@@ -128,7 +129,7 @@ export interface IDockviewComponent extends IBaseGrid<DockviewGroupPanel> {
128
129
  readonly orientation: Orientation;
129
130
  readonly onDidDrop: Event<DockviewDidDropEvent>;
130
131
  readonly onWillDrop: Event<DockviewWillDropEvent>;
131
- readonly onWillShowOverlay: Event<WillShowOverlayLocationEvent>;
132
+ readonly onWillShowOverlay: Event<DockviewWillShowOverlayLocationEvent>;
132
133
  readonly onDidRemovePanel: Event<IDockviewPanel>;
133
134
  readonly onDidAddPanel: Event<IDockviewPanel>;
134
135
  readonly onDidLayoutFromJSON: Event<void>;
@@ -175,6 +176,9 @@ export interface IDockviewComponent extends IBaseGrid<DockviewGroupPanel> {
175
176
  window: Window;
176
177
  }) => void;
177
178
  }): Promise<boolean>;
179
+ fromJSON(data: any, options?: {
180
+ reuseExistingPanels: boolean;
181
+ }): void;
178
182
  }
179
183
  export declare class DockviewComponent extends BaseGrid<DockviewGroupPanel> implements IDockviewComponent {
180
184
  private readonly nextGroupId;
@@ -195,7 +199,7 @@ export declare class DockviewComponent extends BaseGrid<DockviewGroupPanel> impl
195
199
  private readonly _onWillDrop;
196
200
  readonly onWillDrop: Event<DockviewWillDropEvent>;
197
201
  private readonly _onWillShowOverlay;
198
- readonly onWillShowOverlay: Event<WillShowOverlayLocationEvent>;
202
+ readonly onWillShowOverlay: Event<DockviewWillShowOverlayLocationEvent>;
199
203
  private readonly _onUnhandledDragOverEvent;
200
204
  readonly onUnhandledDragOverEvent: Event<DockviewDndOverlayEvent>;
201
205
  private readonly _onDidRemovePanel;
@@ -260,7 +264,9 @@ export declare class DockviewComponent extends BaseGrid<DockviewGroupPanel> impl
260
264
  * @returns A JSON respresentation of the layout
261
265
  */
262
266
  toJSON(): SerializedDockview;
263
- fromJSON(data: SerializedDockview): void;
267
+ fromJSON(data: SerializedDockview, options?: {
268
+ reuseExistingPanels: boolean;
269
+ }): void;
264
270
  clear(): void;
265
271
  closeAllGroups(): void;
266
272
  addPanel<T extends object = Parameters>(options: AddPanelOptions<T>): DockviewPanel;
@@ -12,7 +12,7 @@ import { BaseGrid, toTarget, } from '../gridview/baseComponentGridview';
12
12
  import { DockviewApi } from '../api/component.api';
13
13
  import { Orientation } from '../splitview/splitview';
14
14
  import { DockviewDidDropEvent, DockviewWillDropEvent, } from './dockviewGroupPanelModel';
15
- import { WillShowOverlayLocationEvent } from './events';
15
+ import { DockviewWillShowOverlayLocationEvent } from './events';
16
16
  import { DockviewGroupPanel } from './dockviewGroupPanel';
17
17
  import { DockviewPanelModel } from './dockviewPanelModel';
18
18
  import { getPanelData } from '../dnd/dataTransfer';
@@ -221,7 +221,7 @@ export class DockviewComponent extends BaseGrid {
221
221
  // option only available when no panels in primary grid
222
222
  return;
223
223
  }
224
- this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
224
+ this._onWillShowOverlay.fire(new DockviewWillShowOverlayLocationEvent(event, {
225
225
  kind: 'edge',
226
226
  panel: undefined,
227
227
  api: this._api,
@@ -635,7 +635,7 @@ export class DockviewComponent extends BaseGrid {
635
635
  : (_e = (_d = this.options.floatingGroupBounds) === null || _d === void 0 ? void 0 : _d.minimumHeightWithinViewport) !== null && _e !== void 0 ? _e : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE }));
636
636
  const el = group.element.querySelector('.dv-void-container');
637
637
  if (!el) {
638
- throw new Error('failed to find drag handle');
638
+ throw new Error('dockview: failed to find drag handle');
639
639
  }
640
640
  overlay.setupDrag(el, {
641
641
  inDragMode: typeof (options === null || options === void 0 ? void 0 : options.inDragMode) === 'boolean'
@@ -709,7 +709,7 @@ export class DockviewComponent extends BaseGrid {
709
709
  case 'right':
710
710
  return this.createGroupAtLocation([this.gridview.length], undefined, options); // insert into last position
711
711
  default:
712
- throw new Error(`unsupported position ${position}`);
712
+ throw new Error(`dockview: unsupported position ${position}`);
713
713
  }
714
714
  }
715
715
  updateOptions(options) {
@@ -855,15 +855,48 @@ export class DockviewComponent extends BaseGrid {
855
855
  }
856
856
  return result;
857
857
  }
858
- fromJSON(data) {
858
+ fromJSON(data, options) {
859
859
  var _a, _b;
860
+ const existingPanels = new Map();
861
+ let tempGroup;
862
+ if (options === null || options === void 0 ? void 0 : options.reuseExistingPanels) {
863
+ /**
864
+ * What are we doing here?
865
+ *
866
+ * 1. Create a temporary group to hold any panels that currently exist and that also exist in the new layout
867
+ * 2. Remove that temporary group from the group mapping so that it doesn't get cleared when we clear the layout
868
+ */
869
+ tempGroup = this.createGroup();
870
+ this._groups.delete(tempGroup.api.id);
871
+ const newPanels = Object.keys(data.panels);
872
+ for (const panel of this.panels) {
873
+ if (newPanels.includes(panel.api.id)) {
874
+ existingPanels.set(panel.api.id, panel);
875
+ }
876
+ }
877
+ this.movingLock(() => {
878
+ Array.from(existingPanels.values()).forEach((panel) => {
879
+ this.moveGroupOrPanel({
880
+ from: {
881
+ groupId: panel.api.group.api.id,
882
+ panelId: panel.api.id,
883
+ },
884
+ to: {
885
+ group: tempGroup,
886
+ position: 'center',
887
+ },
888
+ keepEmptyGroups: true,
889
+ });
890
+ });
891
+ });
892
+ }
860
893
  this.clear();
861
894
  if (typeof data !== 'object' || data === null) {
862
- throw new Error('serialized layout must be a non-null object');
895
+ throw new Error('dockview: serialized layout must be a non-null object');
863
896
  }
864
897
  const { grid, panels, activeGroup } = data;
865
898
  if (grid.root.type !== 'branch' || !Array.isArray(grid.root.data)) {
866
- throw new Error('root must be of type branch');
899
+ throw new Error('dockview: root must be of type branch');
867
900
  }
868
901
  try {
869
902
  // take note of the existing dimensions
@@ -872,7 +905,7 @@ export class DockviewComponent extends BaseGrid {
872
905
  const createGroupFromSerializedState = (data) => {
873
906
  const { id, locked, hideHeader, views, activeView } = data;
874
907
  if (typeof id !== 'string') {
875
- throw new Error('group id must be of type string');
908
+ throw new Error('dockview: group id must be of type string');
876
909
  }
877
910
  const group = this.createGroup({
878
911
  id,
@@ -887,17 +920,38 @@ export class DockviewComponent extends BaseGrid {
887
920
  * In running this section first we avoid firing lots of 'add' events in the event of a failure
888
921
  * due to a corruption of input data.
889
922
  */
890
- const panel = this._deserializer.fromJSON(panels[child], group);
891
- createdPanels.push(panel);
923
+ const existingPanel = existingPanels.get(child);
924
+ if (tempGroup && existingPanel) {
925
+ this.movingLock(() => {
926
+ tempGroup.model.removePanel(existingPanel);
927
+ });
928
+ createdPanels.push(existingPanel);
929
+ existingPanel.updateFromStateModel(panels[child]);
930
+ }
931
+ else {
932
+ const panel = this._deserializer.fromJSON(panels[child], group);
933
+ createdPanels.push(panel);
934
+ }
892
935
  }
893
936
  for (let i = 0; i < views.length; i++) {
894
937
  const panel = createdPanels[i];
895
938
  const isActive = typeof activeView === 'string' &&
896
939
  activeView === panel.id;
897
- group.model.openPanel(panel, {
898
- skipSetActive: !isActive,
899
- skipSetGroupActive: true,
900
- });
940
+ const hasExisting = existingPanels.has(panel.api.id);
941
+ if (hasExisting) {
942
+ this.movingLock(() => {
943
+ group.model.openPanel(panel, {
944
+ skipSetActive: !isActive,
945
+ skipSetGroupActive: true,
946
+ });
947
+ });
948
+ }
949
+ else {
950
+ group.model.openPanel(panel, {
951
+ skipSetActive: !isActive,
952
+ skipSetGroupActive: true,
953
+ });
954
+ }
901
955
  }
902
956
  if (!group.activePanel && group.panels.length > 0) {
903
957
  group.model.openPanel(group.panels[group.panels.length - 1], {
@@ -936,7 +990,9 @@ export class DockviewComponent extends BaseGrid {
936
990
  setTimeout(() => {
937
991
  this.addPopoutGroup(group, {
938
992
  position: position !== null && position !== void 0 ? position : undefined,
939
- overridePopoutGroup: gridReferenceGroup ? group : undefined,
993
+ overridePopoutGroup: gridReferenceGroup
994
+ ? group
995
+ : undefined,
940
996
  referenceGroup: gridReferenceGroup
941
997
  ? this.getPanel(gridReferenceGroup)
942
998
  : undefined,
@@ -1022,11 +1078,11 @@ export class DockviewComponent extends BaseGrid {
1022
1078
  addPanel(options) {
1023
1079
  var _a, _b;
1024
1080
  if (this.panels.find((_) => _.id === options.id)) {
1025
- throw new Error(`panel with id ${options.id} already exists`);
1081
+ throw new Error(`dockview: panel with id ${options.id} already exists`);
1026
1082
  }
1027
1083
  let referenceGroup;
1028
1084
  if (options.position && options.floating) {
1029
- throw new Error('you can only provide one of: position, floating as arguments to .addPanel(...)');
1085
+ throw new Error('dockview: you can only provide one of: position, floating as arguments to .addPanel(...)');
1030
1086
  }
1031
1087
  const initial = {
1032
1088
  width: options.initialWidth,
@@ -1040,7 +1096,7 @@ export class DockviewComponent extends BaseGrid {
1040
1096
  : options.position.referencePanel;
1041
1097
  index = options.position.index;
1042
1098
  if (!referencePanel) {
1043
- throw new Error(`referencePanel '${options.position.referencePanel}' does not exist`);
1099
+ throw new Error(`dockview: referencePanel '${options.position.referencePanel}' does not exist`);
1044
1100
  }
1045
1101
  referenceGroup = this.findGroup(referencePanel);
1046
1102
  }
@@ -1051,7 +1107,7 @@ export class DockviewComponent extends BaseGrid {
1051
1107
  : options.position.referenceGroup;
1052
1108
  index = options.position.index;
1053
1109
  if (!referenceGroup) {
1054
- throw new Error(`referenceGroup '${options.position.referenceGroup}' does not exist`);
1110
+ throw new Error(`dockview: referenceGroup '${options.position.referenceGroup}' does not exist`);
1055
1111
  }
1056
1112
  }
1057
1113
  else {
@@ -1163,7 +1219,7 @@ export class DockviewComponent extends BaseGrid {
1163
1219
  }) {
1164
1220
  const group = panel.group;
1165
1221
  if (!group) {
1166
- throw new Error(`cannot remove panel ${panel.id}. it's missing a group.`);
1222
+ throw new Error(`dockview: cannot remove panel ${panel.id}. it's missing a group.`);
1167
1223
  }
1168
1224
  group.model.removePanel(panel, {
1169
1225
  skipSetActiveGroup: options.skipSetActiveGroup,
@@ -1212,11 +1268,11 @@ export class DockviewComponent extends BaseGrid {
1212
1268
  ? this.panels.find((panel) => panel.id === options.referencePanel)
1213
1269
  : options.referencePanel;
1214
1270
  if (!referencePanel) {
1215
- throw new Error(`reference panel ${options.referencePanel} does not exist`);
1271
+ throw new Error(`dockview: reference panel ${options.referencePanel} does not exist`);
1216
1272
  }
1217
1273
  referenceGroup = this.findGroup(referencePanel);
1218
1274
  if (!referenceGroup) {
1219
- throw new Error(`reference group for reference panel ${options.referencePanel} does not exist`);
1275
+ throw new Error(`dockview: reference group for reference panel ${options.referencePanel} does not exist`);
1220
1276
  }
1221
1277
  }
1222
1278
  else if (isGroupOptionsWithGroup(options)) {
@@ -1225,7 +1281,7 @@ export class DockviewComponent extends BaseGrid {
1225
1281
  ? (_a = this._groups.get(options.referenceGroup)) === null || _a === void 0 ? void 0 : _a.value
1226
1282
  : options.referenceGroup;
1227
1283
  if (!referenceGroup) {
1228
- throw new Error(`reference group ${options.referenceGroup} does not exist`);
1284
+ throw new Error(`dockview: reference group ${options.referenceGroup} does not exist`);
1229
1285
  }
1230
1286
  }
1231
1287
  else {
@@ -1293,7 +1349,7 @@ export class DockviewComponent extends BaseGrid {
1293
1349
  }
1294
1350
  return floatingGroup.group;
1295
1351
  }
1296
- throw new Error('failed to find floating group');
1352
+ throw new Error('dockview: failed to find floating group');
1297
1353
  }
1298
1354
  if (group.api.location.type === 'popout') {
1299
1355
  const selectedGroup = this._popoutGroups.find((_) => _.popoutGroup === group);
@@ -1324,7 +1380,7 @@ export class DockviewComponent extends BaseGrid {
1324
1380
  this.updateWatermark();
1325
1381
  return selectedGroup.popoutGroup;
1326
1382
  }
1327
- throw new Error('failed to find popout group');
1383
+ throw new Error('dockview: failed to find popout group');
1328
1384
  }
1329
1385
  const re = super.doRemoveGroup(group, options);
1330
1386
  if (!(options === null || options === void 0 ? void 0 : options.skipActive)) {
@@ -1355,7 +1411,7 @@ export class DockviewComponent extends BaseGrid {
1355
1411
  ? (_a = this._groups.get(sourceGroupId)) === null || _a === void 0 ? void 0 : _a.value
1356
1412
  : undefined;
1357
1413
  if (!sourceGroup) {
1358
- throw new Error(`Failed to find group id ${sourceGroupId}`);
1414
+ throw new Error(`dockview: Failed to find group id ${sourceGroupId}`);
1359
1415
  }
1360
1416
  if (sourceItemId === undefined) {
1361
1417
  /**
@@ -1380,9 +1436,9 @@ export class DockviewComponent extends BaseGrid {
1380
1436
  skipSetActiveGroup: true,
1381
1437
  }));
1382
1438
  if (!removedPanel) {
1383
- throw new Error(`No panel with id ${sourceItemId}`);
1439
+ throw new Error(`dockview: No panel with id ${sourceItemId}`);
1384
1440
  }
1385
- if (sourceGroup.model.size === 0) {
1441
+ if (!options.keepEmptyGroups && sourceGroup.model.size === 0) {
1386
1442
  // remove the group and do not set a new group as active
1387
1443
  this.doRemoveGroup(sourceGroup, { skipActive: true });
1388
1444
  }
@@ -1392,7 +1448,8 @@ export class DockviewComponent extends BaseGrid {
1392
1448
  var _a;
1393
1449
  return destinationGroup.model.openPanel(removedPanel, {
1394
1450
  index: destinationIndex,
1395
- skipSetActive: ((_a = options.skipSetActive) !== null && _a !== void 0 ? _a : false) && !isDestinationGroupEmpty,
1451
+ skipSetActive: ((_a = options.skipSetActive) !== null && _a !== void 0 ? _a : false) &&
1452
+ !isDestinationGroupEmpty,
1396
1453
  skipSetGroupActive: true,
1397
1454
  });
1398
1455
  });
@@ -1403,6 +1460,13 @@ export class DockviewComponent extends BaseGrid {
1403
1460
  panel: removedPanel,
1404
1461
  from: sourceGroup,
1405
1462
  });
1463
+ /**
1464
+ * Update overlay positions after DOM layout completes to prevent 0×0 dimensions.
1465
+ * With defaultRenderer="always" this results in panel content not showing after move operations.
1466
+ */
1467
+ requestAnimationFrame(() => {
1468
+ this.overlayRenderContainer.updateAllPositions();
1469
+ });
1406
1470
  }
1407
1471
  else {
1408
1472
  /**
@@ -1447,7 +1511,9 @@ export class DockviewComponent extends BaseGrid {
1447
1511
  }));
1448
1512
  this.doRemoveGroup(sourceGroup, { skipActive: true });
1449
1513
  const newGroup = this.createGroupAtLocation(targetLocation);
1450
- this.movingLock(() => newGroup.model.openPanel(removedPanel));
1514
+ this.movingLock(() => newGroup.model.openPanel(removedPanel, {
1515
+ skipSetActive: true,
1516
+ }));
1451
1517
  this.doSetGroupAndPanelActive(newGroup);
1452
1518
  this._onDidMovePanel.fire({
1453
1519
  panel: this.getGroupPanel(sourceItemId),
@@ -1480,7 +1546,7 @@ export class DockviewComponent extends BaseGrid {
1480
1546
  skipSetActiveGroup: true,
1481
1547
  }));
1482
1548
  if (!removedPanel) {
1483
- throw new Error(`No panel with id ${sourceItemId}`);
1549
+ throw new Error(`dockview: No panel with id ${sourceItemId}`);
1484
1550
  }
1485
1551
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
1486
1552
  const group = this.createGroupAtLocation(dropLocation);
@@ -1535,7 +1601,7 @@ export class DockviewComponent extends BaseGrid {
1535
1601
  case 'floating': {
1536
1602
  const selectedFloatingGroup = this._floatingGroups.find((x) => x.group === from);
1537
1603
  if (!selectedFloatingGroup) {
1538
- throw new Error('failed to find floating group');
1604
+ throw new Error('dockview: failed to find floating group');
1539
1605
  }
1540
1606
  selectedFloatingGroup.dispose();
1541
1607
  break;
@@ -1543,7 +1609,7 @@ export class DockviewComponent extends BaseGrid {
1543
1609
  case 'popout': {
1544
1610
  const selectedPopoutGroup = this._popoutGroups.find((x) => x.popoutGroup === from);
1545
1611
  if (!selectedPopoutGroup) {
1546
- throw new Error('failed to find popout group');
1612
+ throw new Error('dockview: failed to find popout group');
1547
1613
  }
1548
1614
  // Remove from popout groups list to prevent automatic restoration
1549
1615
  const index = this._popoutGroups.indexOf(selectedPopoutGroup);
@@ -3,7 +3,7 @@ import { PanelTransfer } from '../dnd/dataTransfer';
3
3
  import { Position } from '../dnd/droptarget';
4
4
  import { DockviewComponent } from './dockviewComponent';
5
5
  import { DockviewEvent, Event } from '../events';
6
- import { DockviewGroupDropLocation, WillShowOverlayLocationEvent } from './events';
6
+ import { DockviewGroupDropLocation, DockviewWillShowOverlayLocationEvent } from './events';
7
7
  import { IViewSize } from '../gridview/gridview';
8
8
  import { CompositeDisposable } from '../lifecycle';
9
9
  import { IPanel, PanelInitParameters, PanelUpdateEvent, Parameters } from '../panel/types';
@@ -155,7 +155,7 @@ export declare class DockviewGroupPanelModel extends CompositeDisposable impleme
155
155
  private readonly _onWillDrop;
156
156
  readonly onWillDrop: Event<DockviewWillDropEvent>;
157
157
  private readonly _onWillShowOverlay;
158
- readonly onWillShowOverlay: Event<WillShowOverlayLocationEvent>;
158
+ readonly onWillShowOverlay: Event<DockviewWillShowOverlayLocationEvent>;
159
159
  private readonly _onTabDragStart;
160
160
  readonly onTabDragStart: Event<TabDragEvent>;
161
161
  private readonly _onGroupDragStart;
@@ -2,7 +2,7 @@ import { DockviewApi } from '../api/component.api';
2
2
  import { getPanelData } from '../dnd/dataTransfer';
3
3
  import { isAncestor, toggleClass } from '../dom';
4
4
  import { addDisposableListener, DockviewEvent, Emitter, } from '../events';
5
- import { WillShowOverlayLocationEvent } from './events';
5
+ import { DockviewWillShowOverlayLocationEvent } from './events';
6
6
  import { CompositeDisposable } from '../lifecycle';
7
7
  import { ContentContainer, } from './components/panel/content';
8
8
  import { TabsContainer, } from './components/titlebar/tabsContainer';
@@ -177,7 +177,7 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
177
177
  }), this.tabsContainer.onWillShowOverlay((event) => {
178
178
  this._onWillShowOverlay.fire(event);
179
179
  }), this.contentContainer.dropTarget.onWillShowOverlay((event) => {
180
- this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
180
+ this._onWillShowOverlay.fire(new DockviewWillShowOverlayLocationEvent(event, {
181
181
  kind: 'content',
182
182
  panel: this.activePanel,
183
183
  api: this._api,
@@ -488,8 +488,11 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
488
488
  this._activePanel = panel;
489
489
  if (panel) {
490
490
  this.tabsContainer.setActivePanel(panel);
491
+ this.contentContainer.openPanel(panel);
491
492
  panel.layout(this._width, this._height);
492
493
  this.updateMru(panel);
494
+ // Refresh focus state to handle programmatic activation without DOM focus change
495
+ this.contentContainer.refreshFocusState();
493
496
  this._onDidActivePanelChange.fire({
494
497
  panel,
495
498
  });