Merge pull request #199 from mathuo/198-vanillajs-rendering-and-persistance

198 vanillajs rendering and persistance
This commit is contained in:
mathuo 2023-03-07 22:08:55 +08:00 committed by GitHub
commit d00da9234d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
64 changed files with 1325 additions and 1131 deletions

View File

@ -0,0 +1,42 @@
import { IDockviewPanelModel } from '../../dockview/dockviewPanelModel';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
import {
GroupPanelPartInitParameters,
GroupPanelUpdateEvent,
IContentRenderer,
ITabRenderer,
} from '../../dockview/types';
export class DockviewPanelModelMock implements IDockviewPanelModel {
constructor(
readonly contentComponent: string,
readonly content: IContentRenderer,
readonly tabComponent?: string,
readonly tab?: ITabRenderer
) {
//
}
init(params: GroupPanelPartInitParameters): void {
//
}
update(event: GroupPanelUpdateEvent): void {
//
}
layout(width: number, height: number): void {
//
}
updateParentGroup(
group: DockviewGroupPanel,
isPanelVisible: boolean
): void {
//
}
dispose(): void {
//
}
}

View File

@ -1,7 +1,7 @@
import { DockviewPanelApiImpl, TitleEvent } from '../../api/dockviewPanelApi';
import { DockviewComponent } from '../../dockview/dockviewComponent';
import { DockviewPanel, IDockviewPanel } from '../../dockview/dockviewPanel';
import { GroupPanel } from '../../groupview/groupviewPanel';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
describe('groupPanelApi', () => {
test('title', () => {
@ -10,7 +10,7 @@ describe('groupPanelApi', () => {
update: jest.fn(),
} as any;
});
const groupMock = jest.fn<GroupPanel, []>(() => {
const groupMock = jest.fn<DockviewGroupPanel, []>(() => {
return {} as any;
});
@ -37,7 +37,7 @@ describe('groupPanelApi', () => {
onDidRemovePanel: jest.fn(),
options: {},
};
const groupViewPanel = new GroupPanel(
const groupViewPanel = new DockviewGroupPanel(
<DockviewComponent>accessor,
'',
{}
@ -45,7 +45,7 @@ describe('groupPanelApi', () => {
const cut = new DockviewPanelApiImpl(
<IDockviewPanel>groupPanel,
<GroupPanel>groupViewPanel
<DockviewGroupPanel>groupViewPanel
);
let events = 0;
@ -57,7 +57,7 @@ describe('groupPanelApi', () => {
expect(events).toBe(0);
expect(cut.group).toBe(groupViewPanel);
const groupViewPanel2 = new GroupPanel(
const groupViewPanel2 = new DockviewGroupPanel(
<DockviewComponent>accessor,
'',
{}

View File

@ -1,32 +0,0 @@
import { DefaultGroupPanelView } from '../../dockview/defaultGroupPanelView';
import { IContentRenderer, ITabRenderer } from '../../groupview/types';
describe('defaultGroupPanelView', () => {
test('dispose cleanup', () => {
const contentMock = jest.fn<IContentRenderer, []>(() => {
const partial: Partial<IContentRenderer> = {
element: document.createElement('div'),
dispose: jest.fn(),
};
return partial as IContentRenderer;
});
const tabMock = jest.fn<ITabRenderer, []>(() => {
const partial: Partial<IContentRenderer> = {
element: document.createElement('div'),
dispose: jest.fn(),
};
return partial as IContentRenderer;
});
const content = new contentMock();
const tab = new tabMock();
const cut = new DefaultGroupPanelView({ content, tab });
cut.dispose();
expect(content.dispose).toHaveBeenCalled();
expect(tab.dispose).toHaveBeenCalled();
});
});

View File

@ -3,18 +3,13 @@ import {
GroupPanelPartInitParameters,
IContentRenderer,
ITabRenderer,
} from '../../groupview/types';
import { PanelUpdateEvent } from '../../panel/types';
import { Orientation } from '../../splitview/core/splitview';
import { GroupPanel } from '../../groupview/groupviewPanel';
import { CompositeDisposable } from '../../lifecycle';
import {
GroupPanelUpdateEvent,
GroupviewPanelState,
IGroupPanelInitParameters,
} from '../../groupview/types';
import { IGroupPanelView } from '../../dockview/defaultGroupPanelView';
import { DefaultTab } from '../../dockview/components/tab/defaultTab';
} from '../../dockview/types';
import { PanelUpdateEvent } from '../../panel/types';
import { Orientation } from '../../splitview/core/splitview';
import { CompositeDisposable } from '../../lifecycle';
import { Emitter } from '../../events';
import { IDockviewPanel } from '../../dockview/dockviewPanel';
import {
@ -22,6 +17,10 @@ import {
DockviewPanelApiImpl,
} from '../../api/dockviewPanelApi';
import { DefaultDockviewDeserialzier } from '../../dockview/deserializer';
import { IDockviewPanelModel } from '../../dockview/dockviewPanelModel';
import { DockviewPanelModelMock } from '../__mocks__/mockDockviewPanelMode';
import { DefaultTab } from '../../dockview/components/tab/defaultTab';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
class PanelContentPartTest implements IContentRenderer {
element: HTMLElement = document.createElement('div');
@ -35,10 +34,6 @@ class PanelContentPartTest implements IContentRenderer {
this.element.classList.add(`testpanel-${id}`);
}
updateParentGroup(group: GroupPanel, isPanelVisible: boolean): void {
//noop
}
init(parameters: GroupPanelPartInitParameters): void {
//noop
}
@ -77,10 +72,6 @@ class PanelTabPartTest implements ITabRenderer {
this.element.className = `panel-tab-part-${id}`;
}
updateParentGroup(group: GroupPanel, isPanelVisible: boolean): void {
//noop
}
init(parameters: GroupPanelPartInitParameters): void {
//noop
}
@ -93,10 +84,6 @@ class PanelTabPartTest implements ITabRenderer {
//noop
}
toJSON(): object {
return { id: this.id };
}
focus(): void {
//noop
}
@ -107,43 +94,11 @@ class PanelTabPartTest implements ITabRenderer {
}
}
class TestGroupPanelView implements IGroupPanelView {
readonly tab: ITabRenderer = new DefaultTab();
constructor(public readonly content: IContentRenderer) {
//
}
update(event: GroupPanelUpdateEvent): void {
//
}
layout(width: number, height: number): void {
//
}
init(params: GroupPanelPartInitParameters): void {
//
}
updateParentGroup(group: GroupPanel, isPanelVisible: boolean): void {
//
}
toJSON(): {} {
return {};
}
dispose(): void {
//
}
}
class TestGroupPanel implements IDockviewPanel {
private _group: GroupPanel | undefined;
private _group: DockviewGroupPanel | undefined;
readonly view: IGroupPanelView;
readonly api: DockviewPanelApi;
readonly view: IDockviewPanelModel;
constructor(
public readonly id: string,
@ -151,20 +106,23 @@ class TestGroupPanel implements IDockviewPanel {
accessor: DockviewComponent
) {
this.api = new DockviewPanelApiImpl(this, this._group!);
this._group = new GroupPanel(accessor, id, {});
this.view = new TestGroupPanelView(
new PanelContentPartTest(id, 'component')
this._group = new DockviewGroupPanel(accessor, id, {});
this.view = new DockviewPanelModelMock(
'component',
new PanelContentPartTest(id, 'component'),
'tabComponent',
new DefaultTab()
);
}
get params(): Record<string, any> {
return {};
}
get group(): GroupPanel {
get group(): DockviewGroupPanel {
return this._group!;
}
updateParentGroup(group: GroupPanel, isGroupActive: boolean): void {
updateParentGroup(group: DockviewGroupPanel, isGroupActive: boolean): void {
this._group = group;
}
@ -562,27 +520,27 @@ describe('dockviewComponent', () => {
panels: {
panel1: {
id: 'panel1',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel1',
},
panel2: {
id: 'panel2',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel2',
},
panel3: {
id: 'panel3',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel3',
},
panel4: {
id: 'panel4',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel4',
},
panel5: {
id: 'panel5',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel5',
},
},
@ -647,27 +605,27 @@ describe('dockviewComponent', () => {
panels: {
panel1: {
id: 'panel1',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel1',
},
panel2: {
id: 'panel2',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel2',
},
panel3: {
id: 'panel3',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel3',
},
panel4: {
id: 'panel4',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel4',
},
panel5: {
id: 'panel5',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel5',
},
},
@ -870,7 +828,7 @@ describe('dockviewComponent', () => {
let events: {
panel?: IDockviewPanel;
group?: GroupPanel | undefined;
group?: DockviewGroupPanel | undefined;
type: string;
}[] = [];
@ -1060,7 +1018,7 @@ describe('dockviewComponent', () => {
position: { referencePanel: 'panel2', direction: 'below' },
});
const removedGroups: GroupPanel[] = [];
const removedGroups: DockviewGroupPanel[] = [];
const removedPanels: IDockviewPanel[] = [];
const disposable = new CompositeDisposable(
@ -1098,17 +1056,14 @@ describe('dockviewComponent', () => {
view_1: {
id: 'view_1',
title: 'view_1_title',
view: {},
},
view_2: {
id: 'view_2',
title: 'view_2_title',
view: {},
},
view_3: {
id: 'view_3',
title: 'view_3_title',
view: {},
},
},
options: {},
@ -1516,9 +1471,9 @@ describe('dockviewComponent', () => {
dockview.layout(1000, 1000);
let addGroup: GroupPanel[] = [];
let removeGroup: GroupPanel[] = [];
let activeGroup: (GroupPanel | undefined)[] = [];
let addGroup: DockviewGroupPanel[] = [];
let removeGroup: DockviewGroupPanel[] = [];
let activeGroup: (DockviewGroupPanel | undefined)[] = [];
let addPanel: IDockviewPanel[] = [];
let removePanel: IDockviewPanel[] = [];
let activePanel: (IDockviewPanel | undefined)[] = [];
@ -1602,27 +1557,27 @@ describe('dockviewComponent', () => {
panels: {
panel1: {
id: 'panel1',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel1',
},
panel2: {
id: 'panel2',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel2',
},
panel3: {
id: 'panel3',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel3',
},
panel4: {
id: 'panel4',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel4',
},
panel5: {
id: 'panel5',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel5',
},
},
@ -1736,30 +1691,28 @@ describe('dockviewComponent', () => {
panels: {
panel1: {
id: 'panel1',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel1',
},
panel2: {
id: 'panel2',
view: {
content: { id: 'default' },
tab: { id: '__non__existant_tab__' },
},
contentComponent: 'default',
tabComponent: '__non__existant_tab__',
title: 'panel2',
},
panel3: {
id: 'panel3',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel3',
},
panel4: {
id: 'panel4',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel4',
},
panel5: {
id: 'panel5',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel5',
},
},
@ -1814,15 +1767,14 @@ describe('dockviewComponent', () => {
panels: {
panel1: {
id: 'panel1',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel1',
},
panel2: {
id: 'panel2',
view: {
content: { id: 'default' },
tab: { id: 'test_tab_id' },
},
contentComponent: 'default',
tabComponent: 'test_tab_id',
title: 'panel2',
},
},
@ -1863,15 +1815,13 @@ describe('dockviewComponent', () => {
panels: {
panel1: {
id: 'panel1',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel1',
},
panel2: {
id: 'panel2',
view: {
content: { id: 'default' },
tab: { id: 'test_tab_id' },
},
contentComponent: 'default',
tabComponent: 'test_tab_id',
title: 'panel2',
},
},
@ -1926,20 +1876,18 @@ describe('dockviewComponent', () => {
panels: {
panel1: {
id: 'panel1',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel1',
},
panel2: {
id: 'panel2',
view: {
content: { id: 'default' },
tab: { id: 'test_tab_id' },
},
contentComponent: 'default',
tabComponent: 'test_tab_id',
title: 'panel2',
},
panel3: {
id: 'panel3',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel3',
},
},
@ -1959,7 +1907,7 @@ describe('dockviewComponent', () => {
expect(viewQuery2.length).toBe(1);
const viewQuery3 = group.element.querySelectorAll(
'.groupview > .tabs-and-actions-container > .tabs-container > .tab > .panel-tab-part-test_tab_id'
'.groupview > .tabs-and-actions-container > .tabs-container > .tab > .panel-tab-part-panel2'
);
expect(viewQuery3.length).toBe(1);
});
@ -2009,7 +1957,7 @@ describe('dockviewComponent', () => {
panels: {
panel1: {
id: 'panel1',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel1',
},
},
@ -2061,12 +2009,12 @@ describe('dockviewComponent', () => {
panels: {
panel1: {
id: 'panel1',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel1',
},
panel2: {
id: 'panel2',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel2',
},
},
@ -2124,12 +2072,12 @@ describe('dockviewComponent', () => {
panels: {
panel1: {
id: 'panel1',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel1',
},
panel2: {
id: 'panel2',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel2',
},
},
@ -2196,18 +2144,18 @@ describe('dockviewComponent', () => {
panels: {
panel1: {
id: 'panel1',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel1',
},
panel2: {
id: 'panel2',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel2',
},
panel3: {
id: 'panel3',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel3',
},
},
@ -2256,7 +2204,7 @@ describe('dockviewComponent', () => {
panels: {
panel1: {
id: 'panel1',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel1',
},
},
@ -2325,17 +2273,17 @@ describe('dockviewComponent', () => {
panels: {
panel1: {
id: 'panel1',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel1',
},
panel2: {
id: 'panel2',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel2',
},
panel3: {
id: 'panel3',
view: { content: { id: 'default' } },
contentComponent: 'default',
title: 'panel3',
},
},

View File

@ -1,8 +1,8 @@
import { DockviewComponent } from '../../dockview/dockviewComponent';
import { DockviewApi } from '../../api/component.api';
import { IGroupPanelView } from '../../dockview/defaultGroupPanelView';
import { DockviewPanel } from '../../dockview/dockviewPanel';
import { GroupPanel } from '../../groupview/groupviewPanel';
import { IDockviewPanelModel } from '../../dockview/dockviewPanelModel';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
describe('dockviewPanel', () => {
test('update title', () => {
@ -14,13 +14,22 @@ describe('dockviewPanel', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return {} as any;
});
const groupMock = jest.fn<GroupPanel, []>(() => {
const groupMock = jest.fn<DockviewGroupPanel, []>(() => {
return {} as any;
});
const panelModelMock = jest.fn<Partial<IDockviewPanelModel>, []>(() => {
return {
update: jest.fn(),
init: jest.fn(),
};
});
const api = new dockviewApiMock();
const accessor = new accessorMock();
const group = new groupMock();
const cut = new DockviewPanel('fake-id', accessor, api, group);
const model = <IDockviewPanelModel>new panelModelMock();
const cut = new DockviewPanel('fake-id', accessor, api, group, model);
let latestTitle: string | undefined = undefined;
@ -30,7 +39,7 @@ describe('dockviewPanel', () => {
expect(cut.title).toBe('');
cut.init({ title: 'new title', params: {}, view: null });
cut.init({ title: 'new title', params: {} });
expect(latestTitle).toBe('new title');
expect(cut.title).toBe('new title');
@ -48,29 +57,29 @@ describe('dockviewPanel', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return {} as any;
});
const groupMock = jest.fn<GroupPanel, []>(() => {
const groupMock = jest.fn<DockviewGroupPanel, []>(() => {
return {} as any;
});
const panelModelMock = jest.fn<Partial<IDockviewPanelModel>, []>(() => {
return {
update: jest.fn(),
init: jest.fn(),
dispose: jest.fn(),
};
});
const api = new dockviewApiMock();
const accessor = new accessorMock();
const group = new groupMock();
const model = <IDockviewPanelModel>new panelModelMock();
const cut = new DockviewPanel('fake-id', accessor, api, group);
const cut = new DockviewPanel('fake-id', accessor, api, group, model);
const viewMock = jest.fn<IGroupPanelView, []>(() => {
return {
init: jest.fn(),
dispose: jest.fn(),
update: jest.fn(),
} as any;
});
const view = new viewMock();
cut.init({ params: {}, view, title: 'title' });
cut.init({ params: {}, title: 'title' });
cut.dispose();
expect(view.dispose).toHaveBeenCalled();
expect(model.dispose).toHaveBeenCalled();
});
test('get params', () => {
@ -80,13 +89,23 @@ describe('dockviewPanel', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return {} as any;
});
const groupMock = jest.fn<GroupPanel, []>(() => {
const groupMock = jest.fn<DockviewGroupPanel, []>(() => {
return {} as any;
});
const panelModelMock = jest.fn<Partial<IDockviewPanelModel>, []>(() => {
return {
update: jest.fn(),
init: jest.fn(),
dispose: jest.fn(),
};
});
const api = new dockviewApiMock();
const accessor = new accessorMock();
const group = new groupMock();
const cut = new DockviewPanel('fake-id', accessor, api, group);
const model = <IDockviewPanelModel>new panelModelMock();
const cut = new DockviewPanel('fake-id', accessor, api, group, model);
expect(cut.params).toEqual(undefined);
@ -102,17 +121,27 @@ describe('dockviewPanel', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return {} as any;
});
const groupMock = jest.fn<GroupPanel, []>(() => {
const groupMock = jest.fn<DockviewGroupPanel, []>(() => {
return {
api: {
setSize: jest.fn(),
},
} as any;
});
const panelModelMock = jest.fn<Partial<IDockviewPanelModel>, []>(() => {
return {
update: jest.fn(),
init: jest.fn(),
dispose: jest.fn(),
};
});
const api = new dockviewApiMock();
const accessor = new accessorMock();
const group = new groupMock();
const cut = new DockviewPanel('fake-id', accessor, api, group);
const model = <IDockviewPanelModel>new panelModelMock();
const cut = new DockviewPanel('fake-id', accessor, api, group, model);
cut.api.setSize({ height: 123, width: 456 });

View File

@ -0,0 +1,171 @@
import {
DockviewComponent,
IDockviewComponent,
} from '../../dockview/dockviewComponent';
import { DockviewPanelModel } from '../../dockview/dockviewPanelModel';
import { IContentRenderer, ITabRenderer } from '../../dockview/types';
describe('dockviewGroupPanel', () => {
test('that dispose is called on content and tab renderers when present', () => {
const contentMock = jest.fn<IContentRenderer, []>(() => {
const partial: Partial<IContentRenderer> = {
element: document.createElement('div'),
dispose: jest.fn(),
};
return partial as IContentRenderer;
});
const tabMock = jest.fn<ITabRenderer, []>(() => {
const partial: Partial<IContentRenderer> = {
element: document.createElement('div'),
dispose: jest.fn(),
};
return partial as IContentRenderer;
});
const accessorMock = jest.fn<Partial<DockviewComponent>, []>(() => {
return {
options: {
components: {
contentComponent: contentMock,
},
tabComponents: {
tabComponent: tabMock,
},
},
};
});
const cut = new DockviewPanelModel(
<IDockviewComponent>new accessorMock(),
'id',
'contentComponent',
'tabComponent'
);
cut.dispose();
expect(cut.content.dispose).toHaveBeenCalled();
expect(cut.tab.dispose).toHaveBeenCalled();
});
test('that update is called on content and tab renderers when present', () => {
const contentMock = jest.fn<IContentRenderer, []>(() => {
const partial: Partial<IContentRenderer> = {
element: document.createElement('div'),
update: jest.fn(),
};
return partial as IContentRenderer;
});
const tabMock = jest.fn<ITabRenderer, []>(() => {
const partial: Partial<IContentRenderer> = {
element: document.createElement('div'),
update: jest.fn(),
};
return partial as IContentRenderer;
});
const accessorMock = jest.fn<Partial<DockviewComponent>, []>(() => {
return {
options: {
components: {
contentComponent: contentMock,
},
tabComponents: {
tabComponent: tabMock,
},
},
};
});
const cut = new DockviewPanelModel(
<IDockviewComponent>new accessorMock(),
'id',
'contentComponent',
'tabComponent'
);
cut.update({
params: {},
});
expect(cut.content.update).toHaveBeenCalled();
expect(cut.tab.update).toHaveBeenCalled();
});
test('that events are fired', () => {
const contentMock = jest.fn<IContentRenderer, []>(() => {
const partial: Partial<IContentRenderer> = {
element: document.createElement('div'),
onGroupChange: jest.fn(),
onPanelVisibleChange: jest.fn(),
};
return partial as IContentRenderer;
});
const tabMock = jest.fn<ITabRenderer, []>(() => {
const partial: Partial<IContentRenderer> = {
element: document.createElement('div'),
onGroupChange: jest.fn(),
onPanelVisibleChange: jest.fn(),
};
return partial as IContentRenderer;
});
const accessorMock = jest.fn<Partial<DockviewComponent>, []>(() => {
return {
options: {
components: {
contentComponent: contentMock,
},
tabComponents: {
tabComponent: tabMock,
},
},
};
});
const cut = new DockviewPanelModel(
<IDockviewComponent>new accessorMock(),
'id',
'contentComponent',
'tabComponent'
);
const group1 = jest.fn() as any;
const group2 = jest.fn() as any;
cut.updateParentGroup(group1, false);
expect(cut.content.onGroupChange).toHaveBeenNthCalledWith(1, group1);
expect(cut.tab.onGroupChange).toHaveBeenNthCalledWith(1, group1);
expect(cut.content.onPanelVisibleChange).toHaveBeenNthCalledWith(
1,
false
);
expect(cut.tab.onPanelVisibleChange).toHaveBeenNthCalledWith(1, false);
expect(cut.content.onGroupChange).toHaveBeenCalledTimes(1);
expect(cut.tab.onGroupChange).toHaveBeenCalledTimes(1);
expect(cut.content.onPanelVisibleChange).toHaveBeenCalledTimes(1);
expect(cut.tab.onPanelVisibleChange).toHaveBeenCalledTimes(1);
cut.updateParentGroup(group1, true);
expect(cut.content.onPanelVisibleChange).toHaveBeenNthCalledWith(
2,
true
);
expect(cut.tab.onPanelVisibleChange).toHaveBeenNthCalledWith(2, true);
expect(cut.content.onGroupChange).toHaveBeenCalledTimes(1);
expect(cut.tab.onGroupChange).toHaveBeenCalledTimes(1);
expect(cut.content.onPanelVisibleChange).toHaveBeenCalledTimes(2);
expect(cut.tab.onPanelVisibleChange).toHaveBeenCalledTimes(2);
cut.updateParentGroup(group2, true);
expect(cut.content.onGroupChange).toHaveBeenNthCalledWith(2, group2);
expect(cut.tab.onGroupChange).toHaveBeenNthCalledWith(2, group2);
expect(cut.content.onGroupChange).toHaveBeenCalledTimes(2);
expect(cut.tab.onGroupChange).toHaveBeenCalledTimes(2);
expect(cut.content.onPanelVisibleChange).toHaveBeenCalledTimes(2);
expect(cut.tab.onPanelVisibleChange).toHaveBeenCalledTimes(2);
});
});

View File

@ -1,5 +1,5 @@
import { DockviewComponent } from '../../dockview/dockviewComponent';
import { GroupPanel } from '../../groupview/groupviewPanel';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
describe('gridviewPanel', () => {
test('get panel', () => {
@ -13,7 +13,7 @@ describe('gridviewPanel', () => {
const accessor = new accessorMock();
const cut = new GroupPanel(accessor, 'id', {});
const cut = new DockviewGroupPanel(accessor, 'id', {});
expect(cut.params).toEqual(undefined);

View File

@ -1,26 +1,28 @@
import { DockviewComponent } from '../../dockview/dockviewComponent';
import {
GroupPanelUpdateEvent,
GroupviewPanelState,
IGroupPanelInitParameters,
} from '../../groupview/types';
import {
GroupPanelPartInitParameters,
IContentRenderer,
ITabRenderer,
IWatermarkRenderer,
} from '../../groupview/types';
} from '../../dockview/types';
import { PanelUpdateEvent } from '../../panel/types';
import { GroupOptions, Groupview } from '../../groupview/groupview';
import {
DefaultGroupPanelView,
IGroupPanelView,
} from '../../dockview/defaultGroupPanelView';
import { GroupPanel } from '../../groupview/groupviewPanel';
DockviewGroupPanelModel,
GroupOptions,
} from '../../dockview/dockviewGroupPanelModel';
import { fireEvent } from '@testing-library/dom';
import { LocalSelectionTransfer, PanelTransfer } from '../../dnd/dataTransfer';
import { CompositeDisposable } from '../../lifecycle';
import { DockviewPanelApi } from '../../api/dockviewPanelApi';
import { IDockviewPanel } from '../../dockview/dockviewPanel';
import {
IDockviewPanelModel,
DockviewPanelModel,
} from '../../dockview/dockviewPanelModel';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
enum GroupChangeKind2 {
ADD_PANEL,
@ -28,6 +30,41 @@ enum GroupChangeKind2 {
PANEL_ACTIVE,
}
class TestModel implements IDockviewPanelModel {
readonly content: IContentRenderer;
readonly contentComponent: string;
readonly tab: ITabRenderer;
constructor(id: string) {
this.content = new TestHeaderPart(id);
this.contentComponent = id;
this.tab = new TestContentPart(id);
}
update(event: GroupPanelUpdateEvent): void {
//
}
layout(width: number, height: number): void {
//
}
init(params: GroupPanelPartInitParameters): void {
//
}
updateParentGroup(
group: DockviewGroupPanel,
isPanelVisible: boolean
): void {
//
}
dispose(): void {
//
}
}
class Watermark implements IWatermarkRenderer {
public readonly element = document.createElement('div');
@ -87,10 +124,6 @@ class TestContentPart implements IContentRenderer {
//void
}
updateParentGroup(group: GroupPanel, isPanelVisible: boolean) {
//noop
}
focus() {
//noop
}
@ -122,10 +155,6 @@ class TestHeaderPart implements ITabRenderer {
//void
}
updateParentGroup(group: GroupPanel, isPanelVisible: boolean) {
//noop
}
focus() {
//noop
}
@ -140,9 +169,9 @@ class TestHeaderPart implements ITabRenderer {
}
export class TestPanel implements IDockviewPanel {
private _view: IGroupPanelView | undefined;
private _group: GroupPanel | undefined;
private _group: DockviewGroupPanel | undefined;
private _params: IGroupPanelInitParameters;
readonly view: IDockviewPanelModel;
get title() {
return '';
@ -152,33 +181,24 @@ export class TestPanel implements IDockviewPanel {
return this._group!;
}
get view() {
return this._view;
}
get params(): Record<string, any> {
return {};
}
constructor(public readonly id: string, public api: DockviewPanelApi) {
this.view = new TestModel(id);
this.init({
view: new DefaultGroupPanelView({
tab: new TestHeaderPart(id),
content: new TestContentPart(id),
}),
title: `${id}`,
params: {},
});
}
init(params: IGroupPanelInitParameters) {
this._view = params.view;
this._params = params;
}
updateParentGroup(group: GroupPanel, isGroupActive: boolean) {
this._group = group;
updateParentGroup(group: DockviewGroupPanel, isGroupActive: boolean): void {
//
}
layout(width: number, height: number) {
@ -196,7 +216,6 @@ export class TestPanel implements IDockviewPanel {
toJSON(): GroupviewPanelState {
return {
id: this.id,
view: this._view?.toJSON(),
title: this._params?.title,
};
}
@ -207,7 +226,7 @@ export class TestPanel implements IDockviewPanel {
}
describe('groupview', () => {
let groupview: GroupPanel;
let groupview: DockviewGroupPanel;
let dockview: DockviewComponent;
let options: GroupOptions;
@ -232,41 +251,16 @@ describe('groupview', () => {
options = {
tabHeight: 30,
};
groupview = new GroupPanel(dockview, 'groupview-1', options);
groupview = new DockviewGroupPanel(dockview, 'groupview-1', options);
groupview.initialize();
});
test('serialized layout shows active panel', () => {
const panel1 = new TestPanel('panel1', jest.fn() as any);
const panel2 = new TestPanel('panel2', jest.fn() as any);
const panel3 = new TestPanel('panel3', jest.fn() as any);
const groupview2 = new GroupPanel(dockview, 'groupview-2', {
tabHeight: 25,
panels: [panel1, panel2, panel3],
activePanel: panel2,
});
groupview2.initialize();
expect(groupview2.model.activePanel).toBe(panel2);
expect(
groupview2.element.querySelector('.content-part-panel1')
).toBeFalsy();
expect(
groupview2.element.querySelector('.content-part-panel2')
).toBeTruthy();
expect(
groupview2.element.querySelector('.content-part-panel3')
).toBeFalsy();
});
test('panel events are captured during de-serialization', () => {
const panel1 = new TestPanel('panel1', jest.fn() as any);
const panel2 = new TestPanel('panel2', jest.fn() as any);
const panel3 = new TestPanel('panel3', jest.fn() as any);
const groupview2 = new GroupPanel(dockview, 'groupview-2', {
const groupview2 = new DockviewGroupPanel(dockview, 'groupview-2', {
tabHeight: 25,
panels: [panel1, panel2, panel3],
activePanel: panel2,
@ -520,7 +514,7 @@ describe('groupview', () => {
}
);
const cut = new Groupview(
const cut = new DockviewGroupPanelModel(
document.createElement('div'),
dockviewComponent,
'id',
@ -545,7 +539,7 @@ describe('groupview', () => {
}
);
const cut = new Groupview(
const cut = new DockviewGroupPanelModel(
document.createElement('div'),
dockviewComponent,
'id',
@ -576,7 +570,7 @@ describe('groupview', () => {
);
const groupviewContainer = document.createElement('div');
const cut = new Groupview(
const cut = new DockviewGroupPanelModel(
groupviewContainer,
dockviewComponent,
'id',
@ -623,28 +617,32 @@ describe('groupview', () => {
};
});
const accessor = new accessorMock() as DockviewComponent;
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
return {
canDisplayOverlay: jest.fn(),
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
canDisplayOverlay: jest.fn(),
};
}
);
const groupView = new groupviewMock() as Groupview;
const groupView = new groupviewMock() as DockviewGroupPanelModel;
const groupPanelMock = jest.fn<Partial<GroupPanel>, []>(() => {
return {
id: 'testgroupid',
model: groupView,
};
});
const groupPanelMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
id: 'testgroupid',
model: groupView,
};
}
);
const container = document.createElement('div');
const cut = new Groupview(
const cut = new DockviewGroupPanelModel(
container,
accessor,
'groupviewid',
{},
new groupPanelMock() as GroupPanel
new groupPanelMock() as DockviewGroupPanel
);
const element = container
@ -680,15 +678,17 @@ describe('groupview', () => {
};
});
const accessor = new accessorMock() as DockviewComponent;
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
return {
canDisplayOverlay: jest.fn(),
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
canDisplayOverlay: jest.fn(),
};
}
);
const groupView = new groupviewMock() as Groupview;
const groupView = new groupviewMock() as DockviewGroupPanelModel;
const groupPanelMock = jest.fn<Partial<GroupPanel>, []>(() => {
const groupPanelMock = jest.fn<Partial<DockviewGroupPanel>, []>(() => {
return {
id: 'testgroupid',
model: groupView,
@ -696,12 +696,12 @@ describe('groupview', () => {
});
const container = document.createElement('div');
const cut = new Groupview(
const cut = new DockviewGroupPanelModel(
container,
accessor,
'groupviewid',
{},
new groupPanelMock() as GroupPanel
new groupPanelMock() as DockviewGroupPanel
);
cut.openPanel(new TestPanel('panel1', jest.fn() as any));
@ -744,15 +744,17 @@ describe('groupview', () => {
};
});
const accessor = new accessorMock() as DockviewComponent;
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
return {
canDisplayOverlay: jest.fn(),
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
canDisplayOverlay: jest.fn(),
};
}
);
const groupView = new groupviewMock() as Groupview;
const groupView = new groupviewMock() as DockviewGroupPanelModel;
const groupPanelMock = jest.fn<Partial<GroupPanel>, []>(() => {
const groupPanelMock = jest.fn<Partial<DockviewGroupPanel>, []>(() => {
return {
id: 'testgroupid',
model: groupView,
@ -760,12 +762,12 @@ describe('groupview', () => {
});
const container = document.createElement('div');
const cut = new Groupview(
const cut = new DockviewGroupPanelModel(
container,
accessor,
'groupviewid',
{},
new groupPanelMock() as GroupPanel
new groupPanelMock() as DockviewGroupPanel
);
cut.openPanel(new TestPanel('panel1', jest.fn() as any));
@ -809,15 +811,17 @@ describe('groupview', () => {
};
});
const accessor = new accessorMock() as DockviewComponent;
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
return {
canDisplayOverlay: jest.fn(),
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
canDisplayOverlay: jest.fn(),
};
}
);
const groupView = new groupviewMock() as Groupview;
const groupView = new groupviewMock() as DockviewGroupPanelModel;
const groupPanelMock = jest.fn<Partial<GroupPanel>, []>(() => {
const groupPanelMock = jest.fn<Partial<DockviewGroupPanel>, []>(() => {
return {
id: 'testgroupid',
model: groupView,
@ -825,12 +829,12 @@ describe('groupview', () => {
});
const container = document.createElement('div');
const cut = new Groupview(
const cut = new DockviewGroupPanelModel(
container,
accessor,
'groupviewid',
{},
new groupPanelMock() as GroupPanel
new groupPanelMock() as DockviewGroupPanel
);
cut.openPanel(new TestPanel('panel1', jest.fn() as any));
@ -861,15 +865,17 @@ describe('groupview', () => {
});
test('that watermark is added', () => {
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
return {
canDisplayOverlay: jest.fn(),
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
canDisplayOverlay: jest.fn(),
};
}
);
const groupView = new groupviewMock() as Groupview;
const groupView = new groupviewMock() as DockviewGroupPanelModel;
const groupPanelMock = jest.fn<Partial<GroupPanel>, []>(() => {
const groupPanelMock = jest.fn<Partial<DockviewGroupPanel>, []>(() => {
return {
id: 'testgroupid',
model: groupView,
@ -878,12 +884,12 @@ describe('groupview', () => {
const container = document.createElement('div');
const cut = new Groupview(
const cut = new DockviewGroupPanelModel(
container,
dockview,
'groupviewid',
{},
new groupPanelMock() as GroupPanel
new groupPanelMock() as DockviewGroupPanel
);
cut.initialize();

View File

@ -1,15 +1,14 @@
import { fireEvent } from '@testing-library/dom';
import { Emitter, Event } from '../../../events';
import { ContentContainer } from '../../../groupview/panel/content';
import { ContentContainer } from '../../../dockview/components/panel/content';
import {
GroupPanelContentPartInitParameters,
IContentRenderer,
} from '../../../groupview/types';
} from '../../../dockview/types';
import { CompositeDisposable } from '../../../lifecycle';
import { PanelUpdateEvent } from '../../../panel/types';
import { IGroupPanelView } from '../../../dockview/defaultGroupPanelView';
import { GroupPanel } from '../../../groupview/groupviewPanel';
import { IDockviewPanel } from '../../../dockview/dockviewPanel';
import { IDockviewPanelModel } from '../../../dockview/dockviewPanelModel';
class TestContentRenderer
extends CompositeDisposable
@ -27,10 +26,6 @@ class TestContentRenderer
this.element = document.createElement('div');
}
updateParentGroup(group: GroupPanel, isPanelVisible: boolean): void {
//
}
init(parameters: GroupPanelContentPartInitParameters): void {
//
}
@ -77,7 +72,7 @@ describe('contentContainer', () => {
const panel = {
view: {
content: contentRenderer,
} as Partial<IGroupPanelView>,
} as Partial<IDockviewPanelModel>,
} as Partial<IDockviewPanel>;
cut.openPanel(panel as IDockviewPanel);
@ -111,7 +106,7 @@ describe('contentContainer', () => {
const panel2 = {
view: {
content: contentRenderer2,
} as Partial<IGroupPanelView>,
} as Partial<IDockviewPanelModel>,
} as Partial<IDockviewPanel>;
cut.openPanel(panel2 as IDockviewPanel);

View File

@ -1,9 +1,9 @@
import { fireEvent } from '@testing-library/dom';
import { LocalSelectionTransfer, PanelTransfer } from '../../dnd/dataTransfer';
import { DockviewComponent } from '../../dockview/dockviewComponent';
import { Groupview } from '../../groupview/groupview';
import { GroupPanel } from '../../groupview/groupviewPanel';
import { Tab } from '../../groupview/tab';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
import { DockviewGroupPanelModel } from '../../dockview/dockviewGroupPanelModel';
import { Tab } from '../../dockview/components/tab/tab';
describe('tab', () => {
test('that empty tab has inactive-tab class', () => {
@ -34,15 +34,17 @@ describe('tab', () => {
id: 'testcomponentid',
};
});
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
return {
canDisplayOverlay: jest.fn(),
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
canDisplayOverlay: jest.fn(),
};
}
);
const groupView = new groupviewMock() as Groupview;
const groupView = new groupviewMock() as DockviewGroupPanelModel;
const groupPanelMock = jest.fn<Partial<GroupPanel>, []>(() => {
const groupPanelMock = jest.fn<Partial<DockviewGroupPanel>, []>(() => {
return {
id: 'testgroupid',
model: groupView,
@ -50,7 +52,7 @@ describe('tab', () => {
});
const accessor = new accessorMock() as DockviewComponent;
const groupPanel = new groupPanelMock() as GroupPanel;
const groupPanel = new groupPanelMock() as DockviewGroupPanel;
const cut = new Tab('panelId', accessor, groupPanel);
@ -77,15 +79,17 @@ describe('tab', () => {
id: 'testcomponentid',
};
});
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
return {
canDisplayOverlay: jest.fn(),
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
canDisplayOverlay: jest.fn(),
};
}
);
const groupView = new groupviewMock() as Groupview;
const groupView = new groupviewMock() as DockviewGroupPanelModel;
const groupPanelMock = jest.fn<Partial<GroupPanel>, []>(() => {
const groupPanelMock = jest.fn<Partial<DockviewGroupPanel>, []>(() => {
return {
id: 'testgroupid',
model: groupView,
@ -93,7 +97,7 @@ describe('tab', () => {
});
const accessor = new accessorMock() as DockviewComponent;
const groupPanel = new groupPanelMock() as GroupPanel;
const groupPanel = new groupPanelMock() as DockviewGroupPanel;
const cut = new Tab('panel1', accessor, groupPanel);
@ -125,15 +129,17 @@ describe('tab', () => {
id: 'testcomponentid',
};
});
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
return {
canDisplayOverlay: jest.fn(),
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
canDisplayOverlay: jest.fn(),
};
}
);
const groupView = new groupviewMock() as Groupview;
const groupView = new groupviewMock() as DockviewGroupPanelModel;
const groupPanelMock = jest.fn<Partial<GroupPanel>, []>(() => {
const groupPanelMock = jest.fn<Partial<DockviewGroupPanel>, []>(() => {
return {
id: 'testgroupid',
model: groupView,
@ -141,7 +147,7 @@ describe('tab', () => {
});
const accessor = new accessorMock() as DockviewComponent;
const groupPanel = new groupPanelMock() as GroupPanel;
const groupPanel = new groupPanelMock() as DockviewGroupPanel;
const cut = new Tab('panel1', accessor, groupPanel);
@ -173,15 +179,17 @@ describe('tab', () => {
id: 'testcomponentid',
};
});
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
return {
canDisplayOverlay: jest.fn(),
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
canDisplayOverlay: jest.fn(),
};
}
);
const groupView = new groupviewMock() as Groupview;
const groupView = new groupviewMock() as DockviewGroupPanelModel;
const groupPanelMock = jest.fn<Partial<GroupPanel>, []>(() => {
const groupPanelMock = jest.fn<Partial<DockviewGroupPanel>, []>(() => {
return {
id: 'testgroupid',
model: groupView,
@ -189,7 +197,7 @@ describe('tab', () => {
});
const accessor = new accessorMock() as DockviewComponent;
const groupPanel = new groupPanelMock() as GroupPanel;
const groupPanel = new groupPanelMock() as DockviewGroupPanel;
const cut = new Tab('panel1', accessor, groupPanel);
@ -227,15 +235,17 @@ describe('tab', () => {
id: 'testcomponentid',
};
});
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
return {
canDisplayOverlay: jest.fn(),
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
canDisplayOverlay: jest.fn(),
};
}
);
const groupView = new groupviewMock() as Groupview;
const groupView = new groupviewMock() as DockviewGroupPanelModel;
const groupPanelMock = jest.fn<Partial<GroupPanel>, []>(() => {
const groupPanelMock = jest.fn<Partial<DockviewGroupPanel>, []>(() => {
return {
id: 'testgroupid',
model: groupView,
@ -243,7 +253,7 @@ describe('tab', () => {
});
const accessor = new accessorMock() as DockviewComponent;
const groupPanel = new groupPanelMock() as GroupPanel;
const groupPanel = new groupPanelMock() as DockviewGroupPanel;
const cut = new Tab('panel1', accessor, groupPanel);

View File

@ -1,13 +1,13 @@
import { DockviewComponent } from '../../../dockview/dockviewComponent';
import { GroupPanel } from '../../../groupview/groupviewPanel';
import { TabsContainer } from '../../../groupview/titlebar/tabsContainer';
import { TabsContainer } from '../../../dockview/components/titlebar/tabsContainer';
import { fireEvent } from '@testing-library/dom';
import { Groupview } from '../../../groupview/groupview';
import {
LocalSelectionTransfer,
PanelTransfer,
} from '../../../dnd/dataTransfer';
import { TestPanel } from '../groupview.spec';
import { TestPanel } from '../dockviewGroupPanelModel.spec';
import { DockviewGroupPanelModel } from '../../../dockview/dockviewGroupPanelModel';
import { DockviewGroupPanel } from '../../../dockview/dockviewGroupPanel';
describe('tabsContainer', () => {
test('that an external event does not render a drop target and calls through to the group mode', () => {
@ -18,22 +18,24 @@ describe('tabsContainer', () => {
options: {},
};
});
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
return {
canDisplayOverlay: jest.fn(),
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
canDisplayOverlay: jest.fn(),
};
}
);
const groupView = new groupviewMock() as Groupview;
const groupView = new groupviewMock() as DockviewGroupPanelModel;
const groupPanelMock = jest.fn<Partial<GroupPanel>, []>(() => {
const groupPanelMock = jest.fn<Partial<DockviewGroupPanel>, []>(() => {
return {
model: groupView,
};
});
const accessor = new accessorMock() as DockviewComponent;
const groupPanel = new groupPanelMock() as GroupPanel;
const groupPanel = new groupPanelMock() as DockviewGroupPanel;
const cut = new TabsContainer(accessor, groupPanel);
@ -71,15 +73,17 @@ describe('tabsContainer', () => {
options: {},
};
});
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
return {
canDisplayOverlay: jest.fn(),
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
canDisplayOverlay: jest.fn(),
};
}
);
const groupView = new groupviewMock() as Groupview;
const groupView = new groupviewMock() as DockviewGroupPanelModel;
const groupPanelMock = jest.fn<Partial<GroupPanel>, []>(() => {
const groupPanelMock = jest.fn<Partial<DockviewGroupPanel>, []>(() => {
return {
id: 'testgroupid',
model: groupView,
@ -88,7 +92,7 @@ describe('tabsContainer', () => {
});
const accessor = new accessorMock() as DockviewComponent;
const groupPanel = new groupPanelMock() as GroupPanel;
const groupPanel = new groupPanelMock() as DockviewGroupPanel;
const cut = new TabsContainer(accessor, groupPanel);
@ -137,15 +141,17 @@ describe('tabsContainer', () => {
options: {},
};
});
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
return {
canDisplayOverlay: jest.fn(),
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
canDisplayOverlay: jest.fn(),
};
}
);
const groupView = new groupviewMock() as Groupview;
const groupView = new groupviewMock() as DockviewGroupPanelModel;
const groupPanelMock = jest.fn<Partial<GroupPanel>, []>(() => {
const groupPanelMock = jest.fn<Partial<DockviewGroupPanel>, []>(() => {
return {
id: 'testgroupid',
model: groupView,
@ -154,7 +160,7 @@ describe('tabsContainer', () => {
});
const accessor = new accessorMock() as DockviewComponent;
const groupPanel = new groupPanelMock() as GroupPanel;
const groupPanel = new groupPanelMock() as DockviewGroupPanel;
const cut = new TabsContainer(accessor, groupPanel);
@ -200,15 +206,17 @@ describe('tabsContainer', () => {
options: {},
};
});
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
return {
canDisplayOverlay: jest.fn(),
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
canDisplayOverlay: jest.fn(),
};
}
);
const groupView = new groupviewMock() as Groupview;
const groupView = new groupviewMock() as DockviewGroupPanelModel;
const groupPanelMock = jest.fn<Partial<GroupPanel>, []>(() => {
const groupPanelMock = jest.fn<Partial<DockviewGroupPanel>, []>(() => {
return {
id: 'testgroupid',
model: groupView,
@ -217,7 +225,7 @@ describe('tabsContainer', () => {
});
const accessor = new accessorMock() as DockviewComponent;
const groupPanel = new groupPanelMock() as GroupPanel;
const groupPanel = new groupPanelMock() as DockviewGroupPanel;
const cut = new TabsContainer(accessor, groupPanel);
@ -263,15 +271,17 @@ describe('tabsContainer', () => {
options: {},
};
});
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
return {
canDisplayOverlay: jest.fn(),
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
canDisplayOverlay: jest.fn(),
};
}
);
const groupView = new groupviewMock() as Groupview;
const groupView = new groupviewMock() as DockviewGroupPanelModel;
const groupPanelMock = jest.fn<Partial<GroupPanel>, []>(() => {
const groupPanelMock = jest.fn<Partial<DockviewGroupPanel>, []>(() => {
return {
id: 'testgroupid',
model: groupView,
@ -279,7 +289,7 @@ describe('tabsContainer', () => {
});
const accessor = new accessorMock() as DockviewComponent;
const groupPanel = new groupPanelMock() as GroupPanel;
const groupPanel = new groupPanelMock() as DockviewGroupPanel;
const cut = new TabsContainer(accessor, groupPanel);

View File

@ -2,7 +2,7 @@ export class ActionContainer {
private _element: HTMLElement;
private _list: HTMLElement;
get element() {
get element(): HTMLElement {
return this._element;
}
@ -16,7 +16,7 @@ export class ActionContainer {
this._element.appendChild(this._list);
}
public add(element: HTMLElement) {
public add(element: HTMLElement): void {
const listItem = document.createElement('li');
listItem.className = 'action-item';
this._list.appendChild(element);

View File

@ -12,7 +12,7 @@ import { Direction } from '../gridview/baseComponentGridview';
import {
AddComponentOptions,
IGridviewComponent,
SerializedGridview,
SerializedGridviewComponent,
} from '../gridview/gridviewComponent';
import { IGridviewPanel } from '../gridview/gridviewPanel';
@ -30,7 +30,10 @@ import {
} from '../splitview/splitviewComponent';
import { IView, Orientation, Sizing } from '../splitview/core/splitview';
import { ISplitviewPanel } from '../splitview/splitviewPanel';
import { GroupPanel, IGroupviewPanel } from '../groupview/groupviewPanel';
import {
DockviewGroupPanel,
IDockviewGroupPanel,
} from '../dockview/dockviewGroupPanel';
import { Emitter, Event } from '../events';
import { IDockviewPanel } from '../dockview/dockviewPanel';
import { PaneviewDropEvent } from '../paneview/draggablePaneviewPanel';
@ -226,7 +229,7 @@ export class PaneviewApi implements CommonApi<SerializedPaneview> {
}
}
export class GridviewApi implements CommonApi<SerializedGridview> {
export class GridviewApi implements CommonApi<SerializedGridviewComponent> {
get minimumHeight(): number {
return this.component.minimumHeight;
}
@ -312,11 +315,11 @@ export class GridviewApi implements CommonApi<SerializedGridview> {
return this.component.getPanel(id);
}
fromJSON(data: SerializedGridview): void {
fromJSON(data: SerializedGridviewComponent): void {
return this.component.fromJSON(data);
}
toJSON(): SerializedGridview {
toJSON(): SerializedGridviewComponent {
return this.component.toJSON();
}
@ -362,15 +365,15 @@ export class DockviewApi implements CommonApi<SerializedDockview> {
return this.component.totalPanels;
}
get onDidActiveGroupChange(): Event<GroupPanel | undefined> {
get onDidActiveGroupChange(): Event<DockviewGroupPanel | undefined> {
return this.component.onDidActiveGroupChange;
}
get onDidAddGroup(): Event<GroupPanel> {
get onDidAddGroup(): Event<DockviewGroupPanel> {
return this.component.onDidAddGroup;
}
get onDidRemoveGroup(): Event<GroupPanel> {
get onDidRemoveGroup(): Event<DockviewGroupPanel> {
return this.component.onDidRemoveGroup;
}
@ -402,7 +405,7 @@ export class DockviewApi implements CommonApi<SerializedDockview> {
return this.component.panels;
}
get groups(): GroupPanel[] {
get groups(): DockviewGroupPanel[] {
return this.component.groups;
}
@ -410,7 +413,7 @@ export class DockviewApi implements CommonApi<SerializedDockview> {
return this.component.activePanel;
}
get activeGroup(): GroupPanel | undefined {
get activeGroup(): DockviewGroupPanel | undefined {
return this.component.activeGroup;
}
@ -440,7 +443,7 @@ export class DockviewApi implements CommonApi<SerializedDockview> {
return this.component.addPanel(options);
}
addGroup(options?: AddGroupOptions): IGroupviewPanel {
addGroup(options?: AddGroupOptions): IDockviewGroupPanel {
return this.component.addGroup(options);
}
@ -456,11 +459,11 @@ export class DockviewApi implements CommonApi<SerializedDockview> {
return this.component.closeAllGroups();
}
removeGroup(group: IGroupviewPanel): void {
this.component.removeGroup(<GroupPanel>group);
removeGroup(group: IDockviewGroupPanel): void {
this.component.removeGroup(<DockviewGroupPanel>group);
}
getGroup(id: string): GroupPanel | undefined {
getGroup(id: string): DockviewGroupPanel | undefined {
return this.component.getPanel(id);
}

View File

@ -1,6 +1,6 @@
import { Emitter, Event } from '../events';
import { GridviewPanelApiImpl, GridviewPanelApi } from './gridviewPanelApi';
import { GroupPanel } from '../groupview/groupviewPanel';
import { DockviewGroupPanel } from '../dockview/dockviewGroupPanel';
import { MutableDisposable } from '../lifecycle';
import { IDockviewPanel } from '../dockview/dockviewPanel';
@ -13,7 +13,7 @@ export interface TitleEvent {
* because it belongs to a groupview
*/
export interface DockviewPanelApi extends Omit<GridviewPanelApi, 'setVisible'> {
readonly group: GroupPanel;
readonly group: DockviewGroupPanel;
readonly isGroupActive: boolean;
readonly title: string;
readonly onDidActiveGroupChange: Event<void>;
@ -26,7 +26,7 @@ export class DockviewPanelApiImpl
extends GridviewPanelApiImpl
implements DockviewPanelApi
{
private _group: GroupPanel;
private _group: DockviewGroupPanel;
readonly _onDidTitleChange = new Emitter<TitleEvent>();
readonly onDidTitleChange = this._onDidTitleChange.event;
@ -47,7 +47,7 @@ export class DockviewPanelApiImpl
return !!this.group?.isActive;
}
set group(value: GroupPanel) {
set group(value: DockviewGroupPanel) {
const isOldGroupActive = this.isGroupActive;
this._group = value;
@ -65,11 +65,11 @@ export class DockviewPanelApiImpl
}
}
get group(): GroupPanel {
get group(): DockviewGroupPanel {
return this._group;
}
constructor(private panel: IDockviewPanel, group: GroupPanel) {
constructor(private panel: IDockviewPanel, group: DockviewGroupPanel) {
super(panel.id);
this.initialize(panel);

View File

@ -21,7 +21,7 @@ export abstract class DragHandler extends CompositeDisposable {
abstract getData(dataTransfer?: DataTransfer | null): IDisposable;
private configure() {
private configure(): void {
this.addDisposables(
this._onDragStart,
addDisposableListener(this.el, 'dragstart', (event) => {

View File

@ -3,7 +3,7 @@ import { addClasses } from '../dom';
export function addGhostImage(
dataTransfer: DataTransfer,
ghostElement: HTMLElement
) {
): void {
// class dockview provides to force ghost image to be drawn on a different layer and prevent weird rendering issues
addClasses(ghostElement, 'dv-dragged');

View File

@ -1,4 +1,4 @@
import { GroupPanel } from '../groupview/groupviewPanel';
import { DockviewGroupPanel } from '../dockview/dockviewGroupPanel';
import { IDisposable } from '../lifecycle';
import { DragHandler } from './abstractDragHandler';
import { LocalSelectionTransfer, PanelTransfer } from './dataTransfer';
@ -11,7 +11,7 @@ export class GroupDragHandler extends DragHandler {
constructor(
element: HTMLElement,
private readonly accessorId: string,
private readonly group: GroupPanel
private readonly group: DockviewGroupPanel
) {
super(element);
}

View File

@ -2,10 +2,10 @@ import {
CompositeDisposable,
IDisposable,
MutableDisposable,
} from '../../lifecycle';
import { Emitter, Event } from '../../events';
import { trackFocus } from '../../dom';
import { IDockviewPanel } from '../../dockview/dockviewPanel';
} from '../../../lifecycle';
import { Emitter, Event } from '../../../events';
import { trackFocus } from '../../../dom';
import { IDockviewPanel } from '../../dockviewPanel';
export interface IContentContainer extends IDisposable {
onDidFocus: Event<void>;
@ -74,9 +74,8 @@ export class ContentContainer
const disposable = new CompositeDisposable();
if (this.panel.view) {
const _onDidFocus: Event<void> =
this.panel.view.content.onDidFocus!;
const _onDidBlur: Event<void> = this.panel.view.content.onDidBlur!;
const _onDidFocus = this.panel.view.content.onDidFocus;
const _onDidBlur = this.panel.view.content.onDidBlur;
const { onDidFocus, onDidBlur } = trackFocus(this._element);

View File

@ -1,15 +1,10 @@
import { CompositeDisposable } from '../../../lifecycle';
import {
ITabRenderer,
GroupPanelPartInitParameters,
} from '../../../groupview/types';
import { ITabRenderer, GroupPanelPartInitParameters } from '../../types';
import { addDisposableListener } from '../../../events';
import { PanelUpdateEvent } from '../../../panel/types';
import { GroupPanel } from '../../../groupview/groupviewPanel';
import { DockviewGroupPanel } from '../../dockviewGroupPanel';
import { createCloseButton } from '../../../svg';
export const DEFAULT_TAB_IDENTIFIER = '__default__tab__';
export class DefaultTab extends CompositeDisposable implements ITabRenderer {
private _element: HTMLElement;
@ -26,10 +21,6 @@ export class DefaultTab extends CompositeDisposable implements ITabRenderer {
return this._element;
}
get id() {
return DEFAULT_TAB_IDENTIFIER;
}
constructor() {
super();
@ -69,18 +60,13 @@ export class DefaultTab extends CompositeDisposable implements ITabRenderer {
this.render();
}
public toJSON() {
return { id: this.id };
}
focus() {
//noop
}
public init(params: GroupPanelPartInitParameters) {
this.params = params;
this._content.textContent =
typeof params.title === 'string' ? params.title : this.id;
this._content.textContent = params.title;
addDisposableListener(this.action, 'click', (ev) => {
ev.preventDefault(); //
@ -88,7 +74,10 @@ export class DefaultTab extends CompositeDisposable implements ITabRenderer {
});
}
public updateParentGroup(group: GroupPanel, isPanelVisible: boolean) {
public updateParentGroup(
group: DockviewGroupPanel,
isPanelVisible: boolean
) {
const changed =
this._isPanelVisible !== isPanelVisible ||
this._isGroupActive !== group.isActive;
@ -107,10 +96,7 @@ export class DefaultTab extends CompositeDisposable implements ITabRenderer {
private render() {
if (this._content.textContent !== this.params.title) {
this._content.textContent =
typeof this.params.title === 'string'
? this.params.title
: this.id;
this._content.textContent = this.params.title;
}
}
}

View File

@ -1,17 +1,16 @@
import { addDisposableListener, Emitter, Event } from '../events';
import { CompositeDisposable, IDisposable } from '../lifecycle';
import { addDisposableListener, Emitter, Event } from '../../../events';
import { CompositeDisposable, IDisposable } from '../../../lifecycle';
import {
getPanelData,
LocalSelectionTransfer,
PanelTransfer,
} from '../dnd/dataTransfer';
import { toggleClass } from '../dom';
import { IDockviewComponent } from '../dockview/dockviewComponent';
import { ITabRenderer } from './types';
import { GroupPanel } from './groupviewPanel';
import { DroptargetEvent, Droptarget } from '../dnd/droptarget';
import { DockviewDropTargets } from './dnd';
import { DragHandler } from '../dnd/abstractDragHandler';
} from '../../../dnd/dataTransfer';
import { toggleClass } from '../../../dom';
import { IDockviewComponent } from '../../dockviewComponent';
import { DockviewDropTargets, ITabRenderer } from '../../types';
import { DockviewGroupPanel } from '../../dockviewGroupPanel';
import { DroptargetEvent, Droptarget } from '../../../dnd/droptarget';
import { DragHandler } from '../../../dnd/abstractDragHandler';
export interface ITab {
readonly panelId: string;
@ -40,7 +39,7 @@ export class Tab extends CompositeDisposable implements ITab {
constructor(
public readonly panelId: string,
private readonly accessor: IDockviewComponent,
private readonly group: GroupPanel
private readonly group: DockviewGroupPanel
) {
super();

View File

@ -2,14 +2,14 @@ import {
IDisposable,
CompositeDisposable,
IValueDisposable,
} from '../../lifecycle';
import { addDisposableListener, Emitter, Event } from '../../events';
import { ITab, Tab } from '../tab';
import { DockviewComponent } from '../../dockview/dockviewComponent';
import { GroupPanel } from '../groupviewPanel';
} from '../../../lifecycle';
import { addDisposableListener, Emitter, Event } from '../../../events';
import { ITab, Tab } from '../tab/tab';
import { DockviewComponent } from '../../dockviewComponent';
import { DockviewGroupPanel } from '../../dockviewGroupPanel';
import { VoidContainer } from './voidContainer';
import { toggleClass } from '../../dom';
import { IDockviewPanel } from '../../dockview/dockviewPanel';
import { toggleClass } from '../../../dom';
import { IDockviewPanel } from '../../dockviewPanel';
export interface TabDropIndexEvent {
event: DragEvent;
@ -135,7 +135,7 @@ export class TabsContainer
constructor(
private readonly accessor: DockviewComponent,
private readonly group: GroupPanel
private readonly group: DockviewGroupPanel
) {
super();

View File

@ -1,12 +1,12 @@
import { last } from '../../array';
import { getPanelData } from '../../dnd/dataTransfer';
import { Droptarget, DroptargetEvent } from '../../dnd/droptarget';
import { GroupDragHandler } from '../../dnd/groupDragHandler';
import { DockviewComponent } from '../../dockview/dockviewComponent';
import { addDisposableListener, Emitter, Event } from '../../events';
import { CompositeDisposable } from '../../lifecycle';
import { DockviewDropTargets } from '../dnd';
import { GroupPanel } from '../groupviewPanel';
import { last } from '../../../array';
import { getPanelData } from '../../../dnd/dataTransfer';
import { Droptarget, DroptargetEvent } from '../../../dnd/droptarget';
import { GroupDragHandler } from '../../../dnd/groupDragHandler';
import { DockviewComponent } from '../../dockviewComponent';
import { addDisposableListener, Emitter, Event } from '../../../events';
import { CompositeDisposable } from '../../../lifecycle';
import { DockviewGroupPanel } from '../../dockviewGroupPanel';
import { DockviewDropTargets } from '../../types';
export class VoidContainer extends CompositeDisposable {
private readonly _element: HTMLElement;
@ -21,7 +21,7 @@ export class VoidContainer extends CompositeDisposable {
constructor(
private readonly accessor: DockviewComponent,
private readonly group: GroupPanel
private readonly group: DockviewGroupPanel
) {
super();

View File

@ -1,12 +1,9 @@
import {
GroupPanelPartInitParameters,
IWatermarkRenderer,
} from '../../../groupview/types';
import { GroupPanelPartInitParameters, IWatermarkRenderer } from '../../types';
import { ActionContainer } from '../../../actionbar/actionsContainer';
import { addDisposableListener } from '../../../events';
import { toggleClass } from '../../../dom';
import { CompositeDisposable } from '../../../lifecycle';
import { GroupPanel } from '../../../groupview/groupviewPanel';
import { DockviewGroupPanel } from '../../dockviewGroupPanel';
import { PanelUpdateEvent } from '../../../panel/types';
import { createCloseButton } from '../../../svg';
@ -15,11 +12,11 @@ export class Watermark
implements IWatermarkRenderer
{
private _element: HTMLElement;
private group: GroupPanel | undefined;
private group: DockviewGroupPanel | undefined;
private params: GroupPanelPartInitParameters | undefined;
get id() {
return 'watermark';
get element() {
return this._element;
}
constructor() {
@ -67,10 +64,6 @@ export class Watermark
// noop
}
toJSON() {
return {};
}
layout(_width: number, _height: number) {
// noop
}
@ -87,13 +80,13 @@ export class Watermark
this.render();
}
updateParentGroup(group: GroupPanel, _visible: boolean): void {
updateParentGroup(group: DockviewGroupPanel, _visible: boolean): void {
this.group = group;
this.render();
}
get element() {
return this._element;
dispose() {
super.dispose();
}
private render() {
@ -102,8 +95,4 @@ export class Watermark
);
toggleClass(this.element, 'has-actions', isOneGroup);
}
dispose() {
super.dispose();
}
}

View File

@ -1,75 +0,0 @@
import { DefaultTab } from './components/tab/defaultTab';
import {
GroupPanelPartInitParameters,
IContentRenderer,
ITabRenderer,
GroupPanelUpdateEvent,
} from '../groupview/types';
import { GroupPanel } from '../groupview/groupviewPanel';
import { IDisposable } from '../lifecycle';
export interface IGroupPanelView extends IDisposable {
readonly content: IContentRenderer;
readonly tab?: ITabRenderer;
update(event: GroupPanelUpdateEvent): void;
layout(width: number, height: number): void;
init(params: GroupPanelPartInitParameters): void;
updateParentGroup(group: GroupPanel, isPanelVisible: boolean): void;
toJSON(): {};
}
export class DefaultGroupPanelView implements IGroupPanelView {
private readonly _content: IContentRenderer;
private readonly _tab: ITabRenderer;
get content(): IContentRenderer {
return this._content;
}
get tab(): ITabRenderer {
return this._tab;
}
constructor(renderers: { content: IContentRenderer; tab?: ITabRenderer }) {
this._content = renderers.content;
this._tab = renderers.tab ?? new DefaultTab();
}
init(params: GroupPanelPartInitParameters): void {
this.content.init({ ...params, tab: this.tab });
this.tab.init(params);
}
updateParentGroup(group: GroupPanel, isPanelVisible: boolean): void {
this._content.updateParentGroup(group, isPanelVisible);
this._tab?.updateParentGroup(group, isPanelVisible);
}
layout(width: number, height: number): void {
this.content.layout(width, height);
}
update(event: GroupPanelUpdateEvent): void {
this.content.update(event);
this.tab.update(event);
}
toJSON(): {} {
let tab =
this.tab instanceof DefaultTab ? undefined : this.tab.toJSON();
if (tab && Object.keys(tab).length === 0) {
tab = undefined;
}
return {
content: this.content.toJSON(),
tab,
};
}
dispose(): void {
this.content.dispose();
this.tab.dispose();
}
}

View File

@ -1,34 +1,53 @@
import { GroupviewPanelState, ITabRenderer } from '../groupview/types';
import { GroupPanel } from '../groupview/groupviewPanel';
import { GroupviewPanelState, ITabRenderer } from './types';
import { DockviewGroupPanel } from './dockviewGroupPanel';
import { DockviewPanel, IDockviewPanel } from './dockviewPanel';
import { DockviewComponent } from './dockviewComponent';
import { IDockviewComponent } from './dockviewComponent';
import { createComponent } from '../panel/componentFactory';
import { DefaultTab } from './components/tab/defaultTab';
import { DefaultGroupPanelView } from './defaultGroupPanelView';
import { DockviewPanelModel } from './dockviewPanelModel';
import { DockviewApi } from '../api/component.api';
export interface IPanelDeserializer {
fromJSON(panelData: GroupviewPanelState, group: GroupPanel): IDockviewPanel;
fromJSON(
panelData: GroupviewPanelState,
group: DockviewGroupPanel
): IDockviewPanel;
}
// depreciated
interface LegacyState extends GroupviewPanelState {
view?: {
tab?: { id: string };
content: { id: string };
};
}
export class DefaultDockviewDeserialzier implements IPanelDeserializer {
constructor(private readonly layout: DockviewComponent) {}
constructor(private readonly layout: IDockviewComponent) {}
public fromJSON(
panelData: GroupviewPanelState,
group: GroupPanel
group: DockviewGroupPanel
): IDockviewPanel {
const panelId = panelData.id;
const params = panelData.params;
const title = panelData.title;
const viewData = panelData.view;
const viewData = (panelData as LegacyState).view!;
const contentComponent = viewData
? viewData.content.id
: panelData.contentComponent || 'unknown';
const tabComponent = viewData
? viewData.tab?.id
: panelData.tabComponent;
let tab: ITabRenderer;
if (viewData.tab?.id) {
if (tabComponent) {
tab = createComponent(
viewData.tab.id,
viewData.tab.id,
panelId,
tabComponent,
this.layout.options.tabComponents,
this.layout.options.frameworkTabComponents,
this.layout.options.frameworkComponentFactory?.tab,
@ -36,7 +55,7 @@ export class DefaultDockviewDeserialzier implements IPanelDeserializer {
);
} else if (this.layout.options.defaultTabComponent) {
tab = createComponent(
this.layout.options.defaultTabComponent,
panelId,
this.layout.options.defaultTabComponent,
this.layout.options.tabComponents,
this.layout.options.frameworkTabComponents,
@ -47,27 +66,23 @@ export class DefaultDockviewDeserialzier implements IPanelDeserializer {
tab = new DefaultTab();
}
const view = new DefaultGroupPanelView({
content: createComponent(
viewData.content.id,
viewData.content.id,
this.layout.options.components,
this.layout.options.frameworkComponents,
this.layout.options.frameworkComponentFactory?.content
),
tab,
});
const view = new DockviewPanelModel(
this.layout,
panelId,
contentComponent,
tabComponent
);
const panel = new DockviewPanel(
panelId,
this.layout,
new DockviewApi(this.layout),
group
group,
view
);
panel.init({
view,
title,
title: title || panelId,
params: params || {},
});

View File

@ -11,11 +11,10 @@ import { CompositeDisposable } from '../lifecycle';
import { Event, Emitter } from '../events';
import { Watermark } from './components/watermark/watermark';
import {
IContentRenderer,
ITabRenderer,
IWatermarkRenderer,
GroupviewPanelState,
} from '../groupview/types';
DockviewDropTargets,
} from './types';
import { sequentialNumberGenerator } from '../math';
import { IPanelDeserializer } from './deserializer';
import { createComponent } from '../panel/componentFactory';
@ -37,16 +36,14 @@ import {
} from '../gridview/baseComponentGridview';
import { DockviewApi } from '../api/component.api';
import { Orientation, Sizing } from '../splitview/core/splitview';
import { DefaultTab } from './components/tab/defaultTab';
import {
GroupOptions,
GroupPanelViewState,
GroupviewDropEvent,
} from '../groupview/groupview';
import { GroupPanel, IGroupviewPanel } from '../groupview/groupviewPanel';
import { DefaultGroupPanelView } from './defaultGroupPanelView';
} from './dockviewGroupPanelModel';
import { DockviewGroupPanel, IDockviewGroupPanel } from './dockviewGroupPanel';
import { DockviewPanelModel } from './dockviewPanelModel';
import { getPanelData } from '../dnd/dataTransfer';
import { DockviewDropTargets } from '../groupview/dnd';
export interface PanelReference {
update: (event: { params: { [key: string]: any } }) => void;
@ -80,10 +77,10 @@ export type DockviewComponentUpdateOptions = Pick<
export interface DockviewDropEvent extends GroupviewDropEvent {
api: DockviewApi;
group: GroupPanel | null;
group: DockviewGroupPanel | null;
}
export interface IDockviewComponent extends IBaseGrid<GroupPanel> {
export interface IDockviewComponent extends IBaseGrid<DockviewGroupPanel> {
readonly activePanel: IDockviewPanel | undefined;
readonly totalPanels: number;
readonly panels: IDockviewPanel[];
@ -93,21 +90,21 @@ export interface IDockviewComponent extends IBaseGrid<GroupPanel> {
deserializer: IPanelDeserializer | undefined;
updateOptions(options: DockviewComponentUpdateOptions): void;
moveGroupOrPanel(
referenceGroup: GroupPanel,
referenceGroup: DockviewGroupPanel,
groupId: string,
itemId: string,
target: Position,
index?: number
): void;
doSetGroupActive: (group: GroupPanel, skipFocus?: boolean) => void;
removeGroup: (group: GroupPanel) => void;
doSetGroupActive: (group: DockviewGroupPanel, skipFocus?: boolean) => void;
removeGroup: (group: DockviewGroupPanel) => void;
options: DockviewComponentOptions;
addPanel(options: AddPanelOptions): IDockviewPanel;
removePanel(panel: IDockviewPanel): void;
getGroupPanel: (id: string) => IDockviewPanel | undefined;
createWatermarkComponent(): IWatermarkRenderer;
// lifecycle
addGroup(options?: AddGroupOptions): IGroupviewPanel;
addGroup(options?: AddGroupOptions): IDockviewGroupPanel;
closeAllGroups(): void;
// events
moveToNext(options?: MovementOptions): void;
@ -124,7 +121,7 @@ export interface IDockviewComponent extends IBaseGrid<GroupPanel> {
}
export class DockviewComponent
extends BaseGrid<GroupPanel>
extends BaseGrid<DockviewGroupPanel>
implements IDockviewComponent
{
private readonly nextGroupId = sequentialNumberGenerator();
@ -301,7 +298,7 @@ export class DockviewComponent
this.updateWatermark();
}
private orthogonalize(position: Position): GroupPanel {
private orthogonalize(position: Position): DockviewGroupPanel {
switch (position) {
case 'top':
case 'bottom':
@ -381,7 +378,7 @@ export class DockviewComponent
}
const location = getGridLocation(options.group.element);
const next = <GroupPanel>this.gridview.next(location)?.view;
const next = <DockviewGroupPanel>this.gridview.next(location)?.view;
this.doSetGroupActive(next);
}
@ -403,7 +400,7 @@ export class DockviewComponent
const location = getGridLocation(options.group.element);
const next = this.gridview.previous(location)?.view;
if (next) {
this.doSetGroupActive(next as GroupPanel);
this.doSetGroupActive(next as DockviewGroupPanel);
}
}
@ -532,7 +529,7 @@ export class DockviewComponent
throw new Error(`panel with id ${options.id} already exists`);
}
let referenceGroup: GroupPanel | undefined;
let referenceGroup: DockviewGroupPanel | undefined;
if (options.position) {
if (isPanelOptionsWithPanel(options.position)) {
@ -660,16 +657,16 @@ export class DockviewComponent
}
} else if (this.watermark) {
this.watermark.element.parentElement!.remove();
this.watermark.dispose();
this.watermark.dispose?.();
this.watermark = null;
}
}
addGroup(options?: AddGroupOptions): GroupPanel {
addGroup(options?: AddGroupOptions): DockviewGroupPanel {
const group = this.createGroup();
if (options) {
let referenceGroup: GroupPanel | undefined;
let referenceGroup: DockviewGroupPanel | undefined;
if (isGroupOptionsWithPanel(options)) {
const referencePanel =
@ -726,7 +723,7 @@ export class DockviewComponent
}
}
removeGroup(group: GroupPanel, skipActive = false): void {
removeGroup(group: DockviewGroupPanel, skipActive = false): void {
const panels = [...group.panels]; // reassign since group panels will mutate
for (const panel of panels) {
@ -740,7 +737,7 @@ export class DockviewComponent
}
moveGroupOrPanel(
referenceGroup: GroupPanel,
referenceGroup: DockviewGroupPanel,
groupId: string,
itemId: string | undefined,
target: Position,
@ -831,8 +828,8 @@ export class DockviewComponent
}
private moveGroup(
sourceGroup: GroupPanel,
referenceGroup: GroupPanel,
sourceGroup: DockviewGroupPanel,
referenceGroup: DockviewGroupPanel,
target: Position
): void {
if (sourceGroup) {
@ -872,7 +869,10 @@ export class DockviewComponent
}
}
doSetGroupActive(group: GroupPanel | undefined, skipFocus?: boolean): void {
doSetGroupActive(
group: DockviewGroupPanel | undefined,
skipFocus?: boolean
): void {
const isGroupAlreadyFocused = this._activeGroup === group;
super.doSetGroupActive(group, skipFocus);
@ -881,7 +881,7 @@ export class DockviewComponent
}
}
createGroup(options?: GroupOptions): GroupPanel {
createGroup(options?: GroupOptions): DockviewGroupPanel {
if (!options) {
options = { tabHeight: this.tabHeight };
}
@ -905,7 +905,7 @@ export class DockviewComponent
}
}
const view = new GroupPanel(this, id, options);
const view = new DockviewGroupPanel(this, id, options);
view.init({ params: {}, accessor: <any>null }); // required to initialized .part and allow for correct disposal of group
if (!this._groups.has(view.id)) {
@ -948,19 +948,27 @@ export class DockviewComponent
private createPanel(
options: AddPanelOptions,
group: GroupPanel
group: DockviewGroupPanel
): IDockviewPanel {
const view = new DefaultGroupPanelView({
content: this.createContentComponent(options.id, options.component),
tab: this.createTabComponent(
options.id,
options.tabComponent || this.options.defaultTabComponent
),
});
const contentComponent = options.component;
const tabComponent =
options.tabComponent || this.options.defaultTabComponent;
const panel = new DockviewPanel(options.id, this, this._api, group);
const view = new DockviewPanelModel(
this,
options.id,
contentComponent,
tabComponent
);
const panel = new DockviewPanel(
options.id,
this,
this._api,
group,
view
);
panel.init({
view,
title: options.title || options.id,
params: options?.params || {},
});
@ -968,40 +976,15 @@ export class DockviewComponent
return panel;
}
private createContentComponent(
id: string,
componentName: string
): IContentRenderer {
return createComponent(
id,
componentName,
this.options.components || {},
this.options.frameworkComponents,
this.options.frameworkComponentFactory?.content
);
}
private createTabComponent(
id: string,
componentName?: string
): ITabRenderer {
return createComponent(
id,
componentName,
this.options.tabComponents || {},
this.options.frameworkTabComponents,
this.options.frameworkComponentFactory?.tab,
() => new DefaultTab()
);
}
private createGroupAtLocation(location: number[] = [0]): GroupPanel {
private createGroupAtLocation(
location: number[] = [0]
): DockviewGroupPanel {
const group = this.createGroup();
this.doAddGroup(group, location);
return group;
}
private findGroup(panel: IDockviewPanel): GroupPanel | undefined {
private findGroup(panel: IDockviewPanel): DockviewGroupPanel | undefined {
return Array.from(this._groups.values()).find((group) =>
group.value.model.containsPanel(panel)
)?.value;

View File

@ -1,29 +1,31 @@
import { IFrameworkPart } from '../panel/types';
import { DockviewComponent } from '../dockview/dockviewComponent';
import { GridviewPanelApi } from '../api/gridviewPanelApi';
import {
GridviewPanelApi,
GridviewPanelApiImpl,
} from '../api/gridviewPanelApi';
import { Groupview, GroupOptions, IHeader } from './groupview';
DockviewGroupPanelModel,
GroupOptions,
IHeader,
} from './dockviewGroupPanelModel';
import { GridviewPanel, IGridviewPanel } from '../gridview/gridviewPanel';
import { IDockviewPanel } from '../dockview/dockviewPanel';
export interface IGroupviewPanel extends IGridviewPanel {
model: Groupview;
export interface IDockviewGroupPanel extends IGridviewPanel {
model: DockviewGroupPanelModel;
locked: boolean;
readonly size: number;
readonly panels: IDockviewPanel[];
readonly activePanel: IDockviewPanel | undefined;
}
export type IGroupviewPanelPublic = IGroupviewPanel;
export type IDockviewGroupPanelPublic = IDockviewGroupPanel;
export type GroupviewPanelApi = GridviewPanelApi;
export type DockviewGroupPanelApi = GridviewPanelApi;
class GroupviewApi extends GridviewPanelApiImpl implements GroupviewPanelApi {}
export class GroupPanel extends GridviewPanel implements IGroupviewPanel {
private readonly _model: Groupview;
export class DockviewGroupPanel
extends GridviewPanel
implements IDockviewGroupPanel
{
private readonly _model: DockviewGroupPanelModel;
get panels(): IDockviewPanel[] {
return this._model.panels;
@ -37,7 +39,7 @@ export class GroupPanel extends GridviewPanel implements IGroupviewPanel {
return this._model.size;
}
get model(): Groupview {
get model(): DockviewGroupPanelModel {
return this._model;
}
@ -76,10 +78,16 @@ export class GroupPanel extends GridviewPanel implements IGroupviewPanel {
) {
super(id, 'groupview_default');
this._model = new Groupview(this.element, accessor, id, options, this);
this._model = new DockviewGroupPanelModel(
this.element,
accessor,
id,
options,
this
);
}
initialize() {
initialize(): void {
this._model.initialize();
}
@ -98,6 +106,7 @@ export class GroupPanel extends GridviewPanel implements IGroupviewPanel {
}
toJSON(): any {
// TODO fix typing
return this.model.toJSON();
}
}

View File

@ -1,29 +1,34 @@
import { DockviewApi } from '../api/component.api';
import { getPanelData, PanelTransfer } from '../dnd/dataTransfer';
import { Droptarget, Position } from '../dnd/droptarget';
import { DockviewComponent } from '../dockview/dockviewComponent';
import { DockviewComponent } from './dockviewComponent';
import { isAncestor, toggleClass } from '../dom';
import { addDisposableListener, Emitter, Event } from '../events';
import { IGridPanelView } from '../gridview/baseComponentGridview';
import { IViewSize } from '../gridview/gridview';
import { CompositeDisposable, IDisposable } from '../lifecycle';
import { CompositeDisposable } from '../lifecycle';
import { PanelInitParameters, PanelUpdateEvent } from '../panel/types';
import { ContentContainer, IContentContainer } from './panel/content';
import { ITabsContainer, TabsContainer } from './titlebar/tabsContainer';
import { IWatermarkRenderer } from './types';
import { GroupPanel } from './groupviewPanel';
import { DockviewDropTargets } from './dnd';
import { IDockviewPanel } from '../dockview/dockviewPanel';
import { IGroupControlRenderer } from '../dockview/options';
import {
ContentContainer,
IContentContainer,
} from './components/panel/content';
import {
ITabsContainer,
TabsContainer,
} from './components/titlebar/tabsContainer';
import { DockviewDropTargets, IWatermarkRenderer } from './types';
import { DockviewGroupPanel } from './dockviewGroupPanel';
import { IDockviewPanel } from './dockviewPanel';
import { IGroupControlRenderer } from './options';
export interface DndService {
canDisplayOverlay(
group: IGroupview,
group: IDockviewGroupPanelModel,
event: DragEvent,
target: DockviewDropTargets
): boolean;
onDrop(
group: IGroupview,
group: IDockviewGroupPanelModel,
event: DragEvent,
position: Position,
index?: number
@ -77,7 +82,7 @@ export interface IHeader {
height: number | undefined;
}
export interface IGroupview extends IDisposable, IGridPanelView {
export interface IDockviewGroupPanelModel extends IGridPanelView {
readonly isActive: boolean;
readonly size: number;
readonly panels: IDockviewPanel[];
@ -117,7 +122,10 @@ export interface IGroupview extends IDisposable, IGridPanelView {
): boolean;
}
export class Groupview extends CompositeDisposable implements IGroupview {
export class DockviewGroupPanelModel
extends CompositeDisposable
implements IDockviewGroupPanelModel
{
private readonly tabsContainer: ITabsContainer;
private readonly contentContainer: IContentContainer;
private readonly dropTarget: Droptarget;
@ -232,7 +240,7 @@ export class Groupview extends CompositeDisposable implements IGroupview {
private accessor: DockviewComponent,
public id: string,
private readonly options: GroupOptions,
private readonly groupPanel: GroupPanel
private readonly groupPanel: DockviewGroupPanel
) {
super();
@ -427,7 +435,7 @@ export class Groupview extends CompositeDisposable implements IGroupview {
}
focus(): void {
this._activePanel?.focus();
this._activePanel?.focus?.();
}
public openPanel(
@ -525,7 +533,7 @@ export class Groupview extends CompositeDisposable implements IGroupview {
): void {
if (!force && this.isActive === isGroupActive) {
if (!skipFocus) {
this._activePanel?.focus();
this._activePanel?.focus?.();
}
return;
}
@ -545,7 +553,7 @@ export class Groupview extends CompositeDisposable implements IGroupview {
if (isGroupActive) {
if (!skipFocus) {
this._activePanel?.focus();
this._activePanel?.focus?.();
}
}
}
@ -681,7 +689,7 @@ export class Groupview extends CompositeDisposable implements IGroupview {
}
if (!this.isEmpty && this.watermark) {
this.watermark.element.remove();
this.watermark.dispose();
this.watermark.dispose?.();
this.watermark = undefined;
this.tabsContainer.show();
}
@ -760,7 +768,7 @@ export class Groupview extends CompositeDisposable implements IGroupview {
public dispose(): void {
super.dispose();
this.watermark?.dispose();
this.watermark?.dispose?.();
for (const panel of this.panels) {
panel.dispose();

View File

@ -7,20 +7,20 @@ import {
GroupPanelUpdateEvent,
GroupviewPanelState,
IGroupPanelInitParameters,
} from '../groupview/types';
import { GroupPanel } from '../groupview/groupviewPanel';
} from './types';
import { DockviewGroupPanel } from './dockviewGroupPanel';
import { CompositeDisposable, IDisposable } from '../lifecycle';
import { IPanel, Parameters } from '../panel/types';
import { IGroupPanelView } from './defaultGroupPanelView';
import { DockviewComponent } from './dockviewComponent';
import { IDockviewPanelModel } from './dockviewPanelModel';
import { IDockviewComponent } from './dockviewComponent';
export interface IDockviewPanel extends IDisposable, IPanel {
readonly view?: IGroupPanelView;
readonly group: GroupPanel;
readonly view: IDockviewPanelModel;
readonly group: DockviewGroupPanel;
readonly api: DockviewPanelApi;
readonly title: string;
readonly params: Record<string, any> | undefined;
updateParentGroup(group: GroupPanel, isGroupActive: boolean): void;
updateParentGroup(group: DockviewGroupPanel, isGroupActive: boolean): void;
init(params: IGroupPanelInitParameters): void;
toJSON(): GroupviewPanelState;
update(event: GroupPanelUpdateEvent): void;
@ -31,11 +31,9 @@ export class DockviewPanel
implements IDockviewPanel
{
readonly api: DockviewPanelApiImpl;
private _group: GroupPanel;
private _group: DockviewGroupPanel;
private _params?: Parameters;
private _view?: IGroupPanelView;
private _title: string;
get params(): Parameters | undefined {
@ -46,19 +44,16 @@ export class DockviewPanel
return this._title;
}
get group(): GroupPanel {
get group(): DockviewGroupPanel {
return this._group;
}
get view(): IGroupPanelView | undefined {
return this._view;
}
constructor(
public readonly id: string,
accessor: DockviewComponent,
accessor: IDockviewComponent,
private readonly containerApi: DockviewApi,
group: GroupPanel
group: DockviewGroupPanel,
readonly view: IDockviewPanelModel
) {
super();
this._title = '';
@ -80,11 +75,8 @@ export class DockviewPanel
public init(params: IGroupPanelInitParameters): void {
this._params = params.params;
this._view = params.view;
if (typeof params.title === 'string') {
this.setTitle(params.title);
}
this.setTitle(params.title);
this.view?.init({
...params,
@ -100,7 +92,8 @@ export class DockviewPanel
public toJSON(): GroupviewPanelState {
return <GroupviewPanelState>{
id: this.id,
view: this.view!.toJSON(),
contentComponent: this.view.contentComponent,
tabComponent: this.view.tabComponent,
params:
Object.keys(this._params || {}).length > 0
? this._params
@ -133,11 +126,9 @@ export class DockviewPanel
...event.params.params,
};
if (typeof params.title === 'string') {
if (params.title !== this.title) {
this._title = params.title;
this.api._onDidTitleChange.fire({ title: this.title });
}
if (params.title !== this.title) {
this._title = params.title;
this.api._onDidTitleChange.fire({ title: this.title });
}
this.view?.update({
@ -148,7 +139,10 @@ export class DockviewPanel
});
}
public updateParentGroup(group: GroupPanel, isGroupActive: boolean): void {
public updateParentGroup(
group: DockviewGroupPanel,
isGroupActive: boolean
): void {
this._group = group;
this.api.group = group;

View File

@ -0,0 +1,120 @@
import { DefaultTab } from './components/tab/defaultTab';
import {
GroupPanelPartInitParameters,
IContentRenderer,
ITabRenderer,
GroupPanelUpdateEvent,
} from './types';
import { DockviewGroupPanel } from './dockviewGroupPanel';
import { IDisposable } from '../lifecycle';
import { createComponent } from '../panel/componentFactory';
import { IDockviewComponent } from './dockviewComponent';
export interface IDockviewPanelModel extends IDisposable {
readonly contentComponent: string;
readonly tabComponent?: string;
readonly content: IContentRenderer;
readonly tab?: ITabRenderer;
update(event: GroupPanelUpdateEvent): void;
layout(width: number, height: number): void;
init(params: GroupPanelPartInitParameters): void;
updateParentGroup(group: DockviewGroupPanel, isPanelVisible: boolean): void;
}
export class DockviewPanelModel implements IDockviewPanelModel {
private readonly _content: IContentRenderer;
private readonly _tab: ITabRenderer;
private _group: DockviewGroupPanel | null = null;
private _isPanelVisible: boolean | null = null;
get content(): IContentRenderer {
return this._content;
}
get tab(): ITabRenderer {
return this._tab;
}
constructor(
private readonly accessor: IDockviewComponent,
private readonly id: string,
readonly contentComponent: string,
readonly tabComponent?: string
) {
this._content = this.createContentComponent(this.id, contentComponent);
this._tab =
this.createTabComponent(this.id, tabComponent) ?? new DefaultTab();
}
init(params: GroupPanelPartInitParameters): void {
this.content.init({ ...params, tab: this.tab });
this.tab.init(params);
}
updateParentGroup(
group: DockviewGroupPanel,
isPanelVisible: boolean
): void {
if (group !== this._group) {
this._group = group;
if (this._content.onGroupChange) {
this._content.onGroupChange(group);
}
if (this._tab.onGroupChange) {
this._tab.onGroupChange(group);
}
}
if (isPanelVisible !== this._isPanelVisible) {
this._isPanelVisible = isPanelVisible;
if (this._content.onPanelVisibleChange) {
this._content.onPanelVisibleChange(isPanelVisible);
}
if (this._tab.onPanelVisibleChange) {
this._tab.onPanelVisibleChange(isPanelVisible);
}
}
}
layout(width: number, height: number): void {
this.content.layout?.(width, height);
}
update(event: GroupPanelUpdateEvent): void {
this.content.update?.(event);
this.tab.update?.(event);
}
dispose(): void {
this.content.dispose?.();
this.tab.dispose?.();
}
private createContentComponent(
id: string,
componentName: string
): IContentRenderer {
return createComponent(
id,
componentName,
this.accessor.options.components || {},
this.accessor.options.frameworkComponents,
this.accessor.options.frameworkComponentFactory?.content
);
}
private createTabComponent(
id: string,
componentName?: string
): ITabRenderer {
return createComponent(
id,
componentName,
this.accessor.options.tabComponents || {},
this.accessor.options.frameworkTabComponents,
this.accessor.options.frameworkComponentFactory?.tab,
() => new DefaultTab()
);
}
}

View File

@ -6,11 +6,14 @@ import {
ITabRenderer,
WatermarkConstructor,
IWatermarkRenderer,
} from '../groupview/types';
import { GroupPanel, GroupviewPanelApi } from '../groupview/groupviewPanel';
DockviewDropTargets,
} from './types';
import {
DockviewGroupPanel,
DockviewGroupPanelApi,
} from './dockviewGroupPanel';
import { ISplitviewStyles, Orientation } from '../splitview/core/splitview';
import { FrameworkFactory } from '../types';
import { DockviewDropTargets } from '../groupview/dnd';
import { PanelTransfer } from '../dnd/dataTransfer';
import { IDisposable } from '../lifecycle';
import { Position } from '../dnd/droptarget';
@ -18,7 +21,10 @@ import { IDockviewPanel } from './dockviewPanel';
export interface IGroupControlRenderer extends IDisposable {
readonly element: HTMLElement;
init(params: { containerApi: DockviewApi; api: GroupviewPanelApi }): void;
init(params: {
containerApi: DockviewApi;
api: DockviewGroupPanelApi;
}): void;
}
export interface GroupPanelFrameworkComponentFactory {
@ -61,7 +67,7 @@ export interface DockviewDndOverlayEvent {
nativeEvent: DragEvent;
target: DockviewDropTargets;
position: Position;
group?: GroupPanel;
group?: DockviewGroupPanel;
getData: () => PanelTransfer | undefined;
}
@ -74,7 +80,9 @@ export interface DockviewComponentOptions extends DockviewRenderFunctions {
styles?: ISplitviewStyles;
defaultTabComponent?: string;
showDndOverlay?: (event: DockviewDndOverlayEvent) => boolean;
createGroupControlElement?: (group: GroupPanel) => IGroupControlRenderer;
createGroupControlElement?: (
group: DockviewGroupPanel
) => IGroupControlRenderer;
singleTabMode?: 'fullwidth' | 'default';
}
@ -93,7 +101,7 @@ type RelativePanel = {
type RelativeGroup = {
direction?: Direction;
referenceGroup: string | GroupPanel;
referenceGroup: string | DockviewGroupPanel;
};
type AbsolutePosition = {
@ -136,7 +144,7 @@ type AddGroupOptionsWithPanel = {
};
type AddGroupOptionsWithGroup = {
referenceGroup: string | GroupPanel;
referenceGroup: string | DockviewGroupPanel;
direction?: Omit<Direction, 'within'>;
};
@ -169,5 +177,5 @@ export interface MovementOptions2 {
export interface MovementOptions extends MovementOptions2 {
includePanel?: boolean;
group?: GroupPanel;
group?: DockviewGroupPanel;
}

View File

@ -1,4 +1,4 @@
import { IDockviewComponent } from '../dockview/dockviewComponent';
import { IDockviewComponent } from './dockviewComponent';
import { DockviewPanelApi } from '../api/dockviewPanelApi';
import {
PanelInitParameters,
@ -7,19 +7,19 @@ import {
Parameters,
} from '../panel/types';
import { DockviewApi } from '../api/component.api';
import { GroupPanel } from './groupviewPanel';
import { Event } from '../events';
import { IGroupPanelView } from '../dockview/defaultGroupPanelView';
import { Optional } from '../types';
import { DockviewGroupPanel } from './dockviewGroupPanel';
export interface IRenderable {
id: string;
element: HTMLElement;
onDidFocus?: Event<void>;
onDidBlur?: Event<void>;
export enum DockviewDropTargets {
Tab,
Panel,
TabContainer,
Edge,
}
export interface HeaderPartInitParameters {
title?: string;
title: string;
}
export interface GroupPanelPartInitParameters
@ -34,26 +34,38 @@ export interface GroupPanelContentPartInitParameters
tab: ITabRenderer;
}
export interface IWatermarkRenderer extends IPanel {
export interface IWatermarkRenderer
extends Optional<
Omit<IPanel, 'id'>,
'dispose' | 'update' | 'layout' | 'toJSON'
> {
readonly element: HTMLElement;
init: (params: GroupPanelPartInitParameters) => void;
updateParentGroup(group: GroupPanel, visible: boolean): void;
updateParentGroup(group: DockviewGroupPanel, visible: boolean): void;
}
export interface ITabRenderer extends IPanel {
export interface ITabRenderer
extends Optional<
Omit<IPanel, 'id'>,
'dispose' | 'update' | 'layout' | 'toJSON'
> {
readonly element: HTMLElement;
init(parameters: GroupPanelPartInitParameters): void;
updateParentGroup(group: GroupPanel, isPanelVisible: boolean): void;
onGroupChange?(group: DockviewGroupPanel): void;
onPanelVisibleChange?(isPanelVisible: boolean): void;
}
export interface IContentRenderer extends IPanel {
export interface IContentRenderer
extends Optional<
Omit<IPanel, 'id'>,
'dispose' | 'update' | 'layout' | 'toJSON'
> {
readonly element: HTMLElement;
readonly actions?: HTMLElement;
readonly onDidFocus?: Event<void>;
readonly onDidBlur?: Event<void>;
updateParentGroup(group: GroupPanel, isPanelVisible: boolean): void;
init(parameters: GroupPanelContentPartInitParameters): void;
layout(width: number, height: number): void;
onGroupChange?(group: DockviewGroupPanel): void;
onPanelVisibleChange?(isPanelVisible: boolean): void;
}
// watermark component
@ -64,13 +76,6 @@ export interface WatermarkPartInitParameters {
// constructors
export interface PanelHeaderPartConstructor {
new (): ITabRenderer;
}
export interface PanelContentPartConstructor {
new (): IContentRenderer;
}
export interface WatermarkConstructor {
new (): IWatermarkRenderer;
}
@ -78,7 +83,7 @@ export interface WatermarkConstructor {
export interface IGroupPanelInitParameters
extends PanelInitParameters,
HeaderPartInitParameters {
view: IGroupPanelView;
//
}
export type GroupPanelUpdateEvent = PanelUpdateEvent<{
@ -88,7 +93,8 @@ export type GroupPanelUpdateEvent = PanelUpdateEvent<{
export interface GroupviewPanelState {
id: string;
view?: any;
contentComponent?: string;
tabComponent?: string;
title?: string;
params?: { [key: string]: any };
}

View File

@ -25,7 +25,10 @@ export function watchElementResize(
};
}
export const removeClasses = (element: HTMLElement, ...classes: string[]) => {
export const removeClasses = (
element: HTMLElement,
...classes: string[]
): void => {
for (const classname of classes) {
if (element.classList.contains(classname)) {
element.classList.remove(classname);
@ -33,7 +36,10 @@ export const removeClasses = (element: HTMLElement, ...classes: string[]) => {
}
};
export const addClasses = (element: HTMLElement, ...classes: string[]) => {
export const addClasses = (
element: HTMLElement,
...classes: string[]
): void => {
for (const classname of classes) {
if (!element.classList.contains(classname)) {
element.classList.add(classname);
@ -45,7 +51,7 @@ export const toggleClass = (
element: HTMLElement,
className: string,
isToggled: boolean
) => {
): void => {
const hasClass = element.classList.contains(className);
if (isToggled && !hasClass) {
element.classList.add(className);
@ -74,8 +80,8 @@ export function getElementsByTagName(tag: string): HTMLElement[] {
}
export interface IFocusTracker extends IDisposable {
onDidFocus: Event<void>;
onDidBlur: Event<void>;
readonly onDidFocus: Event<void>;
readonly onDidBlur: Event<void>;
refreshState?(): void;
}
@ -153,11 +159,11 @@ class FocusTracker extends CompositeDisposable implements IFocusTracker {
}
}
refreshState() {
refreshState(): void {
this._refreshStateHandler();
}
public dispose() {
public dispose(): void {
super.dispose();
this._onDidBlur.dispose();

View File

@ -5,7 +5,7 @@ export interface Event<T> {
}
export interface EmitterOptions {
replay?: boolean;
readonly replay?: boolean;
}
export namespace Event {
@ -35,7 +35,7 @@ export class Emitter<T> implements IDisposable {
constructor(private readonly options?: EmitterOptions) {}
get event() {
get event(): Event<T> {
if (!this._event) {
this._event = (listener: (e: T) => void): IDisposable => {
if (this.options?.replay && this._last !== undefined) {
@ -57,14 +57,14 @@ export class Emitter<T> implements IDisposable {
return this._event;
}
public fire(e: T) {
public fire(e: T): void {
this._last = e;
for (const listener of this._listeners) {
listener(e);
}
}
public dispose() {
public dispose(): void {
this._listeners = [];
this._disposed = true;
}

View File

@ -92,40 +92,40 @@ export abstract class BaseGrid<T extends IGridPanelView>
protected readonly _bufferOnDidLayoutChange = new TickDelayedEvent();
get id() {
get id(): string {
return this._id;
}
get element() {
get element(): HTMLElement {
return this._element;
}
get size() {
get size(): number {
return this._groups.size;
}
get groups() {
get groups(): T[] {
return Array.from(this._groups.values()).map((_) => _.value);
}
get width() {
get width(): number {
return this.gridview.width;
}
get height() {
get height(): number {
return this.gridview.height;
}
get minimumHeight() {
get minimumHeight(): number {
return this.gridview.minimumHeight;
}
get maximumHeight() {
get maximumHeight(): number {
return this.gridview.maximumHeight;
}
get minimumWidth() {
get minimumWidth(): number {
return this.gridview.minimumWidth;
}
get maximumWidth() {
get maximumWidth(): number {
return this.gridview.maximumWidth;
}
@ -176,16 +176,20 @@ export abstract class BaseGrid<T extends IGridPanelView>
public abstract clear(): void;
public setVisible(panel: T, visible: boolean) {
public setVisible(panel: T, visible: boolean): void {
this.gridview.setViewVisible(getGridLocation(panel.element), visible);
this._onDidLayoutChange.fire();
}
public isVisible(panel: T) {
public isVisible(panel: T): boolean {
return this.gridview.isViewVisible(getGridLocation(panel.element));
}
protected doAddGroup(group: T, location: number[] = [0], size?: number) {
protected doAddGroup(
group: T,
location: number[] = [0],
size?: number
): void {
this.gridview.addView(group, size ?? Sizing.Distribute, location);
this._onDidAddGroup.fire(group);
@ -196,7 +200,7 @@ export abstract class BaseGrid<T extends IGridPanelView>
protected doRemoveGroup(
group: T,
options?: { skipActive?: boolean; skipDispose?: boolean }
) {
): T {
if (!this._groups.has(group.id)) {
throw new Error('invalid operation');
}
@ -228,21 +232,21 @@ export abstract class BaseGrid<T extends IGridPanelView>
return this._groups.get(id)?.value;
}
public doSetGroupActive(group: T | undefined, skipFocus?: boolean) {
public doSetGroupActive(group: T | undefined, skipFocus?: boolean): void {
if (this._activeGroup === group) {
return;
}
if (this._activeGroup) {
this._activeGroup.setActive(false);
if (!skipFocus) {
this._activeGroup.focus();
this._activeGroup.focus?.();
}
}
if (group) {
group.setActive(true);
if (!skipFocus) {
group.focus();
group.focus?.();
}
}
@ -251,11 +255,11 @@ export abstract class BaseGrid<T extends IGridPanelView>
this._onDidActiveGroupChange.fire(group);
}
public removeGroup(group: T) {
public removeGroup(group: T): void {
this.doRemoveGroup(group);
}
public moveToNext(options?: MovementOptions2) {
public moveToNext(options?: MovementOptions2): void {
if (!options) {
options = {};
}
@ -271,7 +275,7 @@ export abstract class BaseGrid<T extends IGridPanelView>
this.doSetGroupActive(next as T);
}
public moveToPrevious(options?: MovementOptions2) {
public moveToPrevious(options?: MovementOptions2): void {
if (!options) {
options = {};
}

View File

@ -40,15 +40,15 @@ export abstract class BasePanelView<T extends PanelApiImpl>
*/
protected abstract getComponent(): IFrameworkPart;
get element() {
get element(): HTMLElement {
return this._element;
}
get width() {
get width(): number {
return this._width;
}
get height() {
get height(): number {
return this._height;
}
@ -83,11 +83,11 @@ export abstract class BasePanelView<T extends PanelApiImpl>
);
}
focus() {
focus(): void {
this.api._onFocusEvent.fire();
}
layout(width: number, height: number) {
layout(width: number, height: number): void {
this._width = width;
this._height = height;
this.api._onDidDimensionChange.fire({ width, height });
@ -104,7 +104,7 @@ export abstract class BasePanelView<T extends PanelApiImpl>
this.part = this.getComponent();
}
update(event: PanelUpdateEvent) {
update(event: PanelUpdateEvent): void {
this._params = {
...this._params,
params: {
@ -125,7 +125,7 @@ export abstract class BasePanelView<T extends PanelApiImpl>
};
}
dispose() {
dispose(): void {
super.dispose();
this.api.dispose();

View File

@ -22,6 +22,8 @@ export class BranchNode extends CompositeDisposable implements IView {
private splitview: Splitview;
private _orthogonalSize: number;
private _size: number;
private _childrenDisposable: IDisposable = Disposable.NONE;
public readonly children: Node[] = [];
private readonly _onDidChange = new Emitter<{
@ -61,11 +63,11 @@ export class BranchNode extends CompositeDisposable implements IView {
return this.splitview.maximumSize;
}
get orthogonalSize() {
get orthogonalSize(): number {
return this._orthogonalSize;
}
get size() {
get size(): number {
return this._size;
}
@ -168,7 +170,7 @@ export class BranchNode extends CompositeDisposable implements IView {
this.setupChildrenEvents();
}
setVisible(visible: boolean) {
setVisible(visible: boolean): void {
for (const child of this.children) {
child.setVisible(visible);
}
@ -258,7 +260,7 @@ export class BranchNode extends CompositeDisposable implements IView {
return this.splitview.getViewCachedVisibleSize(index);
}
public removeChild(index: number, sizing?: Sizing) {
public removeChild(index: number, sizing?: Sizing): void {
if (index < 0 || index >= this.children.length) {
throw new Error('Invalid index');
}
@ -279,9 +281,7 @@ export class BranchNode extends CompositeDisposable implements IView {
return child;
}
private _childrenDisposable: IDisposable = Disposable.NONE;
private setupChildrenEvents() {
private setupChildrenEvents(): void {
this._childrenDisposable.dispose();
this._childrenDisposable = Event.any(
@ -295,7 +295,7 @@ export class BranchNode extends CompositeDisposable implements IView {
});
}
public dispose() {
public dispose(): void {
super.dispose();
this._childrenDisposable.dispose();
this.children.forEach((child) => child.dispose());

View File

@ -261,6 +261,14 @@ export interface INodeDescriptor {
export interface IViewDeserializer {
fromJSON: (data: ISerializedLeafNode) => IGridView;
}
export interface SerializedGridview<T> {
root: SerializedGridObject<T>;
width: number;
height: number;
orientation: Orientation;
}
export class Gridview implements IDisposable {
private _root: BranchNode | undefined;
public readonly element: HTMLElement;
@ -277,7 +285,41 @@ export class Gridview implements IDisposable {
return this._root ? this._root.children.length : 0;
}
public serialize() {
public get orientation(): Orientation {
return this.root.orientation;
}
public set orientation(orientation: Orientation) {
if (this.root.orientation === orientation) {
return;
}
const { size, orthogonalSize } = this.root;
this.root = flipNode(this.root, orthogonalSize, size);
this.root.layout(size, orthogonalSize);
}
get width(): number {
return this.root.width;
}
get height(): number {
return this.root.height;
}
get minimumWidth(): number {
return this.root.minimumWidth;
}
get minimumHeight(): number {
return this.root.minimumHeight;
}
get maximumWidth(): number {
return this.root.maximumHeight;
}
get maximumHeight(): number {
return this.root.maximumHeight;
}
public serialize(): SerializedGridview<any> {
const root = serializeBranchNode(this.getView(), this.orientation);
return {
@ -288,7 +330,7 @@ export class Gridview implements IDisposable {
};
}
public dispose() {
public dispose(): void {
this.disposable.dispose();
this._onDidChange.dispose();
this.root.dispose();
@ -296,7 +338,7 @@ export class Gridview implements IDisposable {
this.element.remove();
}
public clear() {
public clear(): void {
const orientation = this.root.orientation;
this.root = new BranchNode(
orientation,
@ -307,7 +349,7 @@ export class Gridview implements IDisposable {
);
}
public deserialize(json: any, deserializer: IViewDeserializer) {
public deserialize(json: any, deserializer: IViewDeserializer): void {
const orientation = json.orientation;
const height =
orientation === Orientation.VERTICAL ? json.height : json.width;
@ -378,20 +420,6 @@ export class Gridview implements IDisposable {
return result;
}
public get orientation() {
return this.root.orientation;
}
public set orientation(orientation: Orientation) {
if (this.root.orientation === orientation) {
return;
}
const { size, orthogonalSize } = this.root;
this.root = flipNode(this.root, orthogonalSize, size);
this.root.layout(size, orthogonalSize);
}
private get root(): BranchNode {
return this._root!;
}
@ -448,11 +476,11 @@ export class Gridview implements IDisposable {
});
}
public next(location: number[]) {
public next(location: number[]): LeafNode {
return this.progmaticSelect(location);
}
public previous(location: number[]) {
public previous(location: number[]): LeafNode {
return this.progmaticSelect(location, true);
}
@ -492,7 +520,7 @@ export class Gridview implements IDisposable {
return { box, children };
}
private progmaticSelect(location: number[], reverse = false) {
private progmaticSelect(location: number[], reverse = false): LeafNode {
const [path, node] = this.getNode(location);
if (!(node instanceof LeafNode)) {
@ -513,26 +541,6 @@ export class Gridview implements IDisposable {
return findLeaf(this.root, reverse);
}
get width(): number {
return this.root.width;
}
get height(): number {
return this.root.height;
}
get minimumWidth(): number {
return this.root.minimumWidth;
}
get minimumHeight(): number {
return this.root.minimumHeight;
}
get maximumWidth(): number {
return this.root.maximumHeight;
}
get maximumHeight(): number {
return this.root.maximumHeight;
}
constructor(
readonly proportionalLayout: boolean,
readonly styles: ISplitviewStyles | undefined,
@ -581,7 +589,11 @@ export class Gridview implements IDisposable {
parent.moveChild(from, to);
}
public addView(view: IGridView, size: number | Sizing, location: number[]) {
public addView(
view: IGridView,
size: number | Sizing,
location: number[]
): void {
const [rest, index] = tail(location);
const [pathToParent, parent] = this.getNode(rest);
@ -636,7 +648,7 @@ export class Gridview implements IDisposable {
}
}
public remove(view: IGridView, sizing?: Sizing) {
public remove(view: IGridView, sizing?: Sizing): IGridView {
const location = getGridLocation(view.element);
return this.removeView(location, sizing);
}
@ -721,7 +733,7 @@ export class Gridview implements IDisposable {
return node.view;
}
public layout(width: number, height: number) {
public layout(width: number, height: number): void {
const [size, orthogonalSize] =
this.root.orientation === Orientation.HORIZONTAL
? [height, width]

View File

@ -2,6 +2,7 @@ import {
getRelativeLocation,
SerializedGridObject,
getGridLocation,
SerializedGridview,
} from './gridview';
import { tail, sequenceEquals } from '../array';
import { CompositeDisposable } from '../lifecycle';
@ -26,13 +27,8 @@ import { createComponent } from '../panel/componentFactory';
import { Emitter, Event } from '../events';
import { Position } from '../dnd/droptarget';
export interface SerializedGridview {
grid: {
height: number;
width: number;
orientation: Orientation;
root: SerializedGridObject<GridPanelViewState>;
};
export interface SerializedGridviewComponent {
grid: SerializedGridview<GridPanelViewState>;
activePanel?: string;
}
@ -64,8 +60,8 @@ export interface IGridviewComponent extends IBaseGrid<GridviewPanel> {
addPanel(options: AddComponentOptions): IGridviewPanel;
removePanel(panel: IGridviewPanel, sizing?: Sizing): void;
focus(): void;
fromJSON(serializedGridview: SerializedGridview): void;
toJSON(): SerializedGridview;
fromJSON(serializedGridview: SerializedGridviewComponent): void;
toJSON(): SerializedGridviewComponent;
movePanel(
panel: IGridviewPanel,
options: { direction: Direction; reference: string; size?: number }
@ -84,7 +80,7 @@ export class GridviewComponent
private readonly _onDidLayoutfromJSON = new Emitter<void>();
readonly onDidLayoutFromJSON: Event<void> = this._onDidLayoutfromJSON.event;
get orientation() {
get orientation(): Orientation {
return this.gridview.orientation;
}
@ -92,7 +88,7 @@ export class GridviewComponent
this.gridview.orientation = value;
}
get options() {
get options(): GridviewComponentOptions {
return this._options;
}
@ -135,7 +131,7 @@ export class GridviewComponent
this.layout(this.gridview.width, this.gridview.height, true);
}
removePanel(panel: GridviewPanel) {
removePanel(panel: GridviewPanel): void {
this.removeGroup(panel);
}
@ -144,7 +140,7 @@ export class GridviewComponent
*
* @returns A JSON respresentation of the layout
*/
public toJSON(): SerializedGridview {
public toJSON(): SerializedGridviewComponent {
const data = this.gridview.serialize() as {
height: number;
width: number;
@ -168,11 +164,11 @@ export class GridviewComponent
});
}
focus() {
focus(): void {
this.activeGroup?.focus();
}
public fromJSON(serializedGridview: SerializedGridview) {
public fromJSON(serializedGridview: SerializedGridviewComponent): void {
this.clear();
const { grid, activePanel } = serializedGridview;
@ -339,7 +335,7 @@ export class GridviewComponent
return view;
}
private registerPanel(panel: GridviewPanel) {
private registerPanel(panel: GridviewPanel): void {
const disposable = new CompositeDisposable(
panel.api.onDidFocusChange((event) => {
if (!event.isFocused) {
@ -366,7 +362,7 @@ export class GridviewComponent
referenceGroup: IGridPanelComponentView,
groupId: string,
target: Position
) {
): void {
const sourceGroup = this.getPanel(groupId);
if (!sourceGroup) {
@ -411,11 +407,11 @@ export class GridviewComponent
this.doAddGroup(targetGroup, location);
}
removeGroup(group: GridviewPanel) {
removeGroup(group: GridviewPanel): void {
super.removeGroup(group);
}
public dispose() {
public dispose(): void {
super.dispose();
this._onDidLayoutfromJSON.dispose();

View File

@ -62,11 +62,11 @@ export abstract class GridviewPanel
return this._priority;
}
get snap() {
get snap(): boolean {
return this._snap;
}
get minimumWidth() {
get minimumWidth(): number {
const width =
typeof this._minimumWidth === 'function'
? this._minimumWidth()
@ -80,7 +80,7 @@ export abstract class GridviewPanel
return width;
}
get minimumHeight() {
get minimumHeight(): number {
const height =
typeof this._minimumHeight === 'function'
? this._minimumHeight()
@ -94,7 +94,7 @@ export abstract class GridviewPanel
return height;
}
get maximumHeight() {
get maximumHeight(): number {
const height =
typeof this._maximumHeight === 'function'
? this._maximumHeight()
@ -108,7 +108,7 @@ export abstract class GridviewPanel
return height;
}
get maximumWidth() {
get maximumWidth(): number {
const width =
typeof this._maximumWidth === 'function'
? this._maximumWidth()
@ -122,7 +122,7 @@ export abstract class GridviewPanel
return width;
}
get isActive() {
get isActive(): boolean {
return this.api.isActive;
}
@ -177,11 +177,11 @@ export abstract class GridviewPanel
);
}
setVisible(isVisible: boolean) {
setVisible(isVisible: boolean): void {
this.api._onDidVisibilityChange.fire({ isVisible });
}
setActive(isActive: boolean) {
setActive(isActive: boolean): void {
this.api._onDidActiveChange.fire({ isActive });
}
@ -209,7 +209,7 @@ export abstract class GridviewPanel
}
}
private updateConstraints() {
private updateConstraints(): void {
this.api._onDidConstraintsChange.fire({
minimumWidth: this._evaluatedMinimumWidth,
maximumWidth: this._evaluatedMaximumWidth,

View File

@ -43,7 +43,7 @@ export class LeafNode implements IView {
return this.view.priority;
}
get snap() {
get snap(): boolean | undefined {
return this.view.snap;
}
@ -71,25 +71,25 @@ export class LeafNode implements IView {
: this.maximumHeight;
}
get orthogonalSize() {
get orthogonalSize(): number {
return this._orthogonalSize;
}
get size() {
get size(): number {
return this._size;
}
get element() {
get element(): HTMLElement {
return this.view.element;
}
get width() {
get width(): number {
return this.orientation === Orientation.HORIZONTAL
? this.orthogonalSize
: this.size;
}
get height() {
get height(): number {
return this.orientation === Orientation.HORIZONTAL
? this.size
: this.orthogonalSize;
@ -122,21 +122,21 @@ export class LeafNode implements IView {
});
}
public setVisible(visible: boolean) {
public setVisible(visible: boolean): void {
if (this.view.setVisible) {
this.view.setVisible(visible);
this._onDidChange.fire({});
}
}
public layout(size: number, orthogonalSize: number) {
public layout(size: number, orthogonalSize: number): void {
this._size = size;
this._orthogonalSize = orthogonalSize;
this.view.layout(this.width, this.height);
}
public dispose() {
public dispose(): void {
this._onDidChange.dispose();
this._disposable.dispose();
}

View File

@ -1,6 +0,0 @@
export enum DockviewDropTargets {
Tab,
Panel,
TabContainer,
Edge,
}

View File

@ -23,16 +23,15 @@ export * from './splitview/core/options';
export * from './paneview/paneview';
export * from './gridview/gridview';
export * from './groupview/groupview';
export * from './dockview/dockviewGroupPanelModel';
export * from './gridview/baseComponentGridview';
export * from './paneview/draggablePaneviewPanel';
export * from './groupview/panel/content';
export * from './groupview/tab';
export * from './groupview/dnd';
export * from './groupview/types';
export * from './groupview/groupviewPanel';
export * from './dockview/components/panel/content';
export * from './dockview/components/tab/tab';
export * from './dockview/types';
export * from './dockview/dockviewGroupPanel';
export * from './dockview/options';
export * from './dockview/dockviewPanel';
@ -48,9 +47,8 @@ export { PaneviewComponentOptions } from './paneview/options';
export * from './gridview/gridviewPanel';
export * from './splitview/splitviewPanel';
export * from './paneview/paneviewPanel';
export * from './groupview/types';
export * from './dockview/types';
export { Event } from './events';
export {
Position,
positionToDirection,

View File

@ -3,8 +3,8 @@ export interface IDisposable {
}
export interface IValueDisposable<T> {
value: T;
disposable: IDisposable;
readonly value: T;
readonly disposable: IDisposable;
}
export namespace Disposable {
@ -26,11 +26,11 @@ export class CompositeDisposable {
this.disposables = args;
}
public addDisposables(...args: IDisposable[]) {
public addDisposables(...args: IDisposable[]): void {
args.forEach((arg) => this.disposables.push(arg));
}
public dispose() {
public dispose(): void {
this.disposables.forEach((arg) => arg.dispose());
}
}
@ -45,7 +45,7 @@ export class MutableDisposable implements IDisposable {
this._disposable = disposable;
}
public dispose() {
public dispose(): void {
if (this._disposable) {
this._disposable.dispose();
this._disposable = Disposable.NONE;

View File

@ -22,7 +22,7 @@ export interface IPanel extends IDisposable {
layout(width: number, height: number): void;
update(event: PanelUpdateEvent<Parameters>): void;
toJSON(): object;
focus(): void;
focus?(): void;
}
export interface IFrameworkPart extends IDisposable {

View File

@ -18,7 +18,7 @@ export class DefaultHeader
private readonly _expander: HTMLElement;
private apiRef: { api: PaneviewPanelApiImpl | null } = { api: null };
get element() {
get element(): HTMLElement {
return this._element;
}
@ -42,7 +42,7 @@ export class DefaultHeader
);
}
init(params: PanePanelInitParameter & { api: PaneviewPanelApiImpl }) {
init(params: PanePanelInitParameter & { api: PaneviewPanelApiImpl }): void {
this.apiRef.api = params.api;
this._content.textContent = params.title;
@ -54,7 +54,7 @@ export class DefaultHeader
});
}
private updateIcon() {
private updateIcon(): void {
const isExpanded = !!this.apiRef.api?.isExpanded;
toggleClass(this._expander, 'collapsed', !isExpanded);
@ -75,11 +75,11 @@ export class DefaultHeader
}
}
update(_params: PanelUpdateEvent) {
update(_params: PanelUpdateEvent): void {
//
}
dispose() {
dispose(): void {
this.disposable.dispose();
super.dispose();
}

View File

@ -45,7 +45,7 @@ export abstract class DraggablePaneviewPanel extends PaneviewPanel {
}
}
private initDragFeatures() {
private initDragFeatures(): void {
if (!this.header) {
return;
}
@ -110,7 +110,7 @@ export abstract class DraggablePaneviewPanel extends PaneviewPanel {
);
}
private onDrop(event: DroptargetEvent) {
private onDrop(event: DroptargetEvent): void {
const data = getPaneData();
if (!data || data.viewId !== this.accessor.id) {

View File

@ -25,30 +25,30 @@ export class Paneview extends CompositeDisposable implements IDisposable {
private readonly _onDidChange = new Emitter<void>();
readonly onDidChange: Event<void> = this._onDidChange.event;
get onDidAddView() {
get onDidAddView(): Event<PaneviewPanel> {
return <Event<PaneviewPanel>>this.splitview.onDidAddView;
}
get onDidRemoveView() {
get onDidRemoveView(): Event<PaneviewPanel> {
return <Event<PaneviewPanel>>this.splitview.onDidRemoveView;
}
get minimumSize() {
get minimumSize(): number {
return this.splitview.minimumSize;
}
get maximumSize() {
get maximumSize(): number {
return this.splitview.maximumSize;
}
get orientation() {
get orientation(): Orientation {
return this.splitview.orientation;
}
get size() {
get size(): number {
return this.splitview.size;
}
get orthogonalSize() {
get orthogonalSize(): number {
return this.splitview.orthogonalSize;
}
@ -113,7 +113,7 @@ export class Paneview extends CompositeDisposable implements IDisposable {
size?: number | Sizing,
index = this.splitview.length,
skipLayout = false
) {
): void {
const disposable = pane.onDidChangeExpansionState(() => {
this.setupAnimation();
this._onDidChange.fire(undefined);
@ -134,7 +134,7 @@ export class Paneview extends CompositeDisposable implements IDisposable {
this.splitview.addView(pane, size, index, skipLayout);
}
getViewSize(index: number) {
getViewSize(index: number): number {
return this.splitview.getViewSize(index);
}
@ -145,7 +145,7 @@ export class Paneview extends CompositeDisposable implements IDisposable {
public removePane(
index: number,
options: { skipDispose: boolean } = { skipDispose: false }
) {
): PaneItem {
const paneItem = this.paneItems.splice(index, 1)[0];
this.splitview.removeView(index);
@ -157,7 +157,7 @@ export class Paneview extends CompositeDisposable implements IDisposable {
return paneItem;
}
public moveView(from: number, to: number) {
public moveView(from: number, to: number): void {
if (from === to) {
return;
}
@ -176,7 +176,7 @@ export class Paneview extends CompositeDisposable implements IDisposable {
this.splitview.layout(size, orthogonalSize);
}
private setupAnimation() {
private setupAnimation(): void {
if (this.skipAnimation) {
return;
}
@ -194,7 +194,7 @@ export class Paneview extends CompositeDisposable implements IDisposable {
}, 200);
}
public dispose() {
public dispose(): void {
super.dispose();
if (this.animationTimer) {

View File

@ -175,25 +175,25 @@ export class PaneviewComponent
);
}
get paneview() {
get paneview(): Paneview {
return this._paneview;
}
get minimumSize() {
get minimumSize(): number {
return this.paneview.minimumSize;
}
get maximumSize() {
get maximumSize(): number {
return this.paneview.maximumSize;
}
get height() {
get height(): number {
return this.paneview.orientation === Orientation.HORIZONTAL
? this.paneview.orthogonalSize
: this.paneview.size;
}
get width() {
get width(): number {
return this.paneview.orientation === Orientation.HORIZONTAL
? this.paneview.size
: this.paneview.orthogonalSize;
@ -234,8 +234,8 @@ export class PaneviewComponent
this.addDisposables(this._disposable);
}
focus() {
//
focus(): void {
//noop
}
updateOptions(options: Partial<PaneviewComponentOptions>): void {
@ -311,7 +311,7 @@ export class PaneviewComponent
return view;
}
removePanel(panel: PaneviewPanel) {
removePanel(panel: PaneviewPanel): void {
const views = this.panels;
const index = views.findIndex((_) => _ === panel);
this.paneview.removePane(index);
@ -462,7 +462,7 @@ export class PaneviewComponent
this.paneview.dispose();
}
private doAddPanel(panel: PaneFramework) {
private doAddPanel(panel: PaneFramework): void {
const disposable = panel.onDidDrop((event) => {
this._onDidDrop.fire(event);
});
@ -470,7 +470,7 @@ export class PaneviewComponent
this._viewDisposables.set(panel.id, disposable);
}
private doRemovePanel(panel: PaneviewPanel) {
private doRemovePanel(panel: PaneviewPanel): void {
const disposable = this._viewDisposables.get(panel.id);
if (disposable) {

View File

@ -96,7 +96,7 @@ export abstract class PaneviewPanel
this._orientation = value;
}
get orientation() {
get orientation(): Orientation {
return this._orientation;
}
@ -116,11 +116,11 @@ export abstract class PaneviewPanel
return headerSize + maximumBodySize;
}
get size() {
get size(): number {
return this._size;
}
get orthogonalSize() {
get orthogonalSize(): number {
return this._orthogonalSize;
}
@ -128,7 +128,7 @@ export abstract class PaneviewPanel
this._orthogonalSize = size;
}
get minimumBodySize() {
get minimumBodySize(): number {
return this._minimumBodySize;
}
@ -136,7 +136,7 @@ export abstract class PaneviewPanel
this._minimumBodySize = typeof value === 'number' ? value : 0;
}
get maximumBodySize() {
get maximumBodySize(): number {
return this._maximumBodySize;
}
@ -217,11 +217,11 @@ export abstract class PaneviewPanel
this.renderOnce();
}
setVisible(isVisible: boolean) {
setVisible(isVisible: boolean): void {
this.api._onDidVisibilityChange.fire({ isVisible });
}
setActive(isActive: boolean) {
setActive(isActive: boolean): void {
this.api._onDidActiveChange.fire({ isActive });
}
@ -253,7 +253,7 @@ export abstract class PaneviewPanel
this._onDidChangeExpansionState.fire(expanded);
}
layout(size: number, orthogonalSize: number) {
layout(size: number, orthogonalSize: number): void {
this._size = size;
this._orthogonalSize = orthogonalSize;
const [width, height] =
@ -299,7 +299,7 @@ export abstract class PaneviewPanel
};
}
private renderOnce() {
private renderOnce(): void {
this.header = document.createElement('div');
this.header.tabIndex = 0;

View File

@ -105,6 +105,8 @@ export class Splitview {
private contentSize = 0;
private _proportions: number[] | undefined = undefined;
private proportionalLayout: boolean;
private _startSnappingEnabled = true;
private _endSnappingEnabled = true;
private readonly _onDidSashEnd = new Emitter<void>();
readonly onDidSashEnd = this._onDidSashEnd.event;
@ -113,7 +115,7 @@ export class Splitview {
private readonly _onDidRemoveView = new Emitter<IView>();
readonly onDidRemoveView = this._onDidRemoveView.event;
get size() {
get size(): number {
return this._size;
}
@ -121,7 +123,7 @@ export class Splitview {
this._size = value;
}
get orthogonalSize() {
get orthogonalSize(): number {
return this._orthogonalSize;
}
@ -129,15 +131,15 @@ export class Splitview {
this._orthogonalSize = value;
}
public get length() {
public get length(): number {
return this.views.length;
}
public get proportions() {
public get proportions(): number[] | undefined {
return this._proportions ? [...this._proportions] : undefined;
}
get orientation() {
get orientation(): Orientation {
return this._orientation;
}
@ -166,10 +168,10 @@ export class Splitview {
: this.views.reduce((r, item) => r + item.maximumSize, 0);
}
private _startSnappingEnabled = true;
get startSnappingEnabled(): boolean {
return this._startSnappingEnabled;
}
set startSnappingEnabled(startSnappingEnabled: boolean) {
if (this._startSnappingEnabled === startSnappingEnabled) {
return;
@ -179,10 +181,10 @@ export class Splitview {
this.updateSashEnablement();
}
private _endSnappingEnabled = true;
get endSnappingEnabled(): boolean {
return this._endSnappingEnabled;
}
set endSnappingEnabled(endSnappingEnabled: boolean) {
if (this._endSnappingEnabled === endSnappingEnabled) {
return;
@ -321,7 +323,7 @@ export class Splitview {
this.relayout(lowPriorityIndexes, highPriorityIndexes);
}
public getViews<T extends IView>() {
public getViews<T extends IView>(): T[] {
return this.views.map((x) => x.view as T);
}
@ -345,7 +347,7 @@ export class Splitview {
size: number | Sizing = { type: 'distribute' },
index: number = this.views.length,
skipLayout?: boolean
) {
): void {
const container = document.createElement('div');
container.className = 'view';
@ -622,7 +624,7 @@ export class Splitview {
return viewItem.cachedVisibleSize;
}
public moveView(from: number, to: number) {
public moveView(from: number, to: number): void {
const cachedVisibleSize = this.getViewCachedVisibleSize(from);
const sizing =
typeof cachedVisibleSize === 'undefined'
@ -632,7 +634,7 @@ export class Splitview {
this.addView(view, sizing, to);
}
public layout(size: number, orthogonalSize: number) {
public layout(size: number, orthogonalSize: number): void {
const previousSize = Math.max(this.size, this.contentSize);
this.size = size;
this.orthogonalSize = orthogonalSize;
@ -672,7 +674,7 @@ export class Splitview {
private relayout(
lowPriorityIndexes?: number[],
highPriorityIndexes?: number[]
) {
): void {
const contentSize = this.views.reduce((r, i) => r + i.size, 0);
this.resize(
@ -687,7 +689,7 @@ export class Splitview {
this.saveProportions();
}
private distributeEmptySpace(lowPriorityIndex?: number) {
private distributeEmptySpace(lowPriorityIndex?: number): void {
const contentSize = this.views.reduce((r, i) => r + i.size, 0);
let emptyDelta = this.size - contentSize;
@ -733,7 +735,7 @@ export class Splitview {
}
}
private layoutViews() {
private layoutViews(): void {
this.contentSize = this.views.reduce((r, i) => r + i.size, 0);
let sum = 0;
const x: number[] = [];
@ -875,7 +877,7 @@ export class Splitview {
}
}
private updateSash(sash: ISashItem, state: SashState) {
private updateSash(sash: ISashItem, state: SashState): void {
toggleClass(sash.container, 'disabled', state === SashState.DISABLED);
toggleClass(sash.container, 'enabled', state === SashState.ENABLED);
toggleClass(sash.container, 'maximum', state === SashState.MAXIMUM);
@ -1011,19 +1013,19 @@ export class Splitview {
return delta;
};
private createViewContainer() {
private createViewContainer(): HTMLElement {
const element = document.createElement('div');
element.className = 'view-container';
return element;
}
private createSashContainer() {
private createSashContainer(): HTMLElement {
const element = document.createElement('div');
element.className = 'sash-container';
return element;
}
private createContainer() {
private createContainer(): HTMLElement {
const element = document.createElement('div');
const orientationClassname =
this._orientation === Orientation.HORIZONTAL
@ -1033,7 +1035,7 @@ export class Splitview {
return element;
}
public dispose() {
public dispose(): void {
this._onDidSashEnd.dispose();
this._onDidAddView.dispose();
this._onDidRemoveView.dispose();

View File

@ -4,6 +4,8 @@ import { IView, LayoutPriority } from './splitview';
export class ViewItem {
private _size: number;
private _cachedVisibleSize: number | undefined = undefined;
set size(size: number) {
this._size = size;
}
@ -12,7 +14,6 @@ export class ViewItem {
return this._size;
}
private _cachedVisibleSize: number | undefined = undefined;
get cachedVisibleSize(): number | undefined {
return this._cachedVisibleSize;
}
@ -21,31 +22,6 @@ export class ViewItem {
return typeof this._cachedVisibleSize === 'undefined';
}
setVisible(visible: boolean, size?: number): void {
if (visible === this.visible) {
return;
}
if (visible) {
this.size = clamp(
this._cachedVisibleSize ?? 0,
this.viewMinimumSize,
this.viewMaximumSize
);
this._cachedVisibleSize = undefined;
} else {
this._cachedVisibleSize =
typeof size === 'number' ? size : this.size;
this.size = 0;
}
this.container.classList.toggle('visible', visible);
if (this.view.setVisible) {
this.view.setVisible(visible);
}
}
get minimumSize(): number {
return this.visible ? this.view.minimumSize : 0;
}
@ -87,12 +63,30 @@ export class ViewItem {
}
}
// layout(offset: number, layoutContext: TLayoutContext | undefined): void {
// this.layoutContainer(offset);
// this.view.layout(this.size, offset, layoutContext);
// }
setVisible(visible: boolean, size?: number): void {
if (visible === this.visible) {
return;
}
// abstract layoutContainer(offset: number): void;
if (visible) {
this.size = clamp(
this._cachedVisibleSize ?? 0,
this.viewMinimumSize,
this.viewMaximumSize
);
this._cachedVisibleSize = undefined;
} else {
this._cachedVisibleSize =
typeof size === 'number' ? size : this.size;
this.size = 0;
}
this.container.classList.toggle('visible', visible);
if (this.view.setVisible) {
this.view.setVisible(visible);
}
}
dispose(): IView {
this.disposable.dispose();

View File

@ -1,13 +1,11 @@
export interface Constructor<T> {
new (): T;
}
export interface FrameworkFactory<T> {
createComponent: (id: string, componentId: string, component: any) => T;
}
export type FunctionOrValue<T> = (() => T) | T;
export function isBooleanValue(value: any): value is boolean {
return typeof value === 'boolean';
}
export type FunctionOrValue<T> = (() => T) | T;
export type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;

View File

@ -1,26 +1,32 @@
import { GroupPanel, GroupviewPanelApi, Groupview } from 'dockview-core';
import {
DockviewGroupPanel,
DockviewGroupPanelApi,
DockviewGroupPanelModel,
} from 'dockview-core';
import { ReactGroupControlsRendererPart } from '../../../dockview/groupControlsRenderer';
describe('groupControlsRenderer', () => {
test('#1', () => {
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
return {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
onDidActivePanelChange: jest.fn(),
};
});
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
onDidActivePanelChange: jest.fn(),
};
}
);
const groupview = new groupviewMock() as Groupview;
const groupview = new groupviewMock() as DockviewGroupPanelModel;
const groupPanelMock = jest.fn<Partial<GroupPanel>, []>(() => {
const groupPanelMock = jest.fn<Partial<DockviewGroupPanel>, []>(() => {
return {
api: {} as GroupviewPanelApi as any,
api: {} as DockviewGroupPanelApi as any,
model: groupview,
};
});
const groupPanel = new groupPanelMock() as GroupPanel;
const groupPanel = new groupPanelMock() as DockviewGroupPanel;
const cut = new ReactGroupControlsRendererPart(
jest.fn(),

View File

@ -1,24 +0,0 @@
import { DEFAULT_TAB_IDENTIFIER } from 'dockview-core';
import { ReactPanelHeaderPart } from '../../../dockview/reactHeaderPart';
describe('reactHeaderPart', () => {
test('that tab id is present in toJSON when not the default tab', () => {
const cut = new ReactPanelHeaderPart(
'test-id',
jest.fn(),
<any>jest.fn()
);
expect(cut.toJSON()).toEqual({ id: 'test-id' });
});
test('that tab id is not present in the toJSON when is default tab', () => {
const cut = new ReactPanelHeaderPart(
DEFAULT_TAB_IDENTIFIER,
jest.fn(),
<any>jest.fn()
);
expect(cut.toJSON()).toEqual({});
});
});

View File

@ -10,8 +10,7 @@ import {
IContentRenderer,
ITabRenderer,
watchElementResize,
GroupPanel,
DEFAULT_TAB_IDENTIFIER,
DockviewGroupPanel,
DefaultDockviewDeserialzier,
} from 'dockview-core';
import { ReactPanelContentPart } from './reactContentPart';
@ -28,9 +27,9 @@ import {
function createGroupControlElement(
component: React.FunctionComponent<IDockviewGroupControlProps> | undefined,
store: ReactPortalStore
): ((groupPanel: GroupPanel) => IGroupControlRenderer) | undefined {
): ((groupPanel: DockviewGroupPanel) => IGroupControlRenderer) | undefined {
return component
? (groupPanel: GroupPanel) => {
? (groupPanel: DockviewGroupPanel) => {
return new ReactGroupControlsRendererPart(
component,
store,
@ -72,6 +71,8 @@ export interface IDockviewReactProps {
singleTabMode?: 'fullwidth' | 'default';
}
const DEFAULT_REACT_TAB = 'props.defaultTabComponent';
export const DockviewReact = React.forwardRef(
(props: IDockviewReactProps, ref: React.ForwardedRef<HTMLDivElement>) => {
const domRef = React.useRef<HTMLDivElement>(null);
@ -144,16 +145,22 @@ export const DockviewReact = React.forwardRef(
const element = document.createElement('div');
const frameworkTabComponents = props.tabComponents || {};
if (props.defaultTabComponent) {
frameworkTabComponents[DEFAULT_REACT_TAB] =
props.defaultTabComponent;
}
const dockview = new DockviewComponent(element, {
frameworkComponentFactory: factory,
frameworkComponents: props.components,
frameworkTabComponents: {
...(props.tabComponents || {}),
[DEFAULT_TAB_IDENTIFIER]: props.defaultTabComponent,
},
frameworkTabComponents,
tabHeight: props.tabHeight,
watermarkFrameworkComponent: props.watermarkComponent,
defaultTabComponent: DEFAULT_TAB_IDENTIFIER,
defaultTabComponent: props.defaultTabComponent
? DEFAULT_REACT_TAB
: undefined,
styles: props.hideBorders
? { separatorBorder: 'transparent' }
: undefined,
@ -241,12 +248,19 @@ export const DockviewReact = React.forwardRef(
if (!dockviewRef.current) {
return;
}
const frameworkTabComponents = props.tabComponents || {};
if (props.defaultTabComponent) {
frameworkTabComponents[DEFAULT_REACT_TAB] =
props.defaultTabComponent;
}
dockviewRef.current.updateOptions({
defaultTabComponent: DEFAULT_TAB_IDENTIFIER,
frameworkTabComponents: {
...(props.tabComponents || {}),
[DEFAULT_TAB_IDENTIFIER]: props.defaultTabComponent,
},
defaultTabComponent: props.defaultTabComponent
? DEFAULT_REACT_TAB
: undefined,
frameworkTabComponents,
});
}, [props.defaultTabComponent]);

View File

@ -5,13 +5,13 @@ import {
DockviewCompositeDisposable,
DockviewMutableDisposable,
DockviewApi,
GroupPanel,
GroupviewPanelApi,
DockviewGroupPanel,
DockviewGroupPanelApi,
PanelUpdateEvent,
} from 'dockview-core';
export interface IDockviewGroupControlProps {
api: GroupviewPanelApi;
api: DockviewGroupPanelApi;
containerApi: DockviewApi;
panels: IDockviewPanel[];
activePanel: IDockviewPanel | undefined;
@ -31,26 +31,26 @@ export class ReactGroupControlsRendererPart {
return this._part;
}
get group(): GroupPanel {
get group(): DockviewGroupPanel {
return this._group;
}
constructor(
private readonly component: React.FunctionComponent<IDockviewGroupControlProps>,
private readonly reactPortalStore: ReactPortalStore,
private readonly _group: GroupPanel
private readonly _group: DockviewGroupPanel
) {
this._element = document.createElement('div');
this._element.className = 'dockview-react-part';
}
focus() {
focus(): void {
// TODO
}
public init(parameters: {
containerApi: DockviewApi;
api: GroupviewPanelApi;
api: DockviewGroupPanelApi;
}): void {
this.mutableDisposable.value = new DockviewCompositeDisposable(
this._group.model.onDidAddPanel(() => {
@ -81,20 +81,20 @@ export class ReactGroupControlsRendererPart {
);
}
public update(event: PanelUpdateEvent) {
public update(event: PanelUpdateEvent): void {
this._part?.update(event.params);
}
public dispose() {
public dispose(): void {
this.mutableDisposable.dispose();
this._part?.dispose();
}
private updatePanels() {
private updatePanels(): void {
this.update({ params: { panels: this._group.model.panels } });
}
private updateActivePanel() {
private updateActivePanel(): void {
this.update({
params: {
activePanel: this._group.model.activePanel,
@ -102,7 +102,7 @@ export class ReactGroupControlsRendererPart {
});
}
private updateGroupActive() {
private updateGroupActive(): void {
this.update({
params: {
isGroupActive: this._group.api.isActive,

View File

@ -3,8 +3,8 @@ import { ReactPart, ReactPortalStore } from '../react';
import { IDockviewPanelProps } from '../dockview/dockview';
import {
DockviewEmitter,
Event,
GroupPanel,
DockviewEvent,
DockviewGroupPanel,
PanelUpdateEvent,
IContentRenderer,
GroupPanelContentPartInitParameters,
@ -14,13 +14,13 @@ export class ReactPanelContentPart implements IContentRenderer {
private _element: HTMLElement;
private part?: ReactPart<IDockviewPanelProps>;
//
private _group: GroupPanel | undefined;
private _group: DockviewGroupPanel | undefined;
private readonly _onDidFocus = new DockviewEmitter<void>();
readonly onDidFocus: Event<void> = this._onDidFocus.event;
readonly onDidFocus: DockviewEvent<void> = this._onDidFocus.event;
private readonly _onDidBlur = new DockviewEmitter<void>();
readonly onDidBlur: Event<void> = this._onDidBlur.event;
readonly onDidBlur: DockviewEvent<void> = this._onDidBlur.event;
get element(): HTMLElement {
return this._element;
@ -35,7 +35,7 @@ export class ReactPanelContentPart implements IContentRenderer {
this._element.className = 'dockview-react-part';
}
focus() {
focus(): void {
// TODO
}
@ -52,18 +52,12 @@ export class ReactPanelContentPart implements IContentRenderer {
);
}
public toJSON() {
return {
id: this.id,
};
}
public update(event: PanelUpdateEvent) {
this.part?.update(event.params);
}
public updateParentGroup(
group: GroupPanel,
group: DockviewGroupPanel,
_isPanelVisible: boolean
): void {
this._group = group;
@ -73,7 +67,7 @@ export class ReactPanelContentPart implements IContentRenderer {
// noop
}
public dispose() {
public dispose(): void {
this._onDidFocus.dispose();
this._onDidBlur.dispose();
this.part?.dispose();

View File

@ -2,9 +2,8 @@ import * as React from 'react';
import { ReactPart, ReactPortalStore } from '../react';
import { IGroupPanelBaseProps } from './dockview';
import {
DEFAULT_TAB_IDENTIFIER,
PanelUpdateEvent,
GroupPanel,
DockviewGroupPanel,
ITabRenderer,
GroupPanelPartInitParameters,
} from 'dockview-core';
@ -13,7 +12,7 @@ export class ReactPanelHeaderPart implements ITabRenderer {
private _element: HTMLElement;
private part?: ReactPart<IGroupPanelBaseProps>;
get element() {
get element(): HTMLElement {
return this._element;
}
@ -26,7 +25,7 @@ export class ReactPanelHeaderPart implements ITabRenderer {
this._element.className = 'dockview-react-part';
}
focus() {
focus(): void {
//noop
}
@ -43,32 +42,22 @@ export class ReactPanelHeaderPart implements ITabRenderer {
);
}
public update(event: PanelUpdateEvent) {
public update(event: PanelUpdateEvent): void {
this.part?.update(event.params);
}
public toJSON() {
if (this.id === DEFAULT_TAB_IDENTIFIER) {
return {};
}
return {
id: this.id,
};
}
public layout(_width: number, _height: number) {
public layout(_width: number, _height: number): void {
// noop - retrieval from api
}
public updateParentGroup(
_group: GroupPanel,
_group: DockviewGroupPanel,
_isPanelVisible: boolean
): void {
// noop - retrieval from api
}
public dispose() {
public dispose(): void {
this.part?.dispose();
}
}

View File

@ -3,7 +3,7 @@ import { ReactPart, ReactPortalStore } from '../react';
import { IGroupPanelBaseProps } from './dockview';
import {
PanelUpdateEvent,
GroupPanel,
DockviewGroupPanel,
GroupPanelPartInitParameters,
IWatermarkRenderer,
} from 'dockview-core';
@ -15,12 +15,12 @@ export interface IWatermarkPanelProps extends IGroupPanelBaseProps {
export class ReactWatermarkPart implements IWatermarkRenderer {
private _element: HTMLElement;
private part?: ReactPart<IWatermarkPanelProps>;
private _groupRef: { value: GroupPanel | undefined } = {
private _groupRef: { value: DockviewGroupPanel | undefined } = {
value: undefined,
};
private parameters: GroupPanelPartInitParameters | undefined;
get element() {
get element(): HTMLElement {
return this._element;
}
@ -55,11 +55,11 @@ export class ReactWatermarkPart implements IWatermarkRenderer {
);
}
focus() {
focus(): void {
// noop
}
update(params: PanelUpdateEvent) {
update(params: PanelUpdateEvent): void {
if (this.parameters) {
this.parameters.params = params.params;
}
@ -67,22 +67,19 @@ export class ReactWatermarkPart implements IWatermarkRenderer {
this.part?.update({ params: this.parameters?.params || {} });
}
toJSON() {
return {
id: this.id,
};
}
layout(_width: number, _height: number) {
layout(_width: number, _height: number): void {
// noop - retrieval from api
}
updateParentGroup(group: GroupPanel, _isPanelVisible: boolean): void {
updateParentGroup(
group: DockviewGroupPanel,
_isPanelVisible: boolean
): void {
// noop - retrieval from api
this._groupRef.value = group;
}
dispose() {
dispose(): void {
this.part?.dispose();
}
}

View File

@ -1,9 +1,10 @@
import {
GroupPanelPartInitParameters,
IContentRenderer,
GroupPanel,
DockviewGroupPanel,
HostedContainer,
PanelUpdateEvent,
DockviewEvent,
} from 'dockview-core';
import { ReactPart, ReactPortalStore } from '../../react';
import { IDockviewPanelProps } from '../dockview';
@ -13,7 +14,7 @@ export class ReactContentRenderer implements IContentRenderer {
private _element: HTMLElement;
private part?: ReactPart<IDockviewPanelProps>;
private _group: GroupPanel | undefined;
private _group: DockviewGroupPanel | undefined;
private parameters: GroupPanelPartInitParameters | undefined;
@ -21,11 +22,11 @@ export class ReactContentRenderer implements IContentRenderer {
return this._element;
}
get onDidBlur() {
get onDidBlur(): DockviewEvent<void> {
return this._hostedContainer.onDidBlur;
}
get onDidFocus() {
get onDidFocus(): DockviewEvent<void> {
return this._hostedContainer.onDidFocus;
}
@ -46,7 +47,7 @@ export class ReactContentRenderer implements IContentRenderer {
this._element.style.width = '100%';
}
focus() {
focus(): void {
// noop
}
@ -74,13 +75,7 @@ export class ReactContentRenderer implements IContentRenderer {
);
}
public toJSON() {
return {
id: this.id,
};
}
public update(params: PanelUpdateEvent) {
public update(params: PanelUpdateEvent): void {
if (this.parameters) {
this.parameters.params = params.params;
}
@ -89,7 +84,7 @@ export class ReactContentRenderer implements IContentRenderer {
}
public updateParentGroup(
group: GroupPanel,
group: DockviewGroupPanel,
_isPanelVisible: boolean
): void {
this._group = group;
@ -99,7 +94,7 @@ export class ReactContentRenderer implements IContentRenderer {
this._hostedContainer.layout(this.element);
}
public dispose() {
public dispose(): void {
this.part?.dispose();
}
}

View File

@ -1,7 +1,7 @@
import {
GroupPanelPartInitParameters,
IContentRenderer,
GroupPanel,
DockviewGroupPanel,
HostedContainer,
PanelUpdateEvent,
} from 'dockview-core';
@ -24,7 +24,7 @@ export class WebviewContentRenderer implements IContentRenderer {
this._element.style.width = '100%';
}
focus() {
focus(): void {
// noop
}
@ -32,18 +32,14 @@ export class WebviewContentRenderer implements IContentRenderer {
this.parameters = parameters;
}
public toJSON() {
return {};
}
public update(params: PanelUpdateEvent) {
public update(params: PanelUpdateEvent): void {
if (this.parameters) {
this.parameters.params = params.params;
}
}
public updateParentGroup(
_group: GroupPanel,
_group: DockviewGroupPanel,
_isPanelVisible: boolean
): void {
//
@ -53,7 +49,7 @@ export class WebviewContentRenderer implements IContentRenderer {
this._hostedContainer.layout(this._element);
}
public dispose() {
public dispose(): void {
//
}
}