mirror of
https://github.com/mathuo/dockview
synced 2025-09-11 11:47:54 +00:00
feat: render mode
This commit is contained in:
parent
e686ecb9d5
commit
d0d6508ae3
@ -178,58 +178,7 @@ export class ContentContainer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderer = panel.api.renderer;
|
this.renderPanel(panel);
|
||||||
|
|
||||||
if (
|
|
||||||
this.panel &&
|
|
||||||
this.panel.view.content.element.parentElement === this._element
|
|
||||||
) {
|
|
||||||
/**
|
|
||||||
* If the currently attached panel is mounted directly to the content then remove it
|
|
||||||
*/
|
|
||||||
this._element.removeChild(this.panel.view.content.element);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.panel = panel;
|
|
||||||
|
|
||||||
let container: HTMLElement;
|
|
||||||
|
|
||||||
switch (renderer) {
|
|
||||||
case 'always':
|
|
||||||
container =
|
|
||||||
this.accessor.overlayRenderContainer.setReferenceContentContainer(
|
|
||||||
panel,
|
|
||||||
this
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 'onlyWhenVisibile':
|
|
||||||
this._element.appendChild(this.panel.view.content.element);
|
|
||||||
container = this._element;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const _onDidFocus = this.panel.view.content.onDidFocus;
|
|
||||||
const _onDidBlur = this.panel.view.content.onDidBlur;
|
|
||||||
|
|
||||||
const disposable = new CompositeDisposable();
|
|
||||||
const focusTracker = trackFocus(container);
|
|
||||||
|
|
||||||
disposable.addDisposables(
|
|
||||||
focusTracker,
|
|
||||||
focusTracker.onDidFocus(() => this._onDidFocus.fire()),
|
|
||||||
focusTracker.onDidBlur(() => this._onDidBlur.fire())
|
|
||||||
);
|
|
||||||
|
|
||||||
if (_onDidFocus) {
|
|
||||||
disposable.addDisposables(
|
|
||||||
_onDidFocus(() => this._onDidFocus.fire())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (_onDidBlur) {
|
|
||||||
disposable.addDisposables(_onDidBlur(() => this._onDidBlur.fire()));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.disposable.value = disposable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public layout(_width: number, _height: number): void {
|
public layout(_width: number, _height: number): void {
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
import { DragAndDropObserver } from './dnd/dnd';
|
import { DragAndDropObserver } from './dnd/dnd';
|
||||||
import { Droptarget } from './dnd/droptarget';
|
import { Droptarget } from './dnd/droptarget';
|
||||||
import { getDomNodePagePosition, toggleClass } from './dom';
|
import { getDomNodePagePosition, toggleClass } from './dom';
|
||||||
import { CompositeDisposable, Disposable, IDisposable } from './lifecycle';
|
import {
|
||||||
|
CompositeDisposable,
|
||||||
|
Disposable,
|
||||||
|
IDisposable,
|
||||||
|
MutableDisposable,
|
||||||
|
} from './lifecycle';
|
||||||
import { IDockviewPanel } from './dockview/dockviewPanel';
|
import { IDockviewPanel } from './dockview/dockviewPanel';
|
||||||
|
|
||||||
export type DockviewPanelRenderer = 'onlyWhenVisibile' | 'always';
|
export type DockviewPanelRenderer = 'onlyWhenVisibile' | 'always';
|
||||||
@ -20,7 +25,12 @@ function createFocusableElement(): HTMLDivElement {
|
|||||||
export class OverlayRenderContainer extends CompositeDisposable {
|
export class OverlayRenderContainer extends CompositeDisposable {
|
||||||
private readonly map: Record<
|
private readonly map: Record<
|
||||||
string,
|
string,
|
||||||
{ disposable: IDisposable; element: HTMLElement }
|
{
|
||||||
|
panel: IDockviewPanel;
|
||||||
|
disposable: IDisposable;
|
||||||
|
destroy: IDisposable;
|
||||||
|
element: HTMLElement;
|
||||||
|
}
|
||||||
> = {};
|
> = {};
|
||||||
|
|
||||||
get allIds(): string[] {
|
get allIds(): string[] {
|
||||||
@ -30,13 +40,14 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
|||||||
constructor(private readonly element: HTMLElement) {
|
constructor(private readonly element: HTMLElement) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.addDisposables({
|
this.addDisposables(
|
||||||
dispose: () => {
|
Disposable.from(() => {
|
||||||
for (const value of Object.values(this.map)) {
|
for (const value of Object.values(this.map)) {
|
||||||
value.disposable.dispose();
|
value.disposable.dispose();
|
||||||
|
value.destroy.dispose();
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(panel: IDockviewPanel): boolean {
|
remove(panel: IDockviewPanel): boolean {
|
||||||
@ -57,12 +68,14 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
|||||||
element.className = 'dv-render-overlay';
|
element.className = 'dv-render-overlay';
|
||||||
|
|
||||||
this.map[panel.api.id] = {
|
this.map[panel.api.id] = {
|
||||||
|
panel,
|
||||||
disposable: Disposable.NONE,
|
disposable: Disposable.NONE,
|
||||||
|
destroy: Disposable.NONE,
|
||||||
|
|
||||||
element,
|
element,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
this.map[panel.api.id]?.disposable.dispose();
|
|
||||||
const focusContainer = this.map[panel.api.id].element;
|
const focusContainer = this.map[panel.api.id].element;
|
||||||
|
|
||||||
if (panel.view.content.element.parentElement !== focusContainer) {
|
if (panel.view.content.element.parentElement !== focusContainer) {
|
||||||
@ -97,11 +110,17 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
|||||||
focusContainer.style.display = panel.api.isVisible ? '' : 'none';
|
focusContainer.style.display = panel.api.isVisible ? '' : 'none';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const whenVisible = <T>(func: (event: T) => void) => {
|
||||||
|
return (event: T) => {
|
||||||
|
if (!panel.api.isVisible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
func(event);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const disposable = new CompositeDisposable(
|
const disposable = new CompositeDisposable(
|
||||||
/**
|
|
||||||
* since container is positioned absoutely we must explicitly forward
|
|
||||||
* the dnd events for the expect behaviours to continue to occur in terms of dnd
|
|
||||||
*/
|
|
||||||
new DragAndDropObserver(focusContainer, {
|
new DragAndDropObserver(focusContainer, {
|
||||||
onDragEnd: (e) => {
|
onDragEnd: (e) => {
|
||||||
referenceContainer.dropTarget.dnd.onDragEnd(e);
|
referenceContainer.dropTarget.dnd.onDragEnd(e);
|
||||||
@ -119,6 +138,10 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
|||||||
referenceContainer.dropTarget.dnd.onDragOver(e);
|
referenceContainer.dropTarget.dnd.onDragOver(e);
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
/**
|
||||||
|
* since container is positioned absoutely we must explicitly forward
|
||||||
|
* the dnd events for the expect behaviours to continue to occur in terms of dnd
|
||||||
|
*/
|
||||||
panel.api.onDidVisibilityChange((event) => {
|
panel.api.onDidVisibilityChange((event) => {
|
||||||
/**
|
/**
|
||||||
* Control the visibility of the content, however even when not visible (display: none)
|
* Control the visibility of the content, however even when not visible (display: none)
|
||||||
@ -133,14 +156,13 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resize();
|
resize();
|
||||||
}),
|
})
|
||||||
{
|
);
|
||||||
dispose: () => {
|
|
||||||
|
this.map[panel.api.id].destroy = Disposable.from(() => {
|
||||||
focusContainer.removeChild(panel.view.content.element);
|
focusContainer.removeChild(panel.view.content.element);
|
||||||
this.element.removeChild(focusContainer);
|
this.element.removeChild(focusContainer);
|
||||||
},
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
queueMicrotask(() => {
|
queueMicrotask(() => {
|
||||||
if (this.isDisposed) {
|
if (this.isDisposed) {
|
||||||
@ -155,6 +177,7 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
|||||||
visibilityChanged();
|
visibilityChanged();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.map[panel.api.id].disposable.dispose();
|
||||||
this.map[panel.api.id].disposable = disposable;
|
this.map[panel.api.id].disposable = disposable;
|
||||||
|
|
||||||
return focusContainer;
|
return focusContainer;
|
||||||
|
@ -7,21 +7,26 @@ import * as React from 'react';
|
|||||||
import { HoistedDockviewPanel } from './hoistedDockviewPanel';
|
import { HoistedDockviewPanel } from './hoistedDockviewPanel';
|
||||||
|
|
||||||
const components = {
|
const components = {
|
||||||
iframeComponent: HoistedDockviewPanel(
|
iframeComponent: (props: IDockviewPanelProps<{ color: string }>) => {
|
||||||
(props: IDockviewPanelProps<{ color: string }>) => {
|
return (
|
||||||
|
<div style={{ height: '100%', overflow: 'auto' }}>
|
||||||
|
<div style={{ height: '1000px', color: 'white' }}>
|
||||||
|
{props.api.title}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<iframe
|
<iframe
|
||||||
style={{
|
style={{
|
||||||
pointerEvents: 'none',
|
// pointerEvents: 'none',
|
||||||
border: 'none',
|
// border: 'none',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
}}
|
}}
|
||||||
src="https://dockview.dev"
|
src="https://dockview.dev"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
),
|
|
||||||
basicComponent: () => {
|
basicComponent: () => {
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: '20px', color: 'white' }}>
|
<div style={{ padding: '20px', color: 'white' }}>
|
||||||
@ -36,11 +41,13 @@ export const App: React.FC = (props: { theme?: string }) => {
|
|||||||
event.api.addPanel({
|
event.api.addPanel({
|
||||||
id: 'panel_1',
|
id: 'panel_1',
|
||||||
component: 'iframeComponent',
|
component: 'iframeComponent',
|
||||||
|
renderer: 'always',
|
||||||
});
|
});
|
||||||
|
|
||||||
event.api.addPanel({
|
event.api.addPanel({
|
||||||
id: 'panel_2',
|
id: 'panel_2',
|
||||||
component: 'iframeComponent',
|
component: 'iframeComponent',
|
||||||
|
renderer: 'always',
|
||||||
});
|
});
|
||||||
|
|
||||||
event.api.addPanel({
|
event.api.addPanel({
|
||||||
|
Loading…
x
Reference in New Issue
Block a user