mirror of
https://github.com/mathuo/dockview
synced 2025-02-02 14:35:46 +00:00
Merge branch 'master' of https://github.com/mathuo/dockview into 687-css-class-prefixing
This commit is contained in:
commit
c086cabd39
@ -2,7 +2,7 @@
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "1.16.1",
|
||||
"version": "1.17.2",
|
||||
"npmClient": "yarn",
|
||||
"command": {
|
||||
"publish": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dockview-angular",
|
||||
"version": "1.16.1",
|
||||
"version": "1.17.2",
|
||||
"description": "Zero dependency layout manager supporting tabs, grids and splitviews",
|
||||
"keywords": [
|
||||
"splitview",
|
||||
@ -54,6 +54,6 @@
|
||||
"test:cov": "cross-env ../../node_modules/.bin/jest --selectProjects dockview --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"dockview-core": "^1.16.1"
|
||||
"dockview-core": "^1.17.2"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dockview-core",
|
||||
"version": "1.16.1",
|
||||
"version": "1.17.2",
|
||||
"description": "Zero dependency layout manager supporting tabs, grids and splitviews",
|
||||
"keywords": [
|
||||
"splitview",
|
||||
|
@ -54,7 +54,7 @@ describe('defaultTab', () => {
|
||||
|
||||
let el = cut.element.querySelector('.dv-default-tab-action');
|
||||
|
||||
fireEvent.mouseDown(el!);
|
||||
fireEvent.pointerDown(el!);
|
||||
expect(api.close).toHaveBeenCalledTimes(0);
|
||||
|
||||
fireEvent.click(el!);
|
||||
|
@ -459,6 +459,7 @@ describe('tabsContainer', () => {
|
||||
onDidRemovePanel: jest.fn(),
|
||||
element: document.createElement('div'),
|
||||
addFloatingGroup: jest.fn(),
|
||||
doSetGroupActive: jest.fn(),
|
||||
});
|
||||
|
||||
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
|
||||
@ -486,10 +487,11 @@ describe('tabsContainer', () => {
|
||||
return { top: 10, left: 20, width: 0, height: 0 } as any;
|
||||
});
|
||||
|
||||
const event = new KeyboardEvent('mousedown', { shiftKey: true });
|
||||
const event = new KeyboardEvent('pointerdown', { shiftKey: true });
|
||||
const eventPreventDefaultSpy = jest.spyOn(event, 'preventDefault');
|
||||
fireEvent(container, event);
|
||||
|
||||
expect(accessor.doSetGroupActive).toHaveBeenCalledWith(groupPanel);
|
||||
expect(accessor.addFloatingGroup).toHaveBeenCalledWith(groupPanel, {
|
||||
x: 100,
|
||||
y: 60,
|
||||
@ -498,7 +500,7 @@ describe('tabsContainer', () => {
|
||||
expect(accessor.addFloatingGroup).toHaveBeenCalledTimes(1);
|
||||
expect(eventPreventDefaultSpy).toHaveBeenCalledTimes(1);
|
||||
|
||||
const event2 = new KeyboardEvent('mousedown', { shiftKey: false });
|
||||
const event2 = new KeyboardEvent('pointerdown', { shiftKey: false });
|
||||
const eventPreventDefaultSpy2 = jest.spyOn(event2, 'preventDefault');
|
||||
fireEvent(container, event2);
|
||||
|
||||
@ -513,6 +515,7 @@ describe('tabsContainer', () => {
|
||||
onDidRemovePanel: jest.fn(),
|
||||
element: document.createElement('div'),
|
||||
addFloatingGroup: jest.fn(),
|
||||
doSetGroupActive: jest.fn(),
|
||||
});
|
||||
|
||||
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
|
||||
@ -540,14 +543,15 @@ describe('tabsContainer', () => {
|
||||
return { top: 10, left: 20, width: 0, height: 0 } as any;
|
||||
});
|
||||
|
||||
const event = new KeyboardEvent('mousedown', { shiftKey: true });
|
||||
const event = new KeyboardEvent('pointerdown', { shiftKey: true });
|
||||
const eventPreventDefaultSpy = jest.spyOn(event, 'preventDefault');
|
||||
fireEvent(container, event);
|
||||
|
||||
expect(accessor.doSetGroupActive).toHaveBeenCalledWith(groupPanel);
|
||||
expect(accessor.addFloatingGroup).toHaveBeenCalledTimes(0);
|
||||
expect(eventPreventDefaultSpy).toHaveBeenCalledTimes(0);
|
||||
|
||||
const event2 = new KeyboardEvent('mousedown', { shiftKey: false });
|
||||
const event2 = new KeyboardEvent('pointerdown', { shiftKey: false });
|
||||
const eventPreventDefaultSpy2 = jest.spyOn(event2, 'preventDefault');
|
||||
fireEvent(container, event2);
|
||||
|
||||
@ -595,7 +599,7 @@ describe('tabsContainer', () => {
|
||||
const el = cut.element.querySelector('.dv-tab')!;
|
||||
expect(el).toBeTruthy();
|
||||
|
||||
const event = new KeyboardEvent('mousedown', { shiftKey: true });
|
||||
const event = new KeyboardEvent('pointerdown', { shiftKey: true });
|
||||
const preventDefaultSpy = jest.spyOn(event, 'preventDefault');
|
||||
fireEvent(el, event);
|
||||
|
||||
|
@ -1,20 +1,16 @@
|
||||
import { DockviewApi } from '../../../../api/component.api';
|
||||
import { Watermark } from '../../../../dockview/components/watermark/watermark';
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
|
||||
describe('watermark', () => {
|
||||
test('that the group is closed when the close button is clicked', () => {
|
||||
const cut = new Watermark();
|
||||
|
||||
const mockApi = jest.fn<Partial<DockviewApi>, any[]>(() => {
|
||||
return {
|
||||
removeGroup: jest.fn(),
|
||||
};
|
||||
const api = fromPartial<DockviewApi>({
|
||||
removeGroup: jest.fn(),
|
||||
});
|
||||
const api = <DockviewApi>new mockApi();
|
||||
const group = jest.fn() as any;
|
||||
|
||||
cut.init({ containerApi: api });
|
||||
cut.updateParentGroup(group, true);
|
||||
cut.init({ containerApi: api, group });
|
||||
|
||||
const closeEl = cut.element.querySelector('.dv-close-action')!;
|
||||
|
||||
|
@ -8,9 +8,9 @@ import { PanelUpdateEvent } from '../../panel/types';
|
||||
import { Orientation } from '../../splitview/splitview';
|
||||
import { CompositeDisposable } from '../../lifecycle';
|
||||
import { Emitter } from '../../events';
|
||||
import { DockviewPanel, IDockviewPanel } from '../../dockview/dockviewPanel';
|
||||
import { IDockviewPanel } from '../../dockview/dockviewPanel';
|
||||
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
|
||||
import { fireEvent, getByTestId, queryByTestId } from '@testing-library/dom';
|
||||
import { fireEvent, queryByTestId } from '@testing-library/dom';
|
||||
import { getPanelData } from '../../dnd/dataTransfer';
|
||||
import {
|
||||
GroupDragEvent,
|
||||
@ -262,6 +262,112 @@ describe('dockviewComponent', () => {
|
||||
dockview.dispose();
|
||||
});
|
||||
|
||||
describe('move group', () => {
|
||||
test('horizontal', () => {
|
||||
dockview = new DockviewComponent(container, {
|
||||
createComponent(options) {
|
||||
switch (options.name) {
|
||||
case 'default':
|
||||
return new PanelContentPartTest(
|
||||
options.id,
|
||||
options.name
|
||||
);
|
||||
default:
|
||||
throw new Error(`unsupported`);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
dockview.layout(600, 1000);
|
||||
|
||||
const panel1 = dockview.addPanel({
|
||||
id: 'panel1',
|
||||
component: 'default',
|
||||
});
|
||||
const panel2 = dockview.addPanel({
|
||||
id: 'panel2',
|
||||
component: 'default',
|
||||
position: { direction: 'right' },
|
||||
});
|
||||
const panel3 = dockview.addPanel({
|
||||
id: 'panel3',
|
||||
component: 'default',
|
||||
position: { direction: 'right' },
|
||||
});
|
||||
|
||||
expect(panel1.api.width).toBe(200);
|
||||
expect(panel2.api.width).toBe(200);
|
||||
expect(panel3.api.width).toBe(200);
|
||||
|
||||
panel3.api.setSize({ width: 300 });
|
||||
|
||||
expect(panel1.api.width).toBe(200);
|
||||
expect(panel2.api.width).toBe(100);
|
||||
expect(panel3.api.width).toBe(300);
|
||||
|
||||
dockview.moveGroup({
|
||||
from: { group: panel3.api.group },
|
||||
to: { group: panel1.api.group, position: 'right' },
|
||||
});
|
||||
|
||||
expect(panel1.api.width).toBe(200);
|
||||
expect(panel2.api.width).toBe(100);
|
||||
expect(panel3.api.width).toBe(300);
|
||||
});
|
||||
|
||||
test('vertical', () => {
|
||||
dockview = new DockviewComponent(container, {
|
||||
createComponent(options) {
|
||||
switch (options.name) {
|
||||
case 'default':
|
||||
return new PanelContentPartTest(
|
||||
options.id,
|
||||
options.name
|
||||
);
|
||||
default:
|
||||
throw new Error(`unsupported`);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
dockview.layout(1000, 600);
|
||||
|
||||
const panel1 = dockview.addPanel({
|
||||
id: 'panel1',
|
||||
component: 'default',
|
||||
});
|
||||
const panel2 = dockview.addPanel({
|
||||
id: 'panel2',
|
||||
component: 'default',
|
||||
position: { direction: 'below' },
|
||||
});
|
||||
const panel3 = dockview.addPanel({
|
||||
id: 'panel3',
|
||||
component: 'default',
|
||||
position: { direction: 'below' },
|
||||
});
|
||||
|
||||
expect(panel1.api.height).toBe(200);
|
||||
expect(panel2.api.height).toBe(200);
|
||||
expect(panel3.api.height).toBe(200);
|
||||
|
||||
panel3.api.setSize({ height: 300 });
|
||||
|
||||
expect(panel1.api.height).toBe(200);
|
||||
expect(panel2.api.height).toBe(100);
|
||||
expect(panel3.api.height).toBe(300);
|
||||
|
||||
dockview.moveGroup({
|
||||
from: { group: panel3.api.group },
|
||||
to: { group: panel1.api.group, position: 'bottom' },
|
||||
});
|
||||
|
||||
expect(panel1.api.height).toBe(200);
|
||||
expect(panel2.api.height).toBe(100);
|
||||
expect(panel3.api.height).toBe(300);
|
||||
});
|
||||
});
|
||||
|
||||
test('set active panel', () => {
|
||||
dockview.layout(500, 1000);
|
||||
|
||||
@ -626,6 +732,7 @@ describe('dockviewComponent', () => {
|
||||
panel1: {
|
||||
id: 'panel1',
|
||||
contentComponent: 'default',
|
||||
tabComponent: 'tab-default',
|
||||
title: 'panel1',
|
||||
},
|
||||
panel2: {
|
||||
@ -637,22 +744,26 @@ describe('dockviewComponent', () => {
|
||||
id: 'panel3',
|
||||
contentComponent: 'default',
|
||||
title: 'panel3',
|
||||
renderer: 'onlyWhenVisible',
|
||||
},
|
||||
panel4: {
|
||||
id: 'panel4',
|
||||
contentComponent: 'default',
|
||||
title: 'panel4',
|
||||
renderer: 'always',
|
||||
},
|
||||
panel5: {
|
||||
id: 'panel5',
|
||||
contentComponent: 'default',
|
||||
title: 'panel5',
|
||||
minimumHeight: 100,
|
||||
maximumHeight: 1000,
|
||||
minimumWidth: 200,
|
||||
maximumWidth: 2000,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// dockview.layout(1000, 1000, true);
|
||||
|
||||
expect(JSON.parse(JSON.stringify(dockview.toJSON()))).toEqual({
|
||||
activeGroup: 'group-1',
|
||||
grid: {
|
||||
@ -712,6 +823,7 @@ describe('dockviewComponent', () => {
|
||||
panel1: {
|
||||
id: 'panel1',
|
||||
contentComponent: 'default',
|
||||
tabComponent: 'tab-default',
|
||||
title: 'panel1',
|
||||
},
|
||||
panel2: {
|
||||
@ -723,16 +835,22 @@ describe('dockviewComponent', () => {
|
||||
id: 'panel3',
|
||||
contentComponent: 'default',
|
||||
title: 'panel3',
|
||||
renderer: 'onlyWhenVisible',
|
||||
},
|
||||
panel4: {
|
||||
id: 'panel4',
|
||||
contentComponent: 'default',
|
||||
title: 'panel4',
|
||||
renderer: 'always',
|
||||
},
|
||||
panel5: {
|
||||
id: 'panel5',
|
||||
contentComponent: 'default',
|
||||
title: 'panel5',
|
||||
minimumHeight: 100,
|
||||
maximumHeight: 1000,
|
||||
minimumWidth: 200,
|
||||
maximumWidth: 2000,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -116,10 +116,6 @@ class Watermark implements IWatermarkRenderer {
|
||||
return {};
|
||||
}
|
||||
|
||||
updateParentGroup() {
|
||||
//
|
||||
}
|
||||
|
||||
dispose() {
|
||||
//
|
||||
}
|
||||
|
@ -153,14 +153,14 @@ describe('events', () => {
|
||||
|
||||
const disposable = addDisposableWindowListener(
|
||||
element as any,
|
||||
'mousedown',
|
||||
'pointerdown',
|
||||
handler,
|
||||
true
|
||||
);
|
||||
|
||||
expect(element.addEventListener).toBeCalledTimes(1);
|
||||
expect(element.addEventListener).toHaveBeenCalledWith(
|
||||
'mousedown',
|
||||
'pointerdown',
|
||||
handler,
|
||||
true
|
||||
);
|
||||
@ -171,7 +171,7 @@ describe('events', () => {
|
||||
expect(element.addEventListener).toBeCalledTimes(1);
|
||||
expect(element.removeEventListener).toBeCalledTimes(1);
|
||||
expect(element.removeEventListener).toBeCalledWith(
|
||||
'mousedown',
|
||||
'pointerdown',
|
||||
handler,
|
||||
true
|
||||
);
|
||||
@ -187,13 +187,13 @@ describe('events', () => {
|
||||
|
||||
const disposable = addDisposableWindowListener(
|
||||
element as any,
|
||||
'mousedown',
|
||||
'pointerdown',
|
||||
handler
|
||||
);
|
||||
|
||||
expect(element.addEventListener).toBeCalledTimes(1);
|
||||
expect(element.addEventListener).toHaveBeenCalledWith(
|
||||
'mousedown',
|
||||
'pointerdown',
|
||||
handler,
|
||||
undefined
|
||||
);
|
||||
@ -204,7 +204,7 @@ describe('events', () => {
|
||||
expect(element.addEventListener).toBeCalledTimes(1);
|
||||
expect(element.removeEventListener).toBeCalledTimes(1);
|
||||
expect(element.removeEventListener).toBeCalledWith(
|
||||
'mousedown',
|
||||
'pointerdown',
|
||||
handler,
|
||||
undefined
|
||||
);
|
||||
@ -220,14 +220,14 @@ describe('events', () => {
|
||||
|
||||
const disposable = addDisposableListener(
|
||||
element as any,
|
||||
'mousedown',
|
||||
'pointerdown',
|
||||
handler,
|
||||
true
|
||||
);
|
||||
|
||||
expect(element.addEventListener).toBeCalledTimes(1);
|
||||
expect(element.addEventListener).toHaveBeenCalledWith(
|
||||
'mousedown',
|
||||
'pointerdown',
|
||||
handler,
|
||||
true
|
||||
);
|
||||
@ -238,7 +238,7 @@ describe('events', () => {
|
||||
expect(element.addEventListener).toBeCalledTimes(1);
|
||||
expect(element.removeEventListener).toBeCalledTimes(1);
|
||||
expect(element.removeEventListener).toBeCalledWith(
|
||||
'mousedown',
|
||||
'pointerdown',
|
||||
handler,
|
||||
true
|
||||
);
|
||||
@ -254,13 +254,13 @@ describe('events', () => {
|
||||
|
||||
const disposable = addDisposableListener(
|
||||
element as any,
|
||||
'mousedown',
|
||||
'pointerdown',
|
||||
handler
|
||||
);
|
||||
|
||||
expect(element.addEventListener).toBeCalledTimes(1);
|
||||
expect(element.addEventListener).toHaveBeenCalledWith(
|
||||
'mousedown',
|
||||
'pointerdown',
|
||||
handler,
|
||||
undefined
|
||||
);
|
||||
@ -271,7 +271,7 @@ describe('events', () => {
|
||||
expect(element.addEventListener).toBeCalledTimes(1);
|
||||
expect(element.removeEventListener).toBeCalledTimes(1);
|
||||
expect(element.removeEventListener).toBeCalledWith(
|
||||
'mousedown',
|
||||
'pointerdown',
|
||||
handler,
|
||||
undefined
|
||||
);
|
||||
|
@ -68,8 +68,8 @@ class TestPanel implements IGridPanelView {
|
||||
class ClassUnderTest extends BaseGrid<TestPanel> {
|
||||
readonly gridview = this.gridview;
|
||||
|
||||
constructor(options: BaseGridOptions) {
|
||||
super(options);
|
||||
constructor(parentElement: HTMLElement, options: BaseGridOptions) {
|
||||
super(parentElement, options);
|
||||
}
|
||||
|
||||
doRemoveGroup(
|
||||
@ -106,8 +106,7 @@ class ClassUnderTest extends BaseGrid<TestPanel> {
|
||||
|
||||
describe('baseComponentGridview', () => {
|
||||
test('that .layout(...) force flag works', () => {
|
||||
const cut = new ClassUnderTest({
|
||||
parentElement: document.createElement('div'),
|
||||
const cut = new ClassUnderTest(document.createElement('div'), {
|
||||
orientation: Orientation.HORIZONTAL,
|
||||
proportionalLayout: true,
|
||||
});
|
||||
@ -131,8 +130,7 @@ describe('baseComponentGridview', () => {
|
||||
});
|
||||
|
||||
test('can add group', () => {
|
||||
const cut = new ClassUnderTest({
|
||||
parentElement: document.createElement('div'),
|
||||
const cut = new ClassUnderTest(document.createElement('div'), {
|
||||
orientation: Orientation.HORIZONTAL,
|
||||
proportionalLayout: true,
|
||||
});
|
||||
|
@ -369,8 +369,11 @@ describe('overlay', () => {
|
||||
|
||||
const overlay1 = createOverlay();
|
||||
|
||||
const zIndexValue = (delta: number) =>
|
||||
`calc(var(--dv-overlay-z-index, 999) + ${delta})`;
|
||||
|
||||
expect(overlay1.element.getAttribute('aria-level')).toBe('0');
|
||||
expect(overlay1.element.style.zIndex).toBe('999');
|
||||
expect(overlay1.element.style.zIndex).toBe(zIndexValue(0));
|
||||
|
||||
const overlay2 = createOverlay();
|
||||
const overlay3 = createOverlay();
|
||||
@ -378,38 +381,38 @@ describe('overlay', () => {
|
||||
expect(overlay1.element.getAttribute('aria-level')).toBe('0');
|
||||
expect(overlay2.element.getAttribute('aria-level')).toBe('1');
|
||||
expect(overlay3.element.getAttribute('aria-level')).toBe('2');
|
||||
expect(overlay1.element.style.zIndex).toBe('999');
|
||||
expect(overlay2.element.style.zIndex).toBe('1001');
|
||||
expect(overlay3.element.style.zIndex).toBe('1003');
|
||||
expect(overlay1.element.style.zIndex).toBe(zIndexValue(0));
|
||||
expect(overlay2.element.style.zIndex).toBe(zIndexValue(2));
|
||||
expect(overlay3.element.style.zIndex).toBe(zIndexValue(4));
|
||||
|
||||
overlay2.bringToFront();
|
||||
|
||||
expect(overlay1.element.getAttribute('aria-level')).toBe('0');
|
||||
expect(overlay2.element.getAttribute('aria-level')).toBe('2');
|
||||
expect(overlay3.element.getAttribute('aria-level')).toBe('1');
|
||||
expect(overlay1.element.style.zIndex).toBe('999');
|
||||
expect(overlay2.element.style.zIndex).toBe('1003');
|
||||
expect(overlay3.element.style.zIndex).toBe('1001');
|
||||
expect(overlay1.element.style.zIndex).toBe(zIndexValue(0));
|
||||
expect(overlay2.element.style.zIndex).toBe(zIndexValue(4));
|
||||
expect(overlay3.element.style.zIndex).toBe(zIndexValue(2));
|
||||
|
||||
overlay1.bringToFront();
|
||||
|
||||
expect(overlay1.element.getAttribute('aria-level')).toBe('2');
|
||||
expect(overlay2.element.getAttribute('aria-level')).toBe('1');
|
||||
expect(overlay3.element.getAttribute('aria-level')).toBe('0');
|
||||
expect(overlay1.element.style.zIndex).toBe('1003');
|
||||
expect(overlay2.element.style.zIndex).toBe('1001');
|
||||
expect(overlay3.element.style.zIndex).toBe('999');
|
||||
expect(overlay1.element.style.zIndex).toBe(zIndexValue(4));
|
||||
expect(overlay2.element.style.zIndex).toBe(zIndexValue(2));
|
||||
expect(overlay3.element.style.zIndex).toBe(zIndexValue(0));
|
||||
|
||||
overlay2.dispose();
|
||||
|
||||
expect(overlay1.element.getAttribute('aria-level')).toBe('1');
|
||||
expect(overlay3.element.getAttribute('aria-level')).toBe('0');
|
||||
expect(overlay1.element.style.zIndex).toBe('1001');
|
||||
expect(overlay3.element.style.zIndex).toBe('999');
|
||||
expect(overlay1.element.style.zIndex).toBe(zIndexValue(2));
|
||||
expect(overlay3.element.style.zIndex).toBe(zIndexValue(0));
|
||||
|
||||
overlay1.dispose();
|
||||
|
||||
expect(overlay3.element.getAttribute('aria-level')).toBe('0');
|
||||
expect(overlay3.element.style.zIndex).toBe('999');
|
||||
expect(overlay3.element.style.zIndex).toBe(zIndexValue(0));
|
||||
});
|
||||
});
|
||||
|
@ -258,6 +258,8 @@ describe('overlayRenderContainer', () => {
|
||||
await exhaustMicrotaskQueue();
|
||||
|
||||
expect(spy).toHaveBeenCalledWith('aria-level');
|
||||
expect(panelContentEl.parentElement!.style.zIndex).toBe('1004');
|
||||
expect(panelContentEl.parentElement!.style.zIndex).toBe(
|
||||
'calc(var(--dv-overlay-z-index, 999) + 5)'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -21,7 +21,7 @@ export class GroupDragHandler extends DragHandler {
|
||||
this.addDisposables(
|
||||
addDisposableListener(
|
||||
element,
|
||||
'mousedown',
|
||||
'pointerdown',
|
||||
(e) => {
|
||||
if (e.shiftKey) {
|
||||
/**
|
||||
|
@ -30,7 +30,7 @@ export class DefaultTab extends CompositeDisposable implements ITabRenderer {
|
||||
this._element.appendChild(this.action);
|
||||
|
||||
this.addDisposables(
|
||||
addDisposableListener(this.action, 'mousedown', (ev) => {
|
||||
addDisposableListener(this.action, 'pointerdown', (ev) => {
|
||||
ev.preventDefault();
|
||||
})
|
||||
);
|
||||
@ -46,7 +46,7 @@ export class DefaultTab extends CompositeDisposable implements ITabRenderer {
|
||||
this._title = event.title;
|
||||
this.render();
|
||||
}),
|
||||
addDisposableListener(this.action, 'mousedown', (ev) => {
|
||||
addDisposableListener(this.action, 'pointerdown', (ev) => {
|
||||
ev.preventDefault();
|
||||
}),
|
||||
addDisposableListener(this.action, 'click', (ev) => {
|
||||
|
@ -124,7 +124,7 @@ export class Tab extends CompositeDisposable {
|
||||
this._onDragStart.fire(event);
|
||||
}),
|
||||
dragHandler,
|
||||
addDisposableListener(this._element, 'mousedown', (event) => {
|
||||
addDisposableListener(this._element, 'pointerdown', (event) => {
|
||||
if (event.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ export class TabsContainer
|
||||
}),
|
||||
addDisposableListener(
|
||||
this.voidContainer.element,
|
||||
'mousedown',
|
||||
'pointerdown',
|
||||
(event) => {
|
||||
const isFloatingGroupsEnabled =
|
||||
!this.accessor.options.disableFloatingGroups;
|
||||
@ -278,7 +278,7 @@ export class TabsContainer
|
||||
}
|
||||
}
|
||||
),
|
||||
addDisposableListener(this.tabContainer, 'mousedown', (event) => {
|
||||
addDisposableListener(this.tabContainer, 'pointerdown', (event) => {
|
||||
if (event.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
|
@ -5,8 +5,7 @@ import {
|
||||
import { addDisposableListener } from '../../../events';
|
||||
import { toggleClass } from '../../../dom';
|
||||
import { CompositeDisposable } from '../../../lifecycle';
|
||||
import { DockviewGroupPanel } from '../../dockviewGroupPanel';
|
||||
import { PanelUpdateEvent } from '../../../panel/types';
|
||||
import { IDockviewGroupPanel } from '../../dockviewGroupPanel';
|
||||
import { createCloseButton } from '../../../svg';
|
||||
import { DockviewApi } from '../../../api/component.api';
|
||||
|
||||
@ -15,7 +14,7 @@ export class Watermark
|
||||
implements IWatermarkRenderer
|
||||
{
|
||||
private _element: HTMLElement;
|
||||
private _group: DockviewGroupPanel | undefined;
|
||||
private _group: IDockviewGroupPanel | undefined;
|
||||
private _api: DockviewApi | undefined;
|
||||
|
||||
get element(): HTMLElement {
|
||||
@ -52,8 +51,9 @@ export class Watermark
|
||||
title.appendChild(actionsContainer);
|
||||
|
||||
this.addDisposables(
|
||||
addDisposableListener(closeAnchor, 'click', (ev) => {
|
||||
ev.preventDefault();
|
||||
addDisposableListener(closeAnchor, 'click', (event: MouseEvent) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (this._group) {
|
||||
this._api?.removeGroup(this._group);
|
||||
}
|
||||
@ -61,32 +61,12 @@ export class Watermark
|
||||
);
|
||||
}
|
||||
|
||||
update(_event: PanelUpdateEvent): void {
|
||||
// noop
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
// noop
|
||||
}
|
||||
|
||||
layout(_width: number, _height: number): void {
|
||||
// noop
|
||||
}
|
||||
|
||||
init(_params: WatermarkRendererInitParameters): void {
|
||||
this._api = _params.containerApi;
|
||||
this._group = _params.group;
|
||||
this.render();
|
||||
}
|
||||
|
||||
updateParentGroup(group: DockviewGroupPanel, _visible: boolean): void {
|
||||
this._group = group;
|
||||
this.render();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
private render(): void {
|
||||
const isOneGroup = !!(this._api && this._api.size <= 1);
|
||||
toggleClass(this.element, 'dv-has-actions', isOneGroup);
|
||||
|
@ -57,6 +57,10 @@ export class DefaultDockviewDeserialzier implements IPanelDeserializer {
|
||||
view,
|
||||
{
|
||||
renderer: panelData.renderer,
|
||||
minimumWidth: panelData.minimumWidth,
|
||||
minimumHeight: panelData.minimumHeight,
|
||||
maximumWidth: panelData.maximumWidth,
|
||||
maximumHeight: panelData.maximumHeight,
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -3,6 +3,7 @@ import {
|
||||
SerializedGridObject,
|
||||
getGridLocation,
|
||||
ISerializedLeafNode,
|
||||
orthogonal,
|
||||
} from '../gridview/gridview';
|
||||
import {
|
||||
directionToPosition,
|
||||
@ -51,7 +52,12 @@ import { DockviewPanelModel } from './dockviewPanelModel';
|
||||
import { getPanelData } from '../dnd/dataTransfer';
|
||||
import { Parameters } from '../panel/types';
|
||||
import { Overlay } from '../overlay/overlay';
|
||||
import { addTestId, toggleClass, watchElementResize } from '../dom';
|
||||
import {
|
||||
addTestId,
|
||||
getDockviewTheme,
|
||||
toggleClass,
|
||||
watchElementResize,
|
||||
} from '../dom';
|
||||
import { DockviewFloatingGroupPanel } from './dockviewFloatingGroupPanel';
|
||||
import {
|
||||
GroupDragEvent,
|
||||
@ -92,33 +98,6 @@ function moveGroupWithoutDestroying(options: {
|
||||
});
|
||||
}
|
||||
|
||||
function getDockviewTheme(element: HTMLElement): string | undefined {
|
||||
function toClassList(element: HTMLElement) {
|
||||
const list: string[] = [];
|
||||
|
||||
for (let i = 0; i < element.classList.length; i++) {
|
||||
list.push(element.classList.item(i)!);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
let theme: string | undefined = undefined;
|
||||
let parent: HTMLElement | null = element;
|
||||
|
||||
while (parent !== null) {
|
||||
theme = toClassList(parent).find((cls) =>
|
||||
cls.startsWith('dockview-theme-')
|
||||
);
|
||||
if (typeof theme === 'string') {
|
||||
break;
|
||||
}
|
||||
parent = parent.parentElement;
|
||||
}
|
||||
|
||||
return theme;
|
||||
}
|
||||
|
||||
export interface PanelReference {
|
||||
update: (event: { params: { [key: string]: any } }) => void;
|
||||
remove: () => void;
|
||||
@ -362,23 +341,18 @@ export class DockviewComponent
|
||||
}
|
||||
|
||||
constructor(parentElement: HTMLElement, options: DockviewComponentOptions) {
|
||||
super({
|
||||
super(parentElement, {
|
||||
proportionalLayout: true,
|
||||
orientation: Orientation.HORIZONTAL,
|
||||
styles: options.hideBorders
|
||||
? { separatorBorder: 'transparent' }
|
||||
: undefined,
|
||||
parentElement: parentElement,
|
||||
disableAutoResizing: options.disableAutoResizing,
|
||||
locked: options.locked,
|
||||
margin: options.gap,
|
||||
className: options.className,
|
||||
});
|
||||
|
||||
// const gready = document.createElement('div');
|
||||
// gready.className = 'dv-overlay-render-container';
|
||||
// this.gridview.element.appendChild(gready);
|
||||
|
||||
this.overlayRenderContainer = new OverlayRenderContainer(
|
||||
this.gridview.element,
|
||||
this
|
||||
@ -1022,19 +996,9 @@ export class DockviewComponent
|
||||
override updateOptions(options: Partial<DockviewComponentOptions>): void {
|
||||
super.updateOptions(options);
|
||||
|
||||
const changed_floatingGroupBounds =
|
||||
'floatingGroupBounds' in options &&
|
||||
options.floatingGroupBounds !== this.options.floatingGroupBounds;
|
||||
|
||||
const changed_rootOverlayOptions =
|
||||
'rootOverlayModel' in options &&
|
||||
options.rootOverlayModel !== this.options.rootOverlayModel;
|
||||
|
||||
this._options = { ...this.options, ...options };
|
||||
|
||||
if (changed_floatingGroupBounds) {
|
||||
if ('floatingGroupBounds' in options) {
|
||||
for (const group of this._floatingGroups) {
|
||||
switch (this.options.floatingGroupBounds) {
|
||||
switch (options.floatingGroupBounds) {
|
||||
case 'boundedWithinViewport':
|
||||
group.overlay.minimumInViewportHeight = undefined;
|
||||
group.overlay.minimumInViewportWidth = undefined;
|
||||
@ -1047,30 +1011,26 @@ export class DockviewComponent
|
||||
break;
|
||||
default:
|
||||
group.overlay.minimumInViewportHeight =
|
||||
this.options.floatingGroupBounds?.minimumHeightWithinViewport;
|
||||
options.floatingGroupBounds?.minimumHeightWithinViewport;
|
||||
group.overlay.minimumInViewportWidth =
|
||||
this.options.floatingGroupBounds?.minimumWidthWithinViewport;
|
||||
options.floatingGroupBounds?.minimumWidthWithinViewport;
|
||||
}
|
||||
|
||||
group.overlay.setBounds();
|
||||
}
|
||||
}
|
||||
|
||||
if (changed_rootOverlayOptions) {
|
||||
this._rootDropTarget.setOverlayModel(options.rootOverlayModel!);
|
||||
if ('rootOverlayModel' in options) {
|
||||
this._rootDropTarget.setOverlayModel(
|
||||
options.rootOverlayModel ?? DEFAULT_ROOT_OVERLAY_MODEL
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
// if explicitly set as `undefined`
|
||||
'gap' in options &&
|
||||
options.gap === undefined
|
||||
) {
|
||||
this.gridview.margin = 0;
|
||||
if ('gap' in options) {
|
||||
this.gridview.margin = options.gap ?? 0;
|
||||
}
|
||||
|
||||
if (typeof options.gap === 'number') {
|
||||
this.gridview.margin = options.gap;
|
||||
}
|
||||
this._options = { ...this.options, ...options };
|
||||
|
||||
this.layout(this.gridview.width, this.gridview.height, true);
|
||||
}
|
||||
@ -1412,6 +1372,11 @@ export class DockviewComponent
|
||||
);
|
||||
}
|
||||
|
||||
const initial = {
|
||||
width: options.initialWidth,
|
||||
height: options.initialHeight,
|
||||
};
|
||||
|
||||
if (options.position) {
|
||||
if (isPanelOptionsWithPanel(options.position)) {
|
||||
const referencePanel =
|
||||
@ -1453,6 +1418,11 @@ export class DockviewComponent
|
||||
this.doSetGroupAndPanelActive(group);
|
||||
}
|
||||
|
||||
group.api.setSize({
|
||||
height: initial?.height,
|
||||
width: initial?.width,
|
||||
});
|
||||
|
||||
return panel;
|
||||
}
|
||||
} else {
|
||||
@ -1499,6 +1469,11 @@ export class DockviewComponent
|
||||
skipSetGroupActive: options.inactive,
|
||||
});
|
||||
|
||||
referenceGroup.api.setSize({
|
||||
width: initial?.width,
|
||||
height: initial?.height,
|
||||
});
|
||||
|
||||
if (!options.inactive) {
|
||||
this.doSetGroupAndPanelActive(referenceGroup);
|
||||
}
|
||||
@ -1509,7 +1484,13 @@ export class DockviewComponent
|
||||
location,
|
||||
target
|
||||
);
|
||||
const group = this.createGroupAtLocation(relativeLocation);
|
||||
const group = this.createGroupAtLocation(
|
||||
relativeLocation,
|
||||
this.orientationAtLocation(relativeLocation) ===
|
||||
Orientation.VERTICAL
|
||||
? initial?.height
|
||||
: initial?.width
|
||||
);
|
||||
panel = this.createPanel(options, group);
|
||||
group.model.openPanel(panel, {
|
||||
skipSetActive: options.inactive,
|
||||
@ -1543,7 +1524,12 @@ export class DockviewComponent
|
||||
skipSetGroupActive: options.inactive,
|
||||
});
|
||||
} else {
|
||||
const group = this.createGroupAtLocation();
|
||||
const group = this.createGroupAtLocation(
|
||||
[0],
|
||||
this.gridview.orientation === Orientation.VERTICAL
|
||||
? initial?.height
|
||||
: initial?.width
|
||||
);
|
||||
panel = this.createPanel(options, group);
|
||||
group.model.openPanel(panel, {
|
||||
skipSetActive: options.inactive,
|
||||
@ -1681,7 +1667,12 @@ export class DockviewComponent
|
||||
);
|
||||
|
||||
const group = this.createGroup(options);
|
||||
this.doAddGroup(group, relativeLocation);
|
||||
const size =
|
||||
this.getLocationOrientation(relativeLocation) ===
|
||||
Orientation.VERTICAL
|
||||
? options.initialHeight
|
||||
: options.initialWidth;
|
||||
this.doAddGroup(group, relativeLocation, size);
|
||||
if (!options.skipSetActive) {
|
||||
this.doSetGroupAndPanelActive(group);
|
||||
}
|
||||
@ -1695,6 +1686,13 @@ export class DockviewComponent
|
||||
}
|
||||
}
|
||||
|
||||
private getLocationOrientation(location: number[]) {
|
||||
return location.length % 2 == 0 &&
|
||||
this.gridview.orientation === Orientation.HORIZONTAL
|
||||
? Orientation.HORIZONTAL
|
||||
: Orientation.VERTICAL;
|
||||
}
|
||||
|
||||
removeGroup(
|
||||
group: DockviewGroupPanel,
|
||||
options?:
|
||||
@ -2109,7 +2107,24 @@ export class DockviewComponent
|
||||
target
|
||||
);
|
||||
|
||||
this.gridview.addView(from, Sizing.Distribute, dropLocation);
|
||||
let size: number;
|
||||
|
||||
switch (this.gridview.orientation) {
|
||||
case Orientation.VERTICAL:
|
||||
size =
|
||||
referenceLocation.length % 2 == 0
|
||||
? from.api.width
|
||||
: from.api.height;
|
||||
break;
|
||||
case Orientation.HORIZONTAL:
|
||||
size =
|
||||
referenceLocation.length % 2 == 0
|
||||
? from.api.height
|
||||
: from.api.width;
|
||||
break;
|
||||
}
|
||||
|
||||
this.gridview.addView(from, size, dropLocation);
|
||||
}
|
||||
|
||||
from.panels.forEach((panel) => {
|
||||
@ -2283,7 +2298,13 @@ export class DockviewComponent
|
||||
this._api,
|
||||
group,
|
||||
view,
|
||||
{ renderer: options.renderer }
|
||||
{
|
||||
renderer: options.renderer,
|
||||
minimumWidth: options.minimumWidth,
|
||||
minimumHeight: options.minimumHeight,
|
||||
maximumWidth: options.maximumWidth,
|
||||
maximumHeight: options.maximumHeight,
|
||||
}
|
||||
);
|
||||
|
||||
panel.init({
|
||||
@ -2295,10 +2316,11 @@ export class DockviewComponent
|
||||
}
|
||||
|
||||
private createGroupAtLocation(
|
||||
location: number[] = [0]
|
||||
location: number[],
|
||||
size?: number
|
||||
): DockviewGroupPanel {
|
||||
const group = this.createGroup();
|
||||
this.doAddGroup(group, location);
|
||||
this.doAddGroup(group, location, size);
|
||||
return group;
|
||||
}
|
||||
|
||||
@ -2307,4 +2329,11 @@ export class DockviewComponent
|
||||
group.value.model.containsPanel(panel)
|
||||
)?.value;
|
||||
}
|
||||
|
||||
private orientationAtLocation(location: number[]) {
|
||||
const rootOrientation = this.gridview.orientation;
|
||||
return location.length % 2 == 1
|
||||
? rootOrientation
|
||||
: orthogonal(rootOrientation);
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,34 @@ export class DockviewGroupPanel
|
||||
{
|
||||
private readonly _model: DockviewGroupPanelModel;
|
||||
|
||||
get minimumWidth(): number {
|
||||
const activePanelMinimumWidth = this.activePanel?.minimumWidth;
|
||||
return typeof activePanelMinimumWidth === 'number'
|
||||
? activePanelMinimumWidth
|
||||
: MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH;
|
||||
}
|
||||
|
||||
get minimumHeight(): number {
|
||||
const activePanelMinimumHeight = this.activePanel?.minimumHeight;
|
||||
return typeof activePanelMinimumHeight === 'number'
|
||||
? activePanelMinimumHeight
|
||||
: MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT;
|
||||
}
|
||||
|
||||
get maximumWidth(): number {
|
||||
const activePanelMaximumWidth = this.activePanel?.maximumWidth;
|
||||
return typeof activePanelMaximumWidth === 'number'
|
||||
? activePanelMaximumWidth
|
||||
: Number.MAX_SAFE_INTEGER;
|
||||
}
|
||||
|
||||
get maximumHeight(): number {
|
||||
const activePanelMaximumHeight = this.activePanel?.maximumHeight;
|
||||
return typeof activePanelMaximumHeight === 'number'
|
||||
? activePanelMaximumHeight
|
||||
: Number.MAX_SAFE_INTEGER;
|
||||
}
|
||||
|
||||
get panels(): IDockviewPanel[] {
|
||||
return this._model.panels;
|
||||
}
|
||||
@ -71,8 +99,14 @@ export class DockviewGroupPanel
|
||||
id,
|
||||
'groupview_default',
|
||||
{
|
||||
minimumHeight: MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT,
|
||||
minimumWidth: MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH,
|
||||
minimumHeight:
|
||||
options.constraints?.minimumHeight ??
|
||||
MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT,
|
||||
minimumWidth:
|
||||
options.constraints?.maximumHeight ??
|
||||
MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH,
|
||||
maximumHeight: options.constraints?.maximumHeight,
|
||||
maximumWidth: options.constraints?.maximumWidth,
|
||||
},
|
||||
new DockviewGroupPanelApiImpl(id, accessor)
|
||||
);
|
||||
|
@ -38,6 +38,7 @@ import {
|
||||
} from './options';
|
||||
import { OverlayRenderContainer } from '../overlay/overlayRenderContainer';
|
||||
import { TitleEvent } from '../api/dockviewPanelApi';
|
||||
import { Contraints } from '../gridview/gridviewPanel';
|
||||
|
||||
interface GroupMoveEvent {
|
||||
groupId: string;
|
||||
@ -50,6 +51,9 @@ interface CoreGroupOptions {
|
||||
locked?: DockviewGroupPanelLocked;
|
||||
hideHeader?: boolean;
|
||||
skipSetActive?: boolean;
|
||||
constraints?: Partial<Contraints>;
|
||||
initialWidth?: number;
|
||||
initialHeight?: number;
|
||||
}
|
||||
|
||||
export interface GroupOptions extends CoreGroupOptions {
|
||||
@ -972,8 +976,6 @@ export class DockviewGroupPanelModel
|
||||
|
||||
this.tabsContainer.hide();
|
||||
this.contentContainer.element.appendChild(this.watermark.element);
|
||||
|
||||
this.watermark.updateParentGroup(this.groupPanel, true);
|
||||
}
|
||||
if (!this.isEmpty && this.watermark) {
|
||||
this.watermark.element.remove();
|
||||
|
@ -11,6 +11,7 @@ import { IDockviewPanelModel } from './dockviewPanelModel';
|
||||
import { DockviewComponent } from './dockviewComponent';
|
||||
import { DockviewPanelRenderer } from '../overlay/overlayRenderContainer';
|
||||
import { WillFocusEvent } from '../api/panelApi';
|
||||
import { Contraints } from '../gridview/gridviewPanel';
|
||||
|
||||
export interface IDockviewPanel extends IDisposable, IPanel {
|
||||
readonly view: IDockviewPanelModel;
|
||||
@ -18,6 +19,10 @@ export interface IDockviewPanel extends IDisposable, IPanel {
|
||||
readonly api: DockviewPanelApi;
|
||||
readonly title: string | undefined;
|
||||
readonly params: Parameters | undefined;
|
||||
readonly minimumWidth?: number;
|
||||
readonly minimumHeight?: number;
|
||||
readonly maximumWidth?: number;
|
||||
readonly maximumHeight?: number;
|
||||
updateParentGroup(
|
||||
group: DockviewGroupPanel,
|
||||
options?: { skipSetActive?: boolean }
|
||||
@ -40,6 +45,11 @@ export class DockviewPanel
|
||||
private _title: string | undefined;
|
||||
private _renderer: DockviewPanelRenderer | undefined;
|
||||
|
||||
private _minimumWidth: number | undefined;
|
||||
private _minimumHeight: number | undefined;
|
||||
private _maximumWidth: number | undefined;
|
||||
private _maximumHeight: number | undefined;
|
||||
|
||||
get params(): Parameters | undefined {
|
||||
return this._params;
|
||||
}
|
||||
@ -56,6 +66,22 @@ export class DockviewPanel
|
||||
return this._renderer ?? this.accessor.renderer;
|
||||
}
|
||||
|
||||
get minimumWidth(): number | undefined {
|
||||
return this._minimumWidth;
|
||||
}
|
||||
|
||||
get minimumHeight(): number | undefined {
|
||||
return this._minimumHeight;
|
||||
}
|
||||
|
||||
get maximumWidth(): number | undefined {
|
||||
return this._maximumWidth;
|
||||
}
|
||||
|
||||
get maximumHeight(): number | undefined {
|
||||
return this._maximumHeight;
|
||||
}
|
||||
|
||||
constructor(
|
||||
public readonly id: string,
|
||||
component: string,
|
||||
@ -64,11 +90,15 @@ export class DockviewPanel
|
||||
private readonly containerApi: DockviewApi,
|
||||
group: DockviewGroupPanel,
|
||||
readonly view: IDockviewPanelModel,
|
||||
options: { renderer?: DockviewPanelRenderer }
|
||||
options: { renderer?: DockviewPanelRenderer } & Partial<Contraints>
|
||||
) {
|
||||
super();
|
||||
this._renderer = options.renderer;
|
||||
this._group = group;
|
||||
this._minimumWidth = options.minimumWidth;
|
||||
this._minimumHeight = options.minimumHeight;
|
||||
this._maximumWidth = options.maximumWidth;
|
||||
this._maximumHeight = options.maximumHeight;
|
||||
|
||||
this.api = new DockviewPanelApiImpl(
|
||||
this,
|
||||
@ -129,6 +159,10 @@ export class DockviewPanel
|
||||
: undefined,
|
||||
title: this.title,
|
||||
renderer: this._renderer,
|
||||
minimumHeight: this._minimumHeight,
|
||||
maximumHeight: this._maximumHeight,
|
||||
minimumWidth: this._minimumWidth,
|
||||
maximumWidth: this._maximumWidth,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ import { DockviewPanelRenderer } from '../overlay/overlayRenderContainer';
|
||||
import { IGroupHeaderProps } from './framework';
|
||||
import { AnchoredBox } from '../types';
|
||||
import { FloatingGroupOptions } from './dockviewComponent';
|
||||
import { Contraints } from '../gridview/gridviewPanel';
|
||||
|
||||
export interface IHeaderActionsRenderer extends IDisposable {
|
||||
readonly element: HTMLElement;
|
||||
@ -116,6 +117,17 @@ export const PROPERTY_KEYS: (keyof DockviewOptions)[] = (() => {
|
||||
return Object.keys(properties) as (keyof DockviewOptions)[];
|
||||
})();
|
||||
|
||||
export interface CreateComponentOptions {
|
||||
/**
|
||||
* The unqiue identifer of the component
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* The component name, this should determine what is rendered.
|
||||
*/
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface DockviewFrameworkOptions {
|
||||
defaultTabComponent?: string;
|
||||
createRightHeaderActionComponent?: (
|
||||
@ -127,14 +139,10 @@ export interface DockviewFrameworkOptions {
|
||||
createPrefixHeaderActionComponent?: (
|
||||
group: DockviewGroupPanel
|
||||
) => IHeaderActionsRenderer;
|
||||
createTabComponent?: (options: {
|
||||
id: string;
|
||||
name: string;
|
||||
}) => ITabRenderer | undefined;
|
||||
createComponent: (options: {
|
||||
id: string;
|
||||
name: string;
|
||||
}) => IContentRenderer;
|
||||
createTabComponent?: (
|
||||
options: CreateComponentOptions
|
||||
) => ITabRenderer | undefined;
|
||||
createComponent: (options: CreateComponentOptions) => IContentRenderer;
|
||||
createWatermarkComponent?: () => IWatermarkRenderer;
|
||||
}
|
||||
|
||||
@ -230,7 +238,10 @@ export type AddPanelOptions<P extends object = Parameters> = {
|
||||
* Defaults to `false` which forces newly added panels to become active.
|
||||
*/
|
||||
inactive?: boolean;
|
||||
} & Partial<AddPanelOptionsUnion>;
|
||||
initialWidth?: number;
|
||||
initialHeight?: number;
|
||||
} & Partial<AddPanelOptionsUnion> &
|
||||
Partial<Contraints>;
|
||||
|
||||
type AddGroupOptionsWithPanel = {
|
||||
referencePanel: string | IDockviewPanel;
|
||||
|
@ -32,7 +32,6 @@ export interface IWatermarkRenderer
|
||||
extends Optional<Omit<IPanel, 'id' | 'init'>, RendererMethodOptionalList> {
|
||||
readonly element: HTMLElement;
|
||||
init: (params: WatermarkRendererInitParameters) => void;
|
||||
updateParentGroup(group: DockviewGroupPanel, visible: boolean): void;
|
||||
}
|
||||
|
||||
export interface ITabRenderer
|
||||
@ -64,4 +63,8 @@ export interface GroupviewPanelState {
|
||||
title?: string;
|
||||
renderer?: DockviewPanelRenderer;
|
||||
params?: { [key: string]: any };
|
||||
minimumWidth?: number;
|
||||
minimumHeight?: number;
|
||||
maximumWidth?: number;
|
||||
maximumHeight?: number;
|
||||
}
|
||||
|
@ -280,3 +280,50 @@ export function disableIframePointEvents() {
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function getDockviewTheme(element: HTMLElement): string | undefined {
|
||||
function toClassList(element: HTMLElement) {
|
||||
const list: string[] = [];
|
||||
|
||||
for (let i = 0; i < element.classList.length; i++) {
|
||||
list.push(element.classList.item(i)!);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
let theme: string | undefined = undefined;
|
||||
let parent: HTMLElement | null = element;
|
||||
|
||||
while (parent !== null) {
|
||||
theme = toClassList(parent).find((cls) =>
|
||||
cls.startsWith('dockview-theme-')
|
||||
);
|
||||
if (typeof theme === 'string') {
|
||||
break;
|
||||
}
|
||||
parent = parent.parentElement;
|
||||
}
|
||||
|
||||
return theme;
|
||||
}
|
||||
|
||||
export class Classnames {
|
||||
private _classNames: string[] = [];
|
||||
|
||||
constructor(private readonly element: HTMLElement) {}
|
||||
|
||||
setClassNames(classNames: string) {
|
||||
for (const className of this._classNames) {
|
||||
toggleClass(this.element, className, false);
|
||||
}
|
||||
|
||||
this._classNames = classNames
|
||||
.split(' ')
|
||||
.filter((v) => v.trim().length > 0);
|
||||
|
||||
for (const className of this._classNames) {
|
||||
toggleClass(this.element, className, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import { ISplitviewStyles, Orientation, Sizing } from '../splitview/splitview';
|
||||
import { IPanel } from '../panel/types';
|
||||
import { MovementOptions2 } from '../dockview/options';
|
||||
import { Resizable } from '../resizable';
|
||||
import { toggleClass } from '../dom';
|
||||
import { Classnames, toggleClass } from '../dom';
|
||||
|
||||
const nextLayoutId = sequentialNumberGenerator();
|
||||
|
||||
@ -33,7 +33,6 @@ export interface BaseGridOptions {
|
||||
readonly proportionalLayout: boolean;
|
||||
readonly orientation: Orientation;
|
||||
readonly styles?: ISplitviewStyles;
|
||||
readonly parentElement: HTMLElement;
|
||||
readonly disableAutoResizing?: boolean;
|
||||
readonly locked?: boolean;
|
||||
readonly margin?: number;
|
||||
@ -100,7 +99,7 @@ export abstract class BaseGrid<T extends IGridPanelView>
|
||||
readonly onDidViewVisibilityChangeMicroTaskQueue =
|
||||
this._onDidViewVisibilityChangeMicroTaskQueue.onEvent;
|
||||
|
||||
private classNames: string[] = [];
|
||||
private readonly _classNames: Classnames;
|
||||
|
||||
get id(): string {
|
||||
return this._id;
|
||||
@ -147,18 +146,15 @@ export abstract class BaseGrid<T extends IGridPanelView>
|
||||
this.gridview.locked = value;
|
||||
}
|
||||
|
||||
constructor(options: BaseGridOptions) {
|
||||
constructor(parentElement: HTMLElement, options: BaseGridOptions) {
|
||||
super(document.createElement('div'), options.disableAutoResizing);
|
||||
this.element.style.height = '100%';
|
||||
this.element.style.width = '100%';
|
||||
|
||||
this.classNames = options.className?.split(' ') ?? [];
|
||||
this._classNames = new Classnames(this.element);
|
||||
this._classNames.setClassNames(options.className ?? '');
|
||||
|
||||
for (const className of this.classNames) {
|
||||
toggleClass(this.element, className, true);
|
||||
}
|
||||
|
||||
options.parentElement.appendChild(this.element);
|
||||
parentElement.appendChild(this.element);
|
||||
|
||||
this.gridview = new Gridview(
|
||||
!!options.proportionalLayout,
|
||||
@ -214,14 +210,26 @@ export abstract class BaseGrid<T extends IGridPanelView>
|
||||
}
|
||||
|
||||
updateOptions(options: Partial<BaseGridOptions>) {
|
||||
if (typeof options.proportionalLayout === 'boolean') {
|
||||
// this.gridview.proportionalLayout = options.proportionalLayout; // not supported
|
||||
}
|
||||
if (options.orientation) {
|
||||
this.gridview.orientation = options.orientation;
|
||||
}
|
||||
if ('styles' in options) {
|
||||
// this.gridview.styles = options.styles; // not supported
|
||||
}
|
||||
if ('disableResizing' in options) {
|
||||
this.disableResizing = options.disableAutoResizing ?? false;
|
||||
}
|
||||
if ('locked' in options) {
|
||||
this.locked = options.locked ?? false;
|
||||
}
|
||||
if ('margin' in options) {
|
||||
this.gridview.margin = options.margin ?? 0;
|
||||
}
|
||||
if ('className' in options) {
|
||||
for (const className of this.classNames) {
|
||||
toggleClass(this.element, className, false);
|
||||
}
|
||||
this.classNames = options.className?.split(' ') ?? [];
|
||||
for (const className of this.classNames) {
|
||||
toggleClass(this.element, className, true);
|
||||
}
|
||||
this._classNames.setClassNames(options.className ?? '');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,8 +115,7 @@ export class GridviewComponent
|
||||
}
|
||||
|
||||
constructor(parentElement: HTMLElement, options: GridviewComponentOptions) {
|
||||
super({
|
||||
parentElement: parentElement,
|
||||
super(parentElement, {
|
||||
proportionalLayout: options.proportionalLayout,
|
||||
orientation: options.orientation,
|
||||
styles: options.styles,
|
||||
|
@ -15,6 +15,13 @@ import { Emitter, Event } from '../events';
|
||||
import { IViewSize } from './gridview';
|
||||
import { BaseGrid, IGridPanelView } from './baseComponentGridview';
|
||||
|
||||
export interface Contraints {
|
||||
minimumWidth?: number;
|
||||
maximumWidth?: number;
|
||||
minimumHeight?: number;
|
||||
maximumHeight?: number;
|
||||
}
|
||||
|
||||
export interface GridviewInitParameters extends PanelInitParameters {
|
||||
minimumWidth?: number;
|
||||
maximumWidth?: number;
|
||||
|
@ -26,8 +26,10 @@
|
||||
}
|
||||
|
||||
.dv-resize-container {
|
||||
--dv-overlay-z-index: var(--dv-overlay-z-index, 999);
|
||||
|
||||
position: absolute;
|
||||
z-index: 997;
|
||||
z-index: calc(var(--dv-overlay-z-index) - 2);
|
||||
|
||||
border: 1px solid var(--dv-tab-divider-color);
|
||||
box-shadow: var(--dv-floating-box-shadow);
|
||||
@ -41,7 +43,7 @@
|
||||
width: calc(100% - 8px);
|
||||
left: 4px;
|
||||
top: -2px;
|
||||
z-index: 999;
|
||||
z-index: var(--dv-overlay-z-index);
|
||||
position: absolute;
|
||||
cursor: ns-resize;
|
||||
}
|
||||
@ -51,7 +53,7 @@
|
||||
width: calc(100% - 8px);
|
||||
left: 4px;
|
||||
bottom: -2px;
|
||||
z-index: 999;
|
||||
z-index: var(--dv-overlay-z-index);
|
||||
position: absolute;
|
||||
cursor: ns-resize;
|
||||
}
|
||||
@ -61,7 +63,7 @@
|
||||
width: 4px;
|
||||
left: -2px;
|
||||
top: 4px;
|
||||
z-index: 999;
|
||||
z-index: var(--dv-overlay-z-index);
|
||||
position: absolute;
|
||||
cursor: ew-resize;
|
||||
}
|
||||
@ -71,7 +73,7 @@
|
||||
width: 4px;
|
||||
right: -2px;
|
||||
top: 4px;
|
||||
z-index: 999;
|
||||
z-index: var(--dv-overlay-z-index);
|
||||
position: absolute;
|
||||
cursor: ew-resize;
|
||||
}
|
||||
@ -81,7 +83,7 @@
|
||||
width: 4px;
|
||||
top: -2px;
|
||||
left: -2px;
|
||||
z-index: 999;
|
||||
z-index: var(--dv-overlay-z-index);
|
||||
position: absolute;
|
||||
cursor: nw-resize;
|
||||
}
|
||||
@ -91,7 +93,7 @@
|
||||
width: 4px;
|
||||
right: -2px;
|
||||
top: -2px;
|
||||
z-index: 999;
|
||||
z-index: var(--dv-overlay-z-index);
|
||||
position: absolute;
|
||||
cursor: ne-resize;
|
||||
}
|
||||
@ -101,7 +103,7 @@
|
||||
width: 4px;
|
||||
left: -2px;
|
||||
bottom: -2px;
|
||||
z-index: 999;
|
||||
z-index: var(--dv-overlay-z-index);
|
||||
position: absolute;
|
||||
cursor: sw-resize;
|
||||
}
|
||||
@ -111,7 +113,7 @@
|
||||
width: 4px;
|
||||
right: -2px;
|
||||
bottom: -2px;
|
||||
z-index: 999;
|
||||
z-index: var(--dv-overlay-z-index);
|
||||
position: absolute;
|
||||
cursor: se-resize;
|
||||
}
|
||||
|
@ -13,8 +13,6 @@ import { CompositeDisposable, MutableDisposable } from '../lifecycle';
|
||||
import { clamp } from '../math';
|
||||
import { AnchoredBox } from '../types';
|
||||
|
||||
export const DEFAULT_OVERLAY_Z_INDEX = 999;
|
||||
|
||||
class AriaLevelTracker {
|
||||
private _orderedList: HTMLElement[] = [];
|
||||
|
||||
@ -37,7 +35,9 @@ class AriaLevelTracker {
|
||||
private update(): void {
|
||||
for (let i = 0; i < this._orderedList.length; i++) {
|
||||
this._orderedList[i].setAttribute('aria-level', `${i}`);
|
||||
this._orderedList[i].style.zIndex = `${DEFAULT_OVERLAY_Z_INDEX + i * 2}`;
|
||||
this._orderedList[
|
||||
i
|
||||
].style.zIndex = `calc(var(--dv-overlay-z-index, 999) + ${i * 2})`;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -241,7 +241,7 @@ export class Overlay extends CompositeDisposable {
|
||||
iframes.release();
|
||||
},
|
||||
},
|
||||
addDisposableWindowListener(window, 'mousemove', (e) => {
|
||||
addDisposableWindowListener(window, 'pointermove', (e) => {
|
||||
const containerRect =
|
||||
this.options.container.getBoundingClientRect();
|
||||
const x = e.clientX - containerRect.left;
|
||||
@ -327,7 +327,7 @@ export class Overlay extends CompositeDisposable {
|
||||
|
||||
this.setBounds(bounds);
|
||||
}),
|
||||
addDisposableWindowListener(window, 'mouseup', () => {
|
||||
addDisposableWindowListener(window, 'pointerup', () => {
|
||||
toggleClass(
|
||||
this._element,
|
||||
'dv-resize-container-dragging',
|
||||
@ -342,7 +342,7 @@ export class Overlay extends CompositeDisposable {
|
||||
|
||||
this.addDisposables(
|
||||
move,
|
||||
addDisposableListener(dragTarget, 'mousedown', (event) => {
|
||||
addDisposableListener(dragTarget, 'pointerdown', (event) => {
|
||||
if (event.defaultPrevented) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
@ -358,7 +358,7 @@ export class Overlay extends CompositeDisposable {
|
||||
}),
|
||||
addDisposableListener(
|
||||
this.options.content,
|
||||
'mousedown',
|
||||
'pointerdown',
|
||||
(event) => {
|
||||
if (event.defaultPrevented) {
|
||||
return;
|
||||
@ -377,7 +377,7 @@ export class Overlay extends CompositeDisposable {
|
||||
),
|
||||
addDisposableListener(
|
||||
this.options.content,
|
||||
'mousedown',
|
||||
'pointerdown',
|
||||
() => {
|
||||
arialLevelTracker.push(this._element);
|
||||
},
|
||||
@ -409,7 +409,7 @@ export class Overlay extends CompositeDisposable {
|
||||
|
||||
this.addDisposables(
|
||||
move,
|
||||
addDisposableListener(resizeHandleElement, 'mousedown', (e) => {
|
||||
addDisposableListener(resizeHandleElement, 'pointerdown', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
let startPosition: {
|
||||
@ -422,7 +422,7 @@ export class Overlay extends CompositeDisposable {
|
||||
const iframes = disableIframePointEvents();
|
||||
|
||||
move.value = new CompositeDisposable(
|
||||
addDisposableWindowListener(window, 'mousemove', (e) => {
|
||||
addDisposableWindowListener(window, 'pointermove', (e) => {
|
||||
const containerRect =
|
||||
this.options.container.getBoundingClientRect();
|
||||
const overlayRect =
|
||||
@ -593,7 +593,7 @@ export class Overlay extends CompositeDisposable {
|
||||
iframes.release();
|
||||
},
|
||||
},
|
||||
addDisposableWindowListener(window, 'mouseup', () => {
|
||||
addDisposableWindowListener(window, 'pointerup', () => {
|
||||
move.dispose();
|
||||
this._onDidChangeEnd.fire();
|
||||
})
|
||||
|
@ -1,14 +1,12 @@
|
||||
.dv-render-overlay {
|
||||
--dv-overlay-z-index: var(--dv-overlay-z-index, 999);
|
||||
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
height: 100%;
|
||||
|
||||
&.dv-render-overlay-float {
|
||||
z-index: 998;
|
||||
|
||||
&.dv-render-overlay-active {
|
||||
// z-index: 1000;
|
||||
}
|
||||
z-index: calc(var(--dv-overlay-z-index) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@ import {
|
||||
} from '../lifecycle';
|
||||
import { IDockviewPanel } from '../dockview/dockviewPanel';
|
||||
import { DockviewComponent } from '../dockview/dockviewComponent';
|
||||
import { DEFAULT_OVERLAY_Z_INDEX } from './overlay';
|
||||
|
||||
export type DockviewPanelRenderer = 'onlyWhenVisible' | 'always';
|
||||
|
||||
@ -137,9 +136,9 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
||||
const level = Number(
|
||||
element.getAttribute('aria-level')
|
||||
);
|
||||
focusContainer.style.zIndex = `${
|
||||
DEFAULT_OVERLAY_Z_INDEX + level * 2 + 1
|
||||
}`;
|
||||
focusContainer.style.zIndex = `calc(var(--dv-overlay-z-index, 999) + ${
|
||||
level * 2 + 1
|
||||
})`;
|
||||
};
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
|
@ -24,7 +24,7 @@ import { sequentialNumberGenerator } from '../math';
|
||||
import { PaneTransfer } from '../dnd/dataTransfer';
|
||||
import { Resizable } from '../resizable';
|
||||
import { Parameters } from '../panel/types';
|
||||
import { toggleClass } from '../dom';
|
||||
import { Classnames, toggleClass } from '../dom';
|
||||
|
||||
const nextLayoutId = sequentialNumberGenerator();
|
||||
|
||||
@ -152,7 +152,7 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
|
||||
private readonly _onDidRemoveView = new Emitter<PaneviewPanel>();
|
||||
readonly onDidRemoveView = this._onDidRemoveView.event;
|
||||
|
||||
private classNames: string[] = [];
|
||||
private readonly _classNames: Classnames;
|
||||
|
||||
get id(): string {
|
||||
return this._id;
|
||||
@ -213,11 +213,8 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
|
||||
this._onDidRemoveView
|
||||
);
|
||||
|
||||
this.classNames = options.className?.split(' ') ?? [];
|
||||
|
||||
for (const className of this.classNames) {
|
||||
toggleClass(this.element, className, true);
|
||||
}
|
||||
this._classNames = new Classnames(this.element);
|
||||
this._classNames.setClassNames(options.className ?? '');
|
||||
|
||||
this._options = options;
|
||||
|
||||
@ -247,13 +244,11 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
|
||||
|
||||
updateOptions(options: Partial<PaneviewComponentOptions>): void {
|
||||
if ('className' in options) {
|
||||
for (const className of this.classNames) {
|
||||
toggleClass(this.element, className, false);
|
||||
}
|
||||
this.classNames = options.className?.split(' ') ?? [];
|
||||
for (const className of this.classNames) {
|
||||
toggleClass(this.element, className, true);
|
||||
}
|
||||
this._classNames.setClassNames(options.className ?? '');
|
||||
}
|
||||
|
||||
if ('disableResizing' in options) {
|
||||
this.disableResizing = options.disableAutoResizing ?? false;
|
||||
}
|
||||
|
||||
this._options = { ...this.options, ...options };
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { addStyles } from './dom';
|
||||
import { Emitter, addDisposableWindowListener } from './events';
|
||||
import { CompositeDisposable, IDisposable } from './lifecycle';
|
||||
import { CompositeDisposable, Disposable, IDisposable } from './lifecycle';
|
||||
import { Box } from './types';
|
||||
|
||||
export type PopoutWindowOptions = {
|
||||
@ -99,6 +99,9 @@ export class PopoutWindow extends CompositeDisposable {
|
||||
this._window = { value: externalWindow, disposable };
|
||||
|
||||
disposable.addDisposables(
|
||||
Disposable.from(() => {
|
||||
externalWindow.close();
|
||||
}),
|
||||
addDisposableWindowListener(window, 'beforeunload', () => {
|
||||
/**
|
||||
* before the main window closes we should close this popup too
|
||||
|
@ -17,7 +17,7 @@ import { Emitter, Event } from '../events';
|
||||
import { SplitviewPanel, ISplitviewPanel } from './splitviewPanel';
|
||||
import { createComponent } from '../panel/componentFactory';
|
||||
import { Resizable } from '../resizable';
|
||||
import { toggleClass } from '../dom';
|
||||
import { Classnames, toggleClass } from '../dom';
|
||||
|
||||
export interface SerializedSplitviewPanelData {
|
||||
id: string;
|
||||
@ -100,7 +100,7 @@ export class SplitviewComponent
|
||||
private readonly _onDidLayoutChange = new Emitter<void>();
|
||||
readonly onDidLayoutChange: Event<void> = this._onDidLayoutChange.event;
|
||||
|
||||
private classNames: string[] = [];
|
||||
private readonly _classNames: Classnames;
|
||||
|
||||
get panels(): SplitviewPanel[] {
|
||||
return this.splitview.getViews();
|
||||
@ -162,11 +162,8 @@ export class SplitviewComponent
|
||||
) {
|
||||
super(parentElement, options.disableAutoResizing);
|
||||
|
||||
this.classNames = options.className?.split(' ') ?? [];
|
||||
|
||||
for (const className of this.classNames) {
|
||||
toggleClass(this.element, className, true);
|
||||
}
|
||||
this._classNames = new Classnames(this.element);
|
||||
this._classNames.setClassNames(options.className ?? '');
|
||||
|
||||
this._options = options;
|
||||
|
||||
@ -189,25 +186,19 @@ export class SplitviewComponent
|
||||
|
||||
updateOptions(options: Partial<SplitviewComponentOptions>): void {
|
||||
if ('className' in options) {
|
||||
for (const className of this.classNames) {
|
||||
toggleClass(this.element, className, false);
|
||||
}
|
||||
this.classNames = options.className?.split(' ') ?? [];
|
||||
for (const className of this.classNames) {
|
||||
toggleClass(this.element, className, true);
|
||||
}
|
||||
this._classNames.setClassNames(options.className ?? '');
|
||||
}
|
||||
|
||||
const hasOrientationChanged =
|
||||
typeof options.orientation === 'string' &&
|
||||
this.options.orientation !== options.orientation;
|
||||
if ('disableResizing' in options) {
|
||||
this.disableResizing = options.disableAutoResizing ?? false;
|
||||
}
|
||||
|
||||
this._options = { ...this.options, ...options };
|
||||
|
||||
if (hasOrientationChanged) {
|
||||
if (typeof options.orientation === 'string') {
|
||||
this.splitview.orientation = options.orientation!;
|
||||
}
|
||||
|
||||
this._options = { ...this.options, ...options };
|
||||
|
||||
this.splitview.layout(
|
||||
this.splitview.size,
|
||||
this.splitview.orthogonalSize
|
||||
|
@ -8,6 +8,7 @@
|
||||
--dv-tabs-container-scrollbar-color: #888;
|
||||
--dv-icon-hover-background-color: rgba(90, 93, 94, 0.31);
|
||||
--dv-floating-box-shadow: 8px 8px 8px 0px rgba(83, 89, 93, 0.5);
|
||||
--dv-overlay-z-index: 999;
|
||||
}
|
||||
|
||||
@mixin dockview-theme-dark-mixin {
|
||||
@ -267,29 +268,28 @@
|
||||
}
|
||||
}
|
||||
|
||||
.dv-vertical > .dv-sash-container > .dv-sash {
|
||||
|
||||
&:not(.disabled) {
|
||||
&::after {
|
||||
content: '';
|
||||
height: 4px;
|
||||
width: 40px;
|
||||
border-radius: 2px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: var(--dv-separator-handle-background-color);
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.vertical > .sash-container > .sash {
|
||||
&:not(.disabled) {
|
||||
&::after {
|
||||
background-color: var(
|
||||
--dv-separator-handle-hover-background-color
|
||||
);
|
||||
content: '';
|
||||
height: 4px;
|
||||
width: 40px;
|
||||
border-radius: 2px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: var(--dv-separator-handle-background-color);
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&::after {
|
||||
background-color: var(
|
||||
--dv-separator-handle-hover-background-color
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dv-horizontal > .dv-sash-container > .dv-sash {
|
||||
@ -308,12 +308,25 @@
|
||||
|
||||
&:hover {
|
||||
&::after {
|
||||
background-color: var(
|
||||
--dv-separator-handle-hover-background-color
|
||||
);
|
||||
content: '';
|
||||
height: 40px;
|
||||
width: 4px;
|
||||
border-radius: 2px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: var(--dv-separator-handle-background-color);
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&::after {
|
||||
background-color: var(
|
||||
--dv-separator-handle-hover-background-color
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,7 +339,7 @@
|
||||
--dv-tabs-and-actions-container-background-color: #fcfcfc;
|
||||
//
|
||||
--dv-activegroup-visiblepanel-tab-background-color: #f0f1f2;
|
||||
--dv-activegroup-hiddenpanel-tab-background-color: ##fcfcfc;
|
||||
--dv-activegroup-hiddenpanel-tab-background-color: #fcfcfc;
|
||||
--dv-inactivegroup-visiblepanel-tab-background-color: #f0f1f2;
|
||||
--dv-inactivegroup-hiddenpanel-tab-background-color: #fcfcfc;
|
||||
--dv-tab-divider-color: transparent;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dockview-react",
|
||||
"version": "1.16.1",
|
||||
"version": "1.17.2",
|
||||
"description": "Zero dependency layout manager supporting tabs, grids and splitviews",
|
||||
"keywords": [
|
||||
"splitview",
|
||||
@ -54,6 +54,6 @@
|
||||
"test:cov": "cross-env ../../node_modules/.bin/jest --selectProjects dockview-react --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"dockview": "^1.16.1"
|
||||
"dockview": "^1.17.2"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dockview-vue",
|
||||
"version": "1.16.1",
|
||||
"version": "1.17.2",
|
||||
"description": "Zero dependency layout manager supporting tabs, grids and splitviews",
|
||||
"keywords": [
|
||||
"splitview",
|
||||
@ -52,6 +52,6 @@
|
||||
"test:cov": "cross-env ../../node_modules/.bin/jest --selectProjects dockview-vue --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"dockview-core": "^1.16.1"
|
||||
"dockview-core": "^1.17.2"
|
||||
}
|
||||
}
|
||||
|
@ -183,10 +183,6 @@ export class VueWatermarkRenderer
|
||||
);
|
||||
}
|
||||
|
||||
updateParentGroup(group: DockviewGroupPanel, visible: boolean): void {
|
||||
// TODO: make optional on interface
|
||||
}
|
||||
|
||||
update(event: PanelUpdateEvent<Parameters>): void {
|
||||
// noop
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
##
|
||||
|
||||
![](https://github.com/mathuo/dockview/blob/HEAD/packages/docs/static/img/splashscreen.gif?raw=true)
|
||||
|
||||
Please see the website: https://dockview.dev
|
||||
|
||||
## Features
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dockview",
|
||||
"version": "1.16.1",
|
||||
"version": "1.17.2",
|
||||
"description": "Zero dependency layout manager supporting tabs, grids and splitviews",
|
||||
"keywords": [
|
||||
"splitview",
|
||||
@ -54,6 +54,6 @@
|
||||
"test:cov": "cross-env ../../node_modules/.bin/jest --selectProjects dockview --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"dockview-core": "^1.16.1"
|
||||
"dockview-core": "^1.17.2"
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ describe('defaultTab', () => {
|
||||
expect(element.querySelector('.dv-default-tab-action')).toBeTruthy();
|
||||
});
|
||||
|
||||
test('that mouseDown on close button prevents panel becoming active', async () => {
|
||||
test('that pointerDown on close button prevents panel becoming active', async () => {
|
||||
const api = fromPartial<DockviewPanelApi>({
|
||||
setActive: jest.fn(),
|
||||
onDidTitleChange: jest.fn().mockImplementation(() => Disposable.NONE),
|
||||
@ -197,7 +197,7 @@ describe('defaultTab', () => {
|
||||
'.dv-default-tab-action'
|
||||
) as HTMLElement;
|
||||
|
||||
fireEvent.mouseDown(btn);
|
||||
fireEvent.pointerDown(btn);
|
||||
expect(api.setActive).toHaveBeenCalledTimes(0);
|
||||
|
||||
fireEvent.click(element);
|
||||
|
@ -49,7 +49,7 @@ export const DockviewDefaultTab: React.FunctionComponent<
|
||||
[api, closeActionOverride]
|
||||
);
|
||||
|
||||
const onMouseDown = React.useCallback((e: React.MouseEvent) => {
|
||||
const onPointerDown = React.useCallback((e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
}, []);
|
||||
|
||||
@ -79,7 +79,7 @@ export const DockviewDefaultTab: React.FunctionComponent<
|
||||
{!hideClose && (
|
||||
<div
|
||||
className="dv-default-tab-action"
|
||||
onMouseDown={onMouseDown}
|
||||
onPointerDown={onPointerDown}
|
||||
onClick={onClose}
|
||||
>
|
||||
<CloseButton />
|
||||
|
@ -57,13 +57,6 @@ export class ReactWatermarkPart implements IWatermarkRenderer {
|
||||
// noop - retrieval from api
|
||||
}
|
||||
|
||||
updateParentGroup(
|
||||
_group: DockviewGroupPanel,
|
||||
_isPanelVisible: boolean
|
||||
): void {
|
||||
// noop
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.part?.dispose();
|
||||
}
|
||||
|
23
packages/docs/blog/2024-09-05-dockview-1.17.0.md
Normal file
23
packages/docs/blog/2024-09-05-dockview-1.17.0.md
Normal file
@ -0,0 +1,23 @@
|
||||
---
|
||||
slug: dockview-1.17.0-release
|
||||
title: Dockview 1.17.0
|
||||
tags: [release]
|
||||
---
|
||||
|
||||
# Release Notes
|
||||
|
||||
Please reference docs @ [dockview.dev](https://dockview.dev).
|
||||
|
||||
## 🚀 Features
|
||||
|
||||
- Touch Support [#698](https://github.com/mathuo/dockview/pull/698)
|
||||
- Initial and bounding panel sizing [#690](https://github.com/mathuo/dockview/pull/690)
|
||||
- Improve group resize logic [#693](https://github.com/mathuo/dockview/pull/693)
|
||||
|
||||
## 🛠 Miscs
|
||||
|
||||
- Bug: Theme Typo [#694](https://github.com/mathuo/dockview/pull/694)
|
||||
- Docs [#703](https://github.com/mathuo/dockview/pull/703)
|
||||
|
||||
## 🔥 Breaking changes
|
||||
|
23
packages/docs/blog/2024-09-05-dockview-1.17.1.md
Normal file
23
packages/docs/blog/2024-09-05-dockview-1.17.1.md
Normal file
@ -0,0 +1,23 @@
|
||||
---
|
||||
slug: dockview-1.17.1-release
|
||||
title: Dockview 1.17.1
|
||||
tags: [release]
|
||||
---
|
||||
|
||||
# Release Notes
|
||||
|
||||
Please reference docs @ [dockview.dev](https://dockview.dev).
|
||||
|
||||
## 🚀 Features
|
||||
|
||||
- Touch Support [#698](https://github.com/mathuo/dockview/pull/698) [#709](https://github.com/mathuo/dockview/pull/709)
|
||||
- Initial and bounding panel sizing [#690](https://github.com/mathuo/dockview/pull/690)
|
||||
- Improve group resize logic [#693](https://github.com/mathuo/dockview/pull/693)
|
||||
|
||||
## 🛠 Miscs
|
||||
|
||||
- Bug: Theme Typo [#694](https://github.com/mathuo/dockview/pull/694)
|
||||
- Docs [#703](https://github.com/mathuo/dockview/pull/703)
|
||||
|
||||
## 🔥 Breaking changes
|
||||
|
21
packages/docs/blog/2024-10-12-dockview-1.17.2.md
Normal file
21
packages/docs/blog/2024-10-12-dockview-1.17.2.md
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
slug: dockview-1.17.2-release
|
||||
title: Dockview 1.17.2
|
||||
tags: [release]
|
||||
---
|
||||
|
||||
# Release Notes
|
||||
|
||||
Please reference docs @ [dockview.dev](https://dockview.dev).
|
||||
|
||||
## 🚀 Features
|
||||
|
||||
- Customization of z-index [#730](https://github.com/mathuo/dockview/pull/730) [#724](https://github.com/mathuo/dockview/pull/724)
|
||||
|
||||
## 🛠 Miscs
|
||||
|
||||
- Adjust README.md file [#715](https://github.com/mathuo/dockview/pull/715)
|
||||
- Docs typo [#714](https://github.com/mathuo/dockview/pull/714)
|
||||
|
||||
## 🔥 Breaking changes
|
||||
|
@ -1,12 +0,0 @@
|
||||
import { MultiFrameworkContainer } from '@site/src/components/ui/container';
|
||||
import EventsDockview from '@site/sandboxes/events-dockview/src/app';
|
||||
|
||||
# Events
|
||||
|
||||
A simple example showing events fired by `dockviewz that can be interacted with.
|
||||
|
||||
<MultiFrameworkContainer
|
||||
height={600}
|
||||
sandboxId="events-dockview"
|
||||
react={EventsDockview}
|
||||
/>
|
@ -9,25 +9,9 @@ import { DocRef } from '@site/src/components/ui/reference/docRef';
|
||||
import LiveExample from '@site/src/components/ui/exampleFrame';
|
||||
|
||||
<DocRef declaration="DockviewApi"
|
||||
methods={['onDidDrop']}
|
||||
methods={['onDidDrop', 'onUnhandledDragOverEvent']}
|
||||
/>
|
||||
|
||||
|
||||
<FrameworkSpecific framework='React'>
|
||||
<DocRef declaration="IDockviewReactProps" methods={['showDndOverlay']} />
|
||||
</FrameworkSpecific>
|
||||
|
||||
<FrameworkSpecific framework='Vue'>
|
||||
<DocRef declaration="IDockviewVueProps" methods={['showDndOverlay']} />
|
||||
</FrameworkSpecific>
|
||||
|
||||
<FrameworkSpecific framework='JavaScript'>
|
||||
<DocRef declaration="DockviewComponentOptions"
|
||||
methods={['showDndOverlay']}
|
||||
/>
|
||||
</FrameworkSpecific>
|
||||
|
||||
|
||||
## Intercepting Drag Events
|
||||
|
||||
You can intercept drag events to attach your own metadata using the `onWillDragPanel` and `onWillDragGroup` api methods.
|
||||
|
@ -8,6 +8,15 @@ This section provided a core overview.
|
||||
The component takes a collection of [Options](/docs/api/dockview/options) as inputs and
|
||||
once you have created a dock you can store a reference to the [API](/docs/api/dockview/overview) that is created.
|
||||
|
||||
|
||||
<FrameworkSpecific framework='JavaScript'>
|
||||
```tsx
|
||||
const element: HTMLElement
|
||||
const options: DockviewComponentOptions
|
||||
const api: DockviewApi = createDockview(element, options);
|
||||
```
|
||||
</FrameworkSpecific>
|
||||
|
||||
<FrameworkSpecific framework='React'>
|
||||
```tsx
|
||||
function onReady(event: DockviewReadyEvent) {
|
||||
|
@ -176,3 +176,35 @@ api.addPanel({
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Minimum and Maximum
|
||||
|
||||
You can define both minimum and maxmium widths and heights, these are persisted with layouts.
|
||||
|
||||
:::info
|
||||
Since panels exist within groups there are occasions where these boundaries will be ignored to prevent overflow and clipping issues within the dock.
|
||||
:::
|
||||
|
||||
```ts
|
||||
api.addPanel({
|
||||
id: 'panel_1',
|
||||
component: 'default',
|
||||
minimumWidth: 100,
|
||||
maximumWidth: 100,
|
||||
minimumHeight: 200,
|
||||
maximumHeight: 2000
|
||||
});
|
||||
```
|
||||
|
||||
### Initial Size
|
||||
|
||||
You can define an `initialWidth` and `initialHeight`. The dock will may a best attempt to obey these inputs but it may not always be possible due to the constraints of the grid.
|
||||
|
||||
```ts
|
||||
api.addPanel({
|
||||
id: 'panel_1',
|
||||
component: 'default',
|
||||
initialWidth: 100,
|
||||
initialHeight: 100
|
||||
});
|
||||
```
|
||||
|
@ -20,7 +20,7 @@ You can register panels through the dock [option](/docs/api/dockview/options) `
|
||||
|
||||
|
||||
<FrameworkSpecific framework='JavaScript'>
|
||||
<DocRef declaration="DockviewComponentOptions" methods={['components']} />
|
||||
<DocRef declaration="DockviewComponentOptions" methods={['createComponent']} />
|
||||
</FrameworkSpecific>
|
||||
|
||||
|
||||
@ -44,6 +44,37 @@ return <DockviewReact components={components}/>
|
||||
</FrameworkSpecific>
|
||||
|
||||
|
||||
<FrameworkSpecific framework='JavaScript'>
|
||||
```tsx
|
||||
class Panel implements IContentRenderer {
|
||||
private readonly _element: HTMLElement;
|
||||
|
||||
get element(): HTMLElement {
|
||||
return this._element;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this._element = document.createElement('div');
|
||||
}
|
||||
|
||||
init(parameters: GroupPanelPartInitParameters): void {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const api = createDockview(parentElement, {
|
||||
createComponent: (options) => {
|
||||
switch (options.name) {
|
||||
case 'component_1':
|
||||
return new Panel();
|
||||
}
|
||||
},
|
||||
});
|
||||
```
|
||||
</FrameworkSpecific>
|
||||
|
||||
|
||||
<FrameworkSpecific framework='Vue'>
|
||||
```tsx
|
||||
const App = {
|
||||
|
@ -109,7 +109,7 @@ not implemented
|
||||
|
||||
## Accessing Custom Panel Parameters
|
||||
|
||||
You can provide a generic type that matches the structure of the epxected custom panels parameters
|
||||
You can provide a generic type that matches the structure of the expected custom panels parameters
|
||||
to provide type-hints for the panel parameters which can be accessed via the `params` option.
|
||||
|
||||
<FrameworkSpecific framework='React'>
|
||||
|
@ -25,7 +25,7 @@ The following properties can be set to configure the behaviours of floating grou
|
||||
|
||||
<FrameworkSpecific framework='JavaScript'>
|
||||
<DocRef declaration="DockviewComponentOptions"
|
||||
methods={['watermarkComponent', 'watermarkFrameworkComponent', 'frameworkComponentFactory']}
|
||||
methods={['createWatermarkComponent']}
|
||||
/>
|
||||
</FrameworkSpecific>
|
||||
|
||||
|
@ -18,7 +18,7 @@ npm install dockview-core
|
||||
Firstly, install the `dockview` library:
|
||||
|
||||
```sh
|
||||
npm install dockview
|
||||
npm install dockview-react
|
||||
```
|
||||
</FrameworkSpecific>
|
||||
|
||||
|
@ -19,10 +19,15 @@ Firstly, you should import `dockview.css`:
|
||||
|
||||
<FrameworkSpecific framework='React'>
|
||||
```css
|
||||
@import './node_modules/dockview/dist/styles/dockview.css';
|
||||
@import './node_modules/dockview-react/dist/styles/dockview.css';
|
||||
```
|
||||
</FrameworkSpecific>
|
||||
|
||||
<FrameworkSpecific framework='Vue'>
|
||||
```css
|
||||
@import './node_modules/dockview-vue/dist/styles/dockview.css';
|
||||
```
|
||||
</FrameworkSpecific>
|
||||
|
||||
|
||||
## Provided themes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dockview-docs",
|
||||
"version": "1.16.1",
|
||||
"version": "1.17.2",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "npm run build-templates && docusaurus build",
|
||||
@ -38,7 +38,7 @@
|
||||
"ag-grid-react": "^31.0.2",
|
||||
"axios": "^1.6.3",
|
||||
"clsx": "^2.1.0",
|
||||
"dockview": "^1.16.1",
|
||||
"dockview": "^1.17.2",
|
||||
"prism-react-renderer": "^2.3.1",
|
||||
"react-dnd": "^16.0.1",
|
||||
"react-laag": "^2.0.5",
|
||||
|
@ -1,13 +1,33 @@
|
||||
import { DockviewReact, DockviewReadyEvent } from 'dockview';
|
||||
import {
|
||||
DockviewReact,
|
||||
DockviewReadyEvent,
|
||||
IDockviewPanelProps,
|
||||
} from 'dockview';
|
||||
import * as React from 'react';
|
||||
|
||||
const components = {
|
||||
iframeComponent: () => {
|
||||
iframeComponent: (props: IDockviewPanelProps) => {
|
||||
const [enabled, setEnabled] = React.useState<boolean>(
|
||||
props.api.isActive
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
const disposable = props.api.onDidActiveChange((event) => {
|
||||
setEnabled(event.isActive);
|
||||
console.log(event);
|
||||
});
|
||||
|
||||
return () => {
|
||||
disposable.dispose();
|
||||
};
|
||||
}, [props.api]);
|
||||
|
||||
return (
|
||||
<iframe
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
pointerEvents: enabled ? 'inherit' : 'none',
|
||||
}}
|
||||
src="https://dockview.dev"
|
||||
/>
|
||||
|
@ -15,8 +15,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.data-table {
|
||||
table {
|
||||
font-size: 11px;
|
||||
@ -58,35 +56,41 @@
|
||||
.selected {
|
||||
background-color: #4864dc;
|
||||
}
|
||||
}
|
||||
|
||||
.demo-button {
|
||||
min-width: 50px;
|
||||
padding: 0px 2px;
|
||||
border-radius: 0px;
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
align-items: center;
|
||||
outline: 1px solid #4c65d4;
|
||||
.button-group {
|
||||
button {
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.demo-button {
|
||||
min-width: 50px;
|
||||
padding: 0px 2px;
|
||||
border-radius: 0px;
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
align-items: center;
|
||||
outline: 1px solid #4c65d4;
|
||||
}
|
||||
|
||||
.demo-icon-button {
|
||||
outline: 1px solid #4c65d4;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 0px;
|
||||
padding: 0px 4px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
|
||||
&:disabled {
|
||||
color: gray;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.demo-icon-button {
|
||||
outline: 1px solid #4c65d4;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 0px;
|
||||
padding: 0px 4px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
|
||||
&:disabled {
|
||||
color: gray;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
}
|
||||
span {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,24 @@ import { GroupActions } from './groupActions';
|
||||
import { LeftControls, PrefixHeaderControls, RightControls } from './controls';
|
||||
import { Table, usePanelApiMetadata } from './debugPanel';
|
||||
|
||||
const DebugContext = React.createContext<boolean>(false);
|
||||
|
||||
const Option = (props: {
|
||||
title: string;
|
||||
onClick: () => void;
|
||||
value: string;
|
||||
}) => {
|
||||
return (
|
||||
<div>
|
||||
<span>{`${props.title}: `}</span>
|
||||
<button onClick={props.onClick}>{props.value}</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const components = {
|
||||
default: (props: IDockviewPanelProps) => {
|
||||
const isDebug = React.useContext(DebugContext);
|
||||
const metadata = usePanelApiMetadata(props.api);
|
||||
|
||||
return (
|
||||
@ -24,12 +40,11 @@ const components = {
|
||||
style={{
|
||||
height: '100%',
|
||||
overflow: 'auto',
|
||||
color: 'white',
|
||||
position: 'relative',
|
||||
// border: '5px dashed purple',
|
||||
padding: 5,
|
||||
border: isDebug ? '2px dashed orange' : '',
|
||||
}}
|
||||
>
|
||||
{/* <Table data={metadata} /> */}
|
||||
<span
|
||||
style={{
|
||||
position: 'absolute',
|
||||
@ -43,12 +58,52 @@ const components = {
|
||||
>
|
||||
{props.api.title}
|
||||
</span>
|
||||
|
||||
{isDebug && (
|
||||
<div style={{ fontSize: '0.8em' }}>
|
||||
<Option
|
||||
title="Panel Rendering Mode"
|
||||
value={metadata.renderer.value}
|
||||
onClick={() =>
|
||||
props.api.setRenderer(
|
||||
props.api.renderer === 'always'
|
||||
? 'onlyWhenVisible'
|
||||
: 'always'
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
||||
<Table data={metadata} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
iframe: () => {
|
||||
nested: (props: IDockviewPanelProps) => {
|
||||
return (
|
||||
<DockviewReact
|
||||
components={components}
|
||||
onReady={(event: DockviewReadyEvent) => {
|
||||
event.api.addPanel({ id: 'panel_1', component: 'default' });
|
||||
event.api.addPanel({ id: 'panel_2', component: 'default' });
|
||||
event.api.addPanel({
|
||||
id: 'panel_3',
|
||||
component: 'default',
|
||||
floating: true,
|
||||
});
|
||||
}}
|
||||
className={'dockview-theme-abyss'}
|
||||
/>
|
||||
);
|
||||
},
|
||||
iframe: (props: IDockviewPanelProps) => {
|
||||
return (
|
||||
<iframe
|
||||
onMouseDown={() => {
|
||||
if (!props.api.isActive) {
|
||||
props.api.setActive();
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
@ -199,6 +254,7 @@ const DockviewDemo = (props: { theme?: string }) => {
|
||||
}, [gapCheck]);
|
||||
|
||||
const [showLogs, setShowLogs] = React.useState<boolean>(false);
|
||||
const [debug, setDebug] = React.useState<boolean>(false);
|
||||
|
||||
return (
|
||||
<div
|
||||
@ -210,6 +266,7 @@ const DockviewDemo = (props: { theme?: string }) => {
|
||||
padding: '8px',
|
||||
backgroundColor: 'rgba(0,0,50,0.25)',
|
||||
borderRadius: '8px',
|
||||
position: 'relative',
|
||||
...css,
|
||||
}}
|
||||
>
|
||||
@ -252,6 +309,15 @@ const DockviewDemo = (props: { theme?: string }) => {
|
||||
padding: '4px',
|
||||
}}
|
||||
>
|
||||
<button
|
||||
onClick={() => {
|
||||
setDebug(!debug);
|
||||
}}
|
||||
>
|
||||
<span className="material-symbols-outlined">
|
||||
engineering
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
setShowLogs(!showLogs);
|
||||
@ -278,18 +344,20 @@ const DockviewDemo = (props: { theme?: string }) => {
|
||||
display: 'flex',
|
||||
}}
|
||||
>
|
||||
<DockviewReact
|
||||
components={components}
|
||||
defaultTabComponent={headerComponents.default}
|
||||
rightHeaderActionsComponent={RightControls}
|
||||
leftHeaderActionsComponent={LeftControls}
|
||||
prefixHeaderActionsComponent={PrefixHeaderControls}
|
||||
watermarkComponent={
|
||||
watermark ? WatermarkComponent : undefined
|
||||
}
|
||||
onReady={onReady}
|
||||
className={props.theme || 'dockview-theme-abyss'}
|
||||
/>
|
||||
<DebugContext.Provider value={debug}>
|
||||
<DockviewReact
|
||||
components={components}
|
||||
defaultTabComponent={headerComponents.default}
|
||||
rightHeaderActionsComponent={RightControls}
|
||||
leftHeaderActionsComponent={LeftControls}
|
||||
prefixHeaderActionsComponent={PrefixHeaderControls}
|
||||
watermarkComponent={
|
||||
watermark ? WatermarkComponent : undefined
|
||||
}
|
||||
onReady={onReady}
|
||||
className={props.theme || 'dockview-theme-abyss'}
|
||||
/>
|
||||
</DebugContext.Provider>
|
||||
</div>
|
||||
|
||||
{showLogs && (
|
||||
|
@ -2,6 +2,93 @@ import { DockviewApi } from 'dockview';
|
||||
import * as React from 'react';
|
||||
import { defaultConfig, nextId } from './defaultLayout';
|
||||
|
||||
import { createRoot, Root } from 'react-dom/client';
|
||||
import { PanelBuilder } from './panelBuilder';
|
||||
|
||||
let mount = document.querySelector('.popover-anchor') as HTMLElement | null;
|
||||
|
||||
if (!mount) {
|
||||
mount = document.createElement('div');
|
||||
mount.className = 'popover-anchor';
|
||||
document.body.insertBefore(mount, document.body.firstChild);
|
||||
}
|
||||
|
||||
const PopoverComponent = (props: {
|
||||
close: () => void;
|
||||
component: React.FC<{ close: () => void }>;
|
||||
}) => {
|
||||
const ref = React.useRef<HTMLDivElement>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
const handler = (ev: MouseEvent) => {
|
||||
let target = ev.target as HTMLElement;
|
||||
|
||||
while (target.parentElement) {
|
||||
if (target === ref.current) {
|
||||
return;
|
||||
}
|
||||
target = target.parentElement;
|
||||
}
|
||||
|
||||
props.close();
|
||||
};
|
||||
|
||||
window.addEventListener('mousedown', handler);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('mousedown', handler);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: 9999,
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
ref={ref}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%,-50%)',
|
||||
backgroundColor: 'black',
|
||||
color: 'white',
|
||||
padding: 10,
|
||||
}}
|
||||
>
|
||||
<props.component close={props.close} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
function usePopover() {
|
||||
return {
|
||||
open: (Component: React.FC<{ close: () => void }>) => {
|
||||
const el = document.createElement('div');
|
||||
mount!.appendChild(el);
|
||||
const root = createRoot(el);
|
||||
|
||||
root.render(
|
||||
<PopoverComponent
|
||||
component={Component}
|
||||
close={() => {
|
||||
root.unmount();
|
||||
el.remove();
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const GridActions = (props: {
|
||||
api?: DockviewApi;
|
||||
hasCustomWatermark: boolean;
|
||||
@ -39,13 +126,21 @@ export const GridActions = (props: {
|
||||
}
|
||||
};
|
||||
|
||||
const onAddPanel = (options?: { inactive: boolean }) => {
|
||||
props.api?.addPanel({
|
||||
id: `id_${Date.now().toString()}`,
|
||||
component: 'default',
|
||||
title: `Tab ${nextId()}`,
|
||||
inactive: options?.inactive,
|
||||
});
|
||||
const popover = usePopover();
|
||||
|
||||
const onAddPanel = (options?: { advanced: boolean }) => {
|
||||
if (options?.advanced) {
|
||||
popover.open(({ close }) => {
|
||||
return <PanelBuilder api={props.api!} done={close} />;
|
||||
});
|
||||
} else {
|
||||
props.api?.addPanel({
|
||||
id: `id_${Date.now().toString()}`,
|
||||
component: 'default',
|
||||
title: `Tab ${nextId()}`,
|
||||
renderer: 'always',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const onAddGroup = () => {
|
||||
@ -60,15 +155,17 @@ export const GridActions = (props: {
|
||||
|
||||
return (
|
||||
<div className="action-container">
|
||||
<button className="text-button" onClick={() => onAddPanel()}>
|
||||
Add Panel
|
||||
</button>
|
||||
<button
|
||||
className="text-button"
|
||||
onClick={() => onAddPanel({ inactive: true })}
|
||||
>
|
||||
Add Inactive Panel
|
||||
</button>
|
||||
<div className="button-group">
|
||||
<button className="text-button" onClick={() => onAddPanel()}>
|
||||
Add Panel
|
||||
</button>
|
||||
<button
|
||||
className="demo-icon-button"
|
||||
onClick={() => onAddPanel({ advanced: true })}
|
||||
>
|
||||
<span className="material-symbols-outlined">tune</span>
|
||||
</button>
|
||||
</div>
|
||||
<button className="text-button" onClick={onAddGroup}>
|
||||
Add Group
|
||||
</button>
|
||||
|
@ -88,14 +88,18 @@ const GroupAction = (props: {
|
||||
}
|
||||
onClick={() => {
|
||||
if (group) {
|
||||
|
||||
props.api.addFloatingGroup(group, {
|
||||
width: 400,
|
||||
height: 300,
|
||||
x: 50,
|
||||
y: 50,
|
||||
position: {
|
||||
width: 400,
|
||||
height: 300,
|
||||
top: 50,
|
||||
bottom: 50,
|
||||
right: 50,
|
||||
},
|
||||
});
|
||||
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
@ -0,0 +1,115 @@
|
||||
import { DockviewApi } from 'dockview';
|
||||
import * as React from 'react';
|
||||
import { nextId } from './defaultLayout';
|
||||
|
||||
export const PanelBuilder = (props: { api: DockviewApi; done: () => void }) => {
|
||||
const [parameters, setParameters] = React.useState<{
|
||||
initialWidth?: number;
|
||||
initialHeight?: number;
|
||||
maximumHeight?: number;
|
||||
maximumWidth?: number;
|
||||
minimumHeight?: number;
|
||||
minimumWidth?: number;
|
||||
}>({});
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '1fr 1fr',
|
||||
}}
|
||||
>
|
||||
<div>{'Initial Width'}</div>
|
||||
<input
|
||||
type="number"
|
||||
value={parameters.initialWidth}
|
||||
onChange={(event) =>
|
||||
setParameters((_) => ({
|
||||
..._,
|
||||
initialWidth: Number(event.target.value),
|
||||
}))
|
||||
}
|
||||
/>
|
||||
<div>{'Initial Height'}</div>
|
||||
<input
|
||||
type="number"
|
||||
value={parameters.initialHeight}
|
||||
onChange={(event) =>
|
||||
setParameters((_) => ({
|
||||
..._,
|
||||
initialHeight: Number(event.target.value),
|
||||
}))
|
||||
}
|
||||
/>
|
||||
<div>{'Maximum Width'}</div>
|
||||
<input
|
||||
type="number"
|
||||
value={parameters.maximumWidth}
|
||||
onChange={(event) =>
|
||||
setParameters((_) => ({
|
||||
..._,
|
||||
maximumWidth: Number(event.target.value),
|
||||
}))
|
||||
}
|
||||
/>
|
||||
<div>{'Maximum Height'}</div>
|
||||
<input
|
||||
type="number"
|
||||
value={parameters.maximumHeight}
|
||||
onChange={(event) =>
|
||||
setParameters((_) => ({
|
||||
..._,
|
||||
maximumHeight: Number(event.target.value),
|
||||
}))
|
||||
}
|
||||
/>
|
||||
<div>{'Minimum Width'}</div>
|
||||
<input
|
||||
type="number"
|
||||
value={parameters.minimumWidth}
|
||||
onChange={(event) =>
|
||||
setParameters((_) => ({
|
||||
..._,
|
||||
minimumWidth: Number(event.target.value),
|
||||
}))
|
||||
}
|
||||
/>
|
||||
<div>{'Minimum Height'}</div>
|
||||
<input
|
||||
type="number"
|
||||
value={parameters.minimumHeight}
|
||||
onChange={(event) =>
|
||||
setParameters((_) => ({
|
||||
..._,
|
||||
minimumHeight: Number(event.target.value),
|
||||
}))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
onClick={() => {
|
||||
props.done();
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
props.api?.addPanel({
|
||||
id: `id_${Date.now().toString()}`,
|
||||
component: 'default',
|
||||
title: `Tab ${nextId()}`,
|
||||
renderer: 'always',
|
||||
...parameters,
|
||||
});
|
||||
|
||||
props.done();
|
||||
}}
|
||||
>
|
||||
Go
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -10,7 +10,7 @@ export interface FrameworkDescriptor {
|
||||
}
|
||||
|
||||
const frameworks: FrameworkDescriptor[] = [
|
||||
// { value: 'JavaScript', label: 'JavaScript', icon: 'img/js-icon.svg' },
|
||||
{ value: 'JavaScript', label: 'JavaScript', icon: 'img/js-icon.svg' },
|
||||
{ value: 'React', label: 'React', icon: 'img/react-icon.svg' },
|
||||
{ value: 'Vue', label: 'Vue', icon: 'img/vue-icon.svg' },
|
||||
// { value: 'Angular', label: 'Angular' },
|
||||
|
@ -9014,6 +9014,98 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "maximumHeight",
|
||||
"code": "number | undefined",
|
||||
"kind": "accessor",
|
||||
"value": {
|
||||
"name": "maximumHeight",
|
||||
"code": "number | undefined",
|
||||
"kind": "getSignature",
|
||||
"returnType": {
|
||||
"type": "or",
|
||||
"values": [
|
||||
{
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
{
|
||||
"type": "intrinsic",
|
||||
"value": "undefined"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "maximumWidth",
|
||||
"code": "number | undefined",
|
||||
"kind": "accessor",
|
||||
"value": {
|
||||
"name": "maximumWidth",
|
||||
"code": "number | undefined",
|
||||
"kind": "getSignature",
|
||||
"returnType": {
|
||||
"type": "or",
|
||||
"values": [
|
||||
{
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
{
|
||||
"type": "intrinsic",
|
||||
"value": "undefined"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minimumHeight",
|
||||
"code": "number | undefined",
|
||||
"kind": "accessor",
|
||||
"value": {
|
||||
"name": "minimumHeight",
|
||||
"code": "number | undefined",
|
||||
"kind": "getSignature",
|
||||
"returnType": {
|
||||
"type": "or",
|
||||
"values": [
|
||||
{
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
{
|
||||
"type": "intrinsic",
|
||||
"value": "undefined"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minimumWidth",
|
||||
"code": "number | undefined",
|
||||
"kind": "accessor",
|
||||
"value": {
|
||||
"name": "minimumWidth",
|
||||
"code": "number | undefined",
|
||||
"kind": "getSignature",
|
||||
"returnType": {
|
||||
"type": "or",
|
||||
"values": [
|
||||
{
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
{
|
||||
"type": "intrinsic",
|
||||
"value": "undefined"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "params",
|
||||
"code": "Parameters | undefined",
|
||||
@ -22780,19 +22872,6 @@
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "parentElement",
|
||||
"code": "HTMLElement",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "reference",
|
||||
"value": "HTMLElement",
|
||||
"source": "typescript"
|
||||
},
|
||||
"flags": {
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "proportionalLayout",
|
||||
"code": "boolean",
|
||||
@ -23032,6 +23111,104 @@
|
||||
],
|
||||
"extends": []
|
||||
},
|
||||
"Contraints": {
|
||||
"kind": "interface",
|
||||
"name": "Contraints",
|
||||
"children": [
|
||||
{
|
||||
"name": "maximumHeight",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "maximumWidth",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minimumHeight",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minimumWidth",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"extends": []
|
||||
},
|
||||
"CreateComponentOptions": {
|
||||
"kind": "interface",
|
||||
"name": "CreateComponentOptions",
|
||||
"children": [
|
||||
{
|
||||
"name": "id",
|
||||
"code": "string",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "string"
|
||||
},
|
||||
"flags": {},
|
||||
"comment": {
|
||||
"summary": [
|
||||
{
|
||||
"kind": "text",
|
||||
"text": "The unqiue identifer of the component"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"code": "string",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "string"
|
||||
},
|
||||
"flags": {},
|
||||
"comment": {
|
||||
"summary": [
|
||||
{
|
||||
"kind": "text",
|
||||
"text": "The component name, this should determine what is rendered."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"extends": []
|
||||
},
|
||||
"DockviewDndOverlayEvent": {
|
||||
"kind": "interface",
|
||||
"name": "DockviewDndOverlayEvent",
|
||||
@ -23156,13 +23333,13 @@
|
||||
"children": [
|
||||
{
|
||||
"name": "createComponent",
|
||||
"code": "(options: { id: string, name: string }): IContentRenderer",
|
||||
"code": "(options: CreateComponentOptions): IContentRenderer",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "reflection",
|
||||
"value": {
|
||||
"name": "__type",
|
||||
"code": "(options: { id: string, name: string }): IContentRenderer",
|
||||
"code": "(options: CreateComponentOptions): IContentRenderer",
|
||||
"kind": "typeLiteral",
|
||||
"signatures": [
|
||||
{
|
||||
@ -23171,36 +23348,11 @@
|
||||
"parameters": [
|
||||
{
|
||||
"name": "options",
|
||||
"code": "options: { id: string, name: string }",
|
||||
"code": "options: CreateComponentOptions",
|
||||
"type": {
|
||||
"type": "reflection",
|
||||
"value": {
|
||||
"name": "__type",
|
||||
"code": "{ id: string, name: string }",
|
||||
"kind": "typeLiteral",
|
||||
"properties": [
|
||||
{
|
||||
"name": "id",
|
||||
"code": "string",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "string"
|
||||
},
|
||||
"flags": {}
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"code": "string",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "string"
|
||||
},
|
||||
"flags": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
"type": "reference",
|
||||
"value": "CreateComponentOptions",
|
||||
"source": "dockview-core"
|
||||
},
|
||||
"kind": "parameter"
|
||||
}
|
||||
@ -23210,7 +23362,7 @@
|
||||
"value": "IContentRenderer",
|
||||
"source": "dockview-core"
|
||||
},
|
||||
"code": "(options: { id: string, name: string }): IContentRenderer",
|
||||
"code": "(options: CreateComponentOptions): IContentRenderer",
|
||||
"kind": "callSignature"
|
||||
}
|
||||
]
|
||||
@ -23343,13 +23495,13 @@
|
||||
},
|
||||
{
|
||||
"name": "createTabComponent",
|
||||
"code": "(options: { id: string, name: string }): ITabRenderer | undefined",
|
||||
"code": "(options: CreateComponentOptions): ITabRenderer | undefined",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "reflection",
|
||||
"value": {
|
||||
"name": "__type",
|
||||
"code": "(options: { id: string, name: string }): ITabRenderer | undefined",
|
||||
"code": "(options: CreateComponentOptions): ITabRenderer | undefined",
|
||||
"kind": "typeLiteral",
|
||||
"signatures": [
|
||||
{
|
||||
@ -23358,36 +23510,11 @@
|
||||
"parameters": [
|
||||
{
|
||||
"name": "options",
|
||||
"code": "options: { id: string, name: string }",
|
||||
"code": "options: CreateComponentOptions",
|
||||
"type": {
|
||||
"type": "reflection",
|
||||
"value": {
|
||||
"name": "__type",
|
||||
"code": "{ id: string, name: string }",
|
||||
"kind": "typeLiteral",
|
||||
"properties": [
|
||||
{
|
||||
"name": "id",
|
||||
"code": "string",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "string"
|
||||
},
|
||||
"flags": {}
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"code": "string",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "string"
|
||||
},
|
||||
"flags": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
"type": "reference",
|
||||
"value": "CreateComponentOptions",
|
||||
"source": "dockview-core"
|
||||
},
|
||||
"kind": "parameter"
|
||||
}
|
||||
@ -23406,7 +23533,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"code": "(options: { id: string, name: string }): ITabRenderer | undefined",
|
||||
"code": "(options: CreateComponentOptions): ITabRenderer | undefined",
|
||||
"kind": "callSignature"
|
||||
}
|
||||
]
|
||||
@ -26716,6 +26843,26 @@
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "constraints",
|
||||
"code": "Partial<Contraints>",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "reference",
|
||||
"value": "Partial",
|
||||
"source": "typescript",
|
||||
"typeArguments": [
|
||||
{
|
||||
"type": "reference",
|
||||
"value": "Contraints",
|
||||
"source": "dockview-core"
|
||||
}
|
||||
]
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hideHeader",
|
||||
"code": "boolean",
|
||||
@ -26741,6 +26888,30 @@
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "initialHeight",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "initialWidth",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "locked",
|
||||
"code": "'no-drop-target' | boolean",
|
||||
@ -26865,6 +27036,26 @@
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "constraints",
|
||||
"code": "Partial<Contraints>",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "reference",
|
||||
"value": "Partial",
|
||||
"source": "typescript",
|
||||
"typeArguments": [
|
||||
{
|
||||
"type": "reference",
|
||||
"value": "Contraints",
|
||||
"source": "dockview-core"
|
||||
}
|
||||
]
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hideHeader",
|
||||
"code": "boolean",
|
||||
@ -26887,6 +27078,30 @@
|
||||
},
|
||||
"flags": {}
|
||||
},
|
||||
{
|
||||
"name": "initialHeight",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "initialWidth",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "locked",
|
||||
"code": "'no-drop-target' | boolean",
|
||||
@ -26964,6 +27179,54 @@
|
||||
},
|
||||
"flags": {}
|
||||
},
|
||||
{
|
||||
"name": "maximumHeight",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "maximumWidth",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minimumHeight",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minimumWidth",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "params",
|
||||
"code": "",
|
||||
@ -31160,6 +31423,58 @@
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "maximumHeight",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true,
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "maximumWidth",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true,
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minimumHeight",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true,
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minimumWidth",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true,
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "params",
|
||||
"code": "Parameters | undefined",
|
||||
@ -37257,44 +37572,6 @@
|
||||
"kind": "callSignature"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "updateParentGroup",
|
||||
"code": "(group: DockviewGroupPanel, visible: boolean): void",
|
||||
"kind": "method",
|
||||
"signature": [
|
||||
{
|
||||
"name": "updateParentGroup",
|
||||
"typeParameters": [],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "group",
|
||||
"code": "group: DockviewGroupPanel",
|
||||
"type": {
|
||||
"type": "reference",
|
||||
"value": "DockviewGroupPanel",
|
||||
"source": "dockview-core"
|
||||
},
|
||||
"kind": "parameter"
|
||||
},
|
||||
{
|
||||
"name": "visible",
|
||||
"code": "visible: boolean",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "boolean"
|
||||
},
|
||||
"kind": "parameter"
|
||||
}
|
||||
],
|
||||
"returnType": {
|
||||
"type": "intrinsic",
|
||||
"value": "void"
|
||||
},
|
||||
"code": "(group: DockviewGroupPanel, visible: boolean): void",
|
||||
"kind": "callSignature"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"extends": [
|
||||
@ -41037,11 +41314,23 @@
|
||||
},
|
||||
"AddPanelOptions": {
|
||||
"name": "AddPanelOptions",
|
||||
"code": "Partial<AddPanelOptionsUnion> & { component: string, id: string, inactive?: boolean, params?: P, renderer?: DockviewPanelRenderer, tabComponent?: string, title?: string }",
|
||||
"code": "Partial<Contraints> & Partial<AddPanelOptionsUnion> & { component: string, id: string, inactive?: boolean, initialHeight?: number, initialWidth?: number, params?: P, renderer?: DockviewPanelRenderer, tabComponent?: string, title?: string }",
|
||||
"typeParameters": [],
|
||||
"type": {
|
||||
"type": "intersection",
|
||||
"values": [
|
||||
{
|
||||
"type": "reference",
|
||||
"value": "Partial",
|
||||
"source": "typescript",
|
||||
"typeArguments": [
|
||||
{
|
||||
"type": "reference",
|
||||
"value": "Contraints",
|
||||
"source": "dockview-core"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "reference",
|
||||
"value": "Partial",
|
||||
@ -41058,7 +41347,7 @@
|
||||
"type": "reflection",
|
||||
"value": {
|
||||
"name": "__type",
|
||||
"code": "{ component: string, id: string, inactive?: boolean, params?: P, renderer?: DockviewPanelRenderer, tabComponent?: string, title?: string }",
|
||||
"code": "{ component: string, id: string, inactive?: boolean, initialHeight?: number, initialWidth?: number, params?: P, renderer?: DockviewPanelRenderer, tabComponent?: string, title?: string }",
|
||||
"kind": "typeLiteral",
|
||||
"properties": [
|
||||
{
|
||||
@ -41125,6 +41414,30 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "initialHeight",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "initialWidth",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "params",
|
||||
"code": "P",
|
||||
|
@ -50,9 +50,14 @@ const components = {
|
||||
</div>
|
||||
);
|
||||
},
|
||||
iframe: () => {
|
||||
iframe: (props: IDockviewPanelProps) => {
|
||||
return (
|
||||
<iframe
|
||||
onMouseDown={() => {
|
||||
if (!props.api.isActive) {
|
||||
props.api.setActive();
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
|
@ -50,8 +50,7 @@ const Watermark = (props: IWatermarkPanelProps) => {
|
||||
}}
|
||||
>
|
||||
<span>
|
||||
This is a custom watermark. You can put whatever React
|
||||
component you want here
|
||||
This is a custom watermark. You can change this content.
|
||||
</span>
|
||||
<span>
|
||||
<button onClick={addPanel}>Add New Panel</button>
|
||||
|
135
packages/docs/templates/dockview/watermark/typescript/src/index.ts
vendored
Normal file
135
packages/docs/templates/dockview/watermark/typescript/src/index.ts
vendored
Normal file
@ -0,0 +1,135 @@
|
||||
import 'dockview-core/dist/styles/dockview.css';
|
||||
import {
|
||||
createDockview,
|
||||
DockviewApi,
|
||||
GroupPanelPartInitParameters,
|
||||
IContentRenderer,
|
||||
IDockviewGroupPanel,
|
||||
IWatermarkRenderer,
|
||||
WatermarkRendererInitParameters,
|
||||
} from 'dockview-core';
|
||||
|
||||
class Panel implements IContentRenderer {
|
||||
private readonly _element: HTMLElement;
|
||||
|
||||
get element(): HTMLElement {
|
||||
return this._element;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this._element = document.createElement('div');
|
||||
this._element.style.color = 'white';
|
||||
}
|
||||
|
||||
init(parameters: GroupPanelPartInitParameters): void {
|
||||
this._element.textContent = 'Hello World';
|
||||
}
|
||||
}
|
||||
|
||||
class Watermark implements IWatermarkRenderer {
|
||||
private readonly _element: HTMLElement;
|
||||
|
||||
get element(): HTMLElement {
|
||||
return this._element;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
const element = document.createElement('div');
|
||||
element.style.height = '100%';
|
||||
element.style.display = 'flex';
|
||||
element.style.justifyContent = 'center';
|
||||
element.style.alignItems = 'center';
|
||||
element.style.color = 'white';
|
||||
|
||||
this._element = element;
|
||||
}
|
||||
|
||||
init(params: WatermarkRendererInitParameters): void {
|
||||
this.build(params.containerApi, params.group);
|
||||
}
|
||||
|
||||
private build(api: DockviewApi, group?: IDockviewGroupPanel): void {
|
||||
const container = document.createElement('div');
|
||||
container.style.display = 'flex';
|
||||
container.style.flexDirection = 'column';
|
||||
|
||||
const text = document.createElement('span');
|
||||
text.textContent =
|
||||
'This is a custom watermark. You can change this content.';
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.textContent = 'Add New Panel';
|
||||
button.addEventListener('click', () => {
|
||||
api.addPanel({
|
||||
id: Date.now().toString(),
|
||||
component: 'default',
|
||||
});
|
||||
});
|
||||
|
||||
const button2 = document.createElement('button');
|
||||
button2.textContent = 'Close Group';
|
||||
button2.addEventListener('click', () => {
|
||||
api.addPanel({
|
||||
id: Date.now().toString(),
|
||||
component: 'default',
|
||||
});
|
||||
});
|
||||
|
||||
container.append(text, button, button2);
|
||||
this.element.append(container);
|
||||
|
||||
api.onDidLayoutChange(() => {
|
||||
button2.style.display = api.groups.length > 0 ? '' : 'none';
|
||||
});
|
||||
|
||||
button2.addEventListener('click', () => {
|
||||
group?.api.close();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const root = document.createElement('div');
|
||||
root.style.display = 'flex';
|
||||
root.style.flexDirection = 'column';
|
||||
root.style.height = '100%';
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.textContent = 'Add Empty Group';
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.style.flexGrow = '1';
|
||||
|
||||
root.append(button, container);
|
||||
|
||||
const app = document.getElementById('app');
|
||||
app.append(root);
|
||||
|
||||
const api = createDockview(container, {
|
||||
className: 'dockview-theme-abyss',
|
||||
createComponent: (options) => {
|
||||
switch (options.name) {
|
||||
case 'default':
|
||||
return new Panel();
|
||||
}
|
||||
},
|
||||
createWatermarkComponent: () => {
|
||||
return new Watermark();
|
||||
},
|
||||
});
|
||||
|
||||
api.addPanel({
|
||||
id: 'panel_1',
|
||||
component: 'default',
|
||||
title: 'Panel 1',
|
||||
});
|
||||
|
||||
api.addPanel({
|
||||
id: 'panel_2',
|
||||
component: 'default',
|
||||
position: { referencePanel: 'panel_1', direction: 'right' },
|
||||
title: 'Panel 2',
|
||||
});
|
||||
|
||||
button.addEventListener('click', () => {
|
||||
api.addGroup();
|
||||
});
|
Loading…
Reference in New Issue
Block a user