Skip to content

Commit

Permalink
work-in-progress: popout windows
Browse files Browse the repository at this point in the history
  • Loading branch information
mathuo committed Oct 20, 2023
1 parent e3ed425 commit 622e380
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 2 deletions.
4 changes: 4 additions & 0 deletions packages/dockview-core/src/api/component.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -804,4 +804,8 @@ export class DockviewApi implements CommonApi<SerializedDockview> {
moveToPrevious(options?: MovementOptions): void {
this.component.moveToPrevious(options);
}

toggleNewWindow(panel: IDockviewPanel): void {
this.component.toggleNewWindow(panel);
}
}
18 changes: 18 additions & 0 deletions packages/dockview-core/src/dockview/components/tab/defaultTab.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@
.tab {
flex-shrink: 0;

&:focus-within,
&:focus {
position: relative;

&::after {
position: absolute;
content: '';
height: 100%;
width: 100%;
top: 0px;
left: 0px;
pointer-events: none;
outline: 1px solid var(--dv-tab-divider-color) !important;
outline-offset: -1px;
z-index: 5;
}
}

&.dv-tab-dragging {
.tab-action {
background-color: var(--dv-activegroup-visiblepanel-tab-color);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class VoidContainer extends CompositeDisposable {
this._element = document.createElement('div');

this._element.className = 'void-container';
this._element.tabIndex = 0;
this._element.tabIndex = -1;
this._element.draggable = true;

this.addDisposables(
Expand Down
20 changes: 19 additions & 1 deletion packages/dockview-core/src/dockview/dockviewComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ import {
GroupDragEvent,
TabDragEvent,
} from './components/titlebar/tabsContainer';
import { DockviewGroupPanelApi } from '../api/dockviewGroupPanelApi';
import { ExternalWindow } from '../externalWindow';

const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100;

Expand Down Expand Up @@ -234,6 +234,7 @@ export interface IDockviewComponent extends IBaseGrid<DockviewGroupPanel> {
item: IDockviewPanel | DockviewGroupPanel,
coord?: { x: number; y: number }
): void;
toggleNewWindow(panel: IDockviewPanel): void;
}

export class DockviewComponent
Expand Down Expand Up @@ -427,6 +428,23 @@ export class DockviewComponent
this.updateWatermark();
}

toggleNewWindow(panel: IDockviewPanel): void {
const { height, width, top, left } =
panel.group.element.getBoundingClientRect();

const { top: boundingTop, left: boundingLeft } =
this.element.getBoundingClientRect();

const window = new ExternalWindow('test', 'dockview-theme-abyss', {
url: 'popout.html',
left,
top,
width,
height,
});
window.open(panel.group.element);
}

addFloatingGroup(
item: DockviewPanel | DockviewGroupPanel,
coord?: { x?: number; y?: number; height?: number; width?: number },
Expand Down
101 changes: 101 additions & 0 deletions packages/dockview-core/src/externalWindow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
export class ExternalWindow {
constructor(
private readonly id: string,
private readonly className: string,
private readonly options: {
url: string;
top: number;
left: number;
width: number;
height: number;
}
) {
//
}

open(content: HTMLElement): void {
const url = `${this.options.url}`;
const externalWindow = window.open(
'popout.html',
this.id,
`top=${this.options.top},left=${this.options.left},width=${this.options.width},height=${this.options.height}`
);

if (!externalWindow) {
return;
}

const grievingParent = content.parentElement;

if (!grievingParent) {
return;
}

const cleanUp = () => {
grievingParent.appendChild(content);
};

// prevent any default content from loading
externalWindow.document.body.replaceWith(document.createElement('div'));

window.addEventListener('beforeunload', () => {
cleanUp();
externalWindow.close();
});

externalWindow.addEventListener('load', () => {
const externalDocument = externalWindow.document;
externalDocument.title = 'test';

const div = document.createElement('div');
div.style.position = 'absolute';
div.style.width = '100%';
div.style.height = '100%';
div.style.top = '0px';
div.style.left = '0px';
div.appendChild(content);

externalDocument.body.replaceChildren(div);
externalDocument.body.classList.add(this.className);

addStyles(externalDocument, window.document.styleSheets);

externalWindow.addEventListener('beforeunload', () => {
// TODO: indicate external window is closing
cleanUp();
});
});
}
}

function addStyles(document: Document, styleSheetList: StyleSheetList) {
const styleSheets = Array.from(styleSheetList);

for (const styleSheet of styleSheets) {
if (styleSheet.href) {
const link = document.createElement('link');
link.href = styleSheet.href;
link.type = styleSheet.type;
link.rel = 'stylesheet';
document.head.appendChild(link);
}

let cssTexts: string[] = [];

try {
if (styleSheet.cssRules) {
cssTexts = Array.from(styleSheet.cssRules).map(
(rule) => rule.cssText
);
}
} catch (er) {
//
}

for (const rule of cssTexts) {
const style = document.createElement('style');
style.appendChild(document.createTextNode(rule));
document.head.appendChild(style);
}
}
}
5 changes: 5 additions & 0 deletions packages/docs/sandboxes/demo-dockview/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@ const LeftControls = (props: IDockviewHeaderActionsProps) => {
const PrefixHeaderControls = (props: IDockviewHeaderActionsProps) => {
return (
<div
onClick={() => {
if (props.activePanel) {
props.containerApi.toggleNewWindow(props.activePanel);
}
}}
className="group-control"
style={{
display: 'flex',
Expand Down

0 comments on commit 622e380

Please sign in to comment.