mirror of
https://github.com/mathuo/dockview
synced 2025-01-22 17:35:57 +00:00
feat: popout group enhancements
This commit is contained in:
parent
c2791c6124
commit
0bca63b550
@ -62,16 +62,19 @@ describe('contentContainer', () => {
|
||||
|
||||
const disposable = new CompositeDisposable();
|
||||
|
||||
const dockviewComponent = jest.fn<DockviewComponent, []>(() => {
|
||||
return {
|
||||
renderer: 'onlyWhenVisibile',
|
||||
overlayRenderContainer: new OverlayRenderContainer(
|
||||
const overlayRenderContainer = new OverlayRenderContainer(
|
||||
document.createElement('div')
|
||||
),
|
||||
} as DockviewComponent;
|
||||
});
|
||||
);
|
||||
|
||||
const cut = new ContentContainer(dockviewComponent(), jest.fn() as any);
|
||||
const cut = new ContentContainer(
|
||||
fromPartial<DockviewComponent>({
|
||||
renderer: 'onlyWhenVisibile',
|
||||
overlayRenderContainer,
|
||||
}),
|
||||
fromPartial<DockviewGroupPanelModel>({
|
||||
renderContainer: overlayRenderContainer,
|
||||
})
|
||||
);
|
||||
|
||||
disposable.addDisposables(
|
||||
cut.onDidFocus(() => {
|
||||
@ -84,12 +87,12 @@ describe('contentContainer', () => {
|
||||
|
||||
const contentRenderer = new TestContentRenderer('id-1');
|
||||
|
||||
const panel = {
|
||||
const panel = fromPartial<IDockviewPanel>({
|
||||
view: {
|
||||
content: contentRenderer,
|
||||
} as Partial<IDockviewPanelModel>,
|
||||
},
|
||||
api: { renderer: 'onlyWhenVisibile' },
|
||||
} as Partial<IDockviewPanel>;
|
||||
});
|
||||
|
||||
cut.openPanel(panel as IDockviewPanel);
|
||||
|
||||
@ -151,13 +154,17 @@ describe('contentContainer', () => {
|
||||
});
|
||||
|
||||
test("that panels renderered as 'onlyWhenVisibile' are removed when closed", () => {
|
||||
const overlayRenderContainer = fromPartial<OverlayRenderContainer>({
|
||||
detatch: jest.fn(),
|
||||
});
|
||||
|
||||
const cut = new ContentContainer(
|
||||
fromPartial<DockviewComponent>({
|
||||
overlayRenderContainer: {
|
||||
detatch: jest.fn(),
|
||||
},
|
||||
overlayRenderContainer,
|
||||
}),
|
||||
fromPartial<DockviewGroupPanelModel>({})
|
||||
fromPartial<DockviewGroupPanelModel>({
|
||||
renderContainer: overlayRenderContainer,
|
||||
})
|
||||
);
|
||||
|
||||
const panel1 = fromPartial<IDockviewPanel>({
|
||||
|
@ -4434,44 +4434,12 @@ describe('dockviewComponent', () => {
|
||||
cb();
|
||||
}
|
||||
}),
|
||||
removeEventListener: jest.fn(),
|
||||
close: jest.fn(),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
test('that can remove a popout group', async () => {
|
||||
const container = document.createElement('div');
|
||||
|
||||
const dockview = new DockviewComponent({
|
||||
parentElement: container,
|
||||
components: {
|
||||
default: PanelContentPartTest,
|
||||
},
|
||||
tabComponents: {
|
||||
test_tab_id: PanelTabPartTest,
|
||||
},
|
||||
orientation: Orientation.HORIZONTAL,
|
||||
});
|
||||
|
||||
dockview.layout(1000, 500);
|
||||
|
||||
const panel1 = dockview.addPanel({
|
||||
id: 'panel_1',
|
||||
component: 'default',
|
||||
});
|
||||
|
||||
await dockview.addPopoutGroup(panel1);
|
||||
|
||||
expect(dockview.panels.length).toBe(1);
|
||||
expect(dockview.groups.length).toBe(2);
|
||||
expect(panel1.api.group.api.location.type).toBe('popout');
|
||||
|
||||
dockview.removePanel(panel1);
|
||||
|
||||
expect(dockview.panels.length).toBe(0);
|
||||
expect(dockview.groups.length).toBe(0);
|
||||
});
|
||||
|
||||
test('add a popout group', async () => {
|
||||
const container = document.createElement('div');
|
||||
|
||||
@ -4511,6 +4479,39 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.panels.length).toBe(2);
|
||||
});
|
||||
|
||||
test('that can remove a popout group', async () => {
|
||||
const container = document.createElement('div');
|
||||
|
||||
const dockview = new DockviewComponent({
|
||||
parentElement: container,
|
||||
components: {
|
||||
default: PanelContentPartTest,
|
||||
},
|
||||
tabComponents: {
|
||||
test_tab_id: PanelTabPartTest,
|
||||
},
|
||||
orientation: Orientation.HORIZONTAL,
|
||||
});
|
||||
|
||||
dockview.layout(1000, 500);
|
||||
|
||||
const panel1 = dockview.addPanel({
|
||||
id: 'panel_1',
|
||||
component: 'default',
|
||||
});
|
||||
|
||||
await dockview.addPopoutGroup(panel1);
|
||||
|
||||
expect(dockview.panels.length).toBe(1);
|
||||
expect(dockview.groups.length).toBe(2);
|
||||
expect(panel1.api.group.api.location.type).toBe('popout');
|
||||
|
||||
dockview.removePanel(panel1);
|
||||
|
||||
expect(dockview.panels.length).toBe(0);
|
||||
expect(dockview.groups.length).toBe(0);
|
||||
});
|
||||
|
||||
test('move from fixed to popout group and back', async () => {
|
||||
const container = document.createElement('div');
|
||||
|
||||
|
@ -133,7 +133,7 @@ export class ContentContainer
|
||||
|
||||
switch (panel.api.renderer) {
|
||||
case 'onlyWhenVisibile':
|
||||
this.accessor.overlayRenderContainer.detatch(panel);
|
||||
this.group.renderContainer.detatch(panel);
|
||||
if (this.panel) {
|
||||
if (doRender) {
|
||||
this._element.appendChild(
|
||||
@ -149,7 +149,7 @@ export class ContentContainer
|
||||
) {
|
||||
this._element.removeChild(panel.view.content.element);
|
||||
}
|
||||
container = this.accessor.overlayRenderContainer.attach({
|
||||
container = this.group.renderContainer.attach({
|
||||
panel,
|
||||
referenceContainer: this,
|
||||
});
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
import { tail, sequenceEquals, remove } from '../array';
|
||||
import { DockviewPanel, IDockviewPanel } from './dockviewPanel';
|
||||
import { CompositeDisposable, Disposable, IDisposable } from '../lifecycle';
|
||||
import { Event, Emitter } from '../events';
|
||||
import { Event, Emitter, addDisposableWindowListener } from '../events';
|
||||
import { Watermark } from './components/watermark/watermark';
|
||||
import { IWatermarkRenderer, GroupviewPanelState } from './types';
|
||||
import { sequentialNumberGenerator } from '../math';
|
||||
@ -561,12 +561,15 @@ export class DockviewComponent
|
||||
from: DockviewGroupPanel;
|
||||
to: DockviewGroupPanel;
|
||||
}) {
|
||||
const activePanel = options.from.activePanel;
|
||||
const panels = [...options.from.panels].map((panel) =>
|
||||
options.from.model.removePanel(panel)
|
||||
);
|
||||
|
||||
panels.forEach((panel) => {
|
||||
options.to.model.openPanel(panel);
|
||||
options.to.model.openPanel(panel, {
|
||||
skipSetPanelActive: activePanel !== panel,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -624,10 +627,18 @@ export class DockviewComponent
|
||||
return;
|
||||
}
|
||||
|
||||
const gready = document.createElement('div');
|
||||
gready.className = 'dv-overlay-render-container';
|
||||
|
||||
const overlayRenderContainer = new OverlayRenderContainer(
|
||||
gready
|
||||
);
|
||||
|
||||
const referenceGroup =
|
||||
item instanceof DockviewPanel ? item.group : item;
|
||||
|
||||
const group = this.createGroup({ id: groupId });
|
||||
group.model.renderContainer = overlayRenderContainer;
|
||||
|
||||
if (item instanceof DockviewPanel) {
|
||||
const panel = referenceGroup.model.removePanel(item);
|
||||
@ -637,9 +648,13 @@ export class DockviewComponent
|
||||
from: referenceGroup,
|
||||
to: group,
|
||||
});
|
||||
referenceGroup.api.setHidden(false);
|
||||
referenceGroup.api.setHidden(true);
|
||||
}
|
||||
|
||||
popoutContainer.classList.add('dv-dockview');
|
||||
popoutContainer.style.overflow = 'hidden';
|
||||
popoutContainer.appendChild(gready);
|
||||
|
||||
popoutContainer.appendChild(group.element);
|
||||
|
||||
group.model.location = {
|
||||
@ -655,6 +670,19 @@ export class DockviewComponent
|
||||
};
|
||||
|
||||
popoutWindowDisposable.addDisposables(
|
||||
/**
|
||||
* ResizeObserver seems slow here, I do not know why but we don't need it
|
||||
* since we can reply on the window resize event as we will occupy the full
|
||||
* window dimensions
|
||||
*/
|
||||
addDisposableWindowListener(
|
||||
_window.window!,
|
||||
'resize',
|
||||
() => {
|
||||
group.layout(window.innerWidth, window.innerHeight);
|
||||
}
|
||||
),
|
||||
overlayRenderContainer,
|
||||
Disposable.from(() => {
|
||||
if (this.getPanel(referenceGroup.id)) {
|
||||
moveGroupWithoutDestroying({
|
||||
@ -666,12 +694,16 @@ export class DockviewComponent
|
||||
referenceGroup.api.setHidden(false);
|
||||
}
|
||||
|
||||
this.doRemoveGroup(group);
|
||||
this.doRemoveGroup(group, {
|
||||
skipPopoutAssociated: true,
|
||||
});
|
||||
} else {
|
||||
const removedGroup = this.doRemoveGroup(group, {
|
||||
skipDispose: true,
|
||||
skipActive: true,
|
||||
});
|
||||
removedGroup.model.renderContainer =
|
||||
this.overlayRenderContainer;
|
||||
removedGroup.model.location = { type: 'grid' };
|
||||
this.doAddGroup(removedGroup, [0]);
|
||||
}
|
||||
@ -1484,6 +1516,7 @@ export class DockviewComponent
|
||||
| {
|
||||
skipActive?: boolean;
|
||||
skipDispose?: boolean;
|
||||
skipPopoutAssociated?: boolean;
|
||||
}
|
||||
| undefined
|
||||
): DockviewGroupPanel {
|
||||
@ -1523,7 +1556,9 @@ export class DockviewComponent
|
||||
|
||||
if (selectedGroup) {
|
||||
if (!options?.skipDispose) {
|
||||
this.doRemoveGroup(selectedGroup.referenceGroup);
|
||||
if (!options?.skipPopoutAssociated) {
|
||||
this.removeGroup(selectedGroup.referenceGroup);
|
||||
}
|
||||
|
||||
selectedGroup.popoutGroup.dispose();
|
||||
this._groups.delete(group.id);
|
||||
|
@ -26,6 +26,7 @@ import { DockviewDropTargets, IWatermarkRenderer } from './types';
|
||||
import { DockviewGroupPanel } from './dockviewGroupPanel';
|
||||
import { IDockviewPanel } from './dockviewPanel';
|
||||
import { IHeaderActionsRenderer } from './options';
|
||||
import { OverlayRenderContainer } from '../overlayRenderContainer';
|
||||
|
||||
interface GroupMoveEvent {
|
||||
groupId: string;
|
||||
@ -421,6 +422,27 @@ export class DockviewGroupPanelModel
|
||||
);
|
||||
}
|
||||
|
||||
private _overwriteRenderContainer: OverlayRenderContainer | null = null;
|
||||
|
||||
set renderContainer(value: OverlayRenderContainer | null) {
|
||||
this.panels.forEach((panel) => {
|
||||
this.renderContainer.detatch(panel);
|
||||
});
|
||||
|
||||
this._overwriteRenderContainer = value;
|
||||
|
||||
this.panels.forEach((panel) => {
|
||||
this.rerender(panel);
|
||||
});
|
||||
}
|
||||
|
||||
get renderContainer(): OverlayRenderContainer {
|
||||
return (
|
||||
this._overwriteRenderContainer ??
|
||||
this.accessor.overlayRenderContainer
|
||||
);
|
||||
}
|
||||
|
||||
initialize(): void {
|
||||
if (this.options.panels) {
|
||||
this.options.panels.forEach((panel) => {
|
||||
|
Loading…
Reference in New Issue
Block a user