mirror of
https://github.com/mathuo/dockview
synced 2025-05-01 17:18:27 +00:00
Compare commits
63 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1e63da807b | ||
|
68d7947dea | ||
|
093a034738 | ||
|
f9ca5b99d5 | ||
|
420466398d | ||
|
20b5c844f3 | ||
|
6d2f2f1012 | ||
|
3ddea55834 | ||
|
2f334c63c1 | ||
|
8334f9795c | ||
|
7ea3154946 | ||
|
1ef3dc06ce | ||
|
1ff74f2e65 | ||
|
a82aac09bc | ||
|
d1239a5ee5 | ||
|
22deb851dc | ||
|
87f257df1e | ||
|
a92a056981 | ||
|
c3e203f420 | ||
|
8bdd15161c | ||
|
8a3a7e5063 | ||
|
65d95f1271 | ||
|
3ec6627013 | ||
|
c0227d620c | ||
|
aad168da84 | ||
|
dfee4111a2 | ||
|
712f3f860d | ||
|
f545a0a5c7 | ||
|
e3d39fd2ed | ||
|
dca0eb0df7 | ||
|
8188fd9429 | ||
|
54a51ed10b | ||
|
1a11a4ba2c | ||
|
b6d83df1aa | ||
|
6444e4cb7d | ||
|
ca7bd0a86d | ||
|
dc828b7658 | ||
|
6e02e59fec | ||
|
f79bbe0a6a | ||
|
12448e006f | ||
|
5e380affe7 | ||
|
a44fc01f34 | ||
|
8e03e584a7 | ||
|
1ddcaefe80 | ||
|
d086dfd081 | ||
|
b231367e44 | ||
|
bba22fedd4 | ||
|
3ebcb8eaef | ||
|
39dd5f0759 | ||
|
e4f07dfbda | ||
|
d30263af67 | ||
|
54ae457ccd | ||
|
416039bc99 | ||
|
e8fdabba08 | ||
|
9373802115 | ||
|
759dcc7b05 | ||
|
f8faca731d | ||
|
d168356344 | ||
|
64e11a880c | ||
|
a306742508 | ||
|
6511b8d936 | ||
|
0c1b8ce4d7 | ||
|
f40532f272 |
@ -35,4 +35,4 @@ Please see the website: https://dockview.dev
|
||||
- Transparent builds and Code Analysis
|
||||
- Security at mind - verifed publishing and builds through GitHub Actions
|
||||
|
||||
Want to verify our builds? Go [here](https://www.npmjs.com/package/dockview#Provenance).
|
||||
Want to verify our builds? Go [here](https://www.npmjs.com/package/dockview#user-content-provenance).
|
||||
|
@ -2,7 +2,7 @@
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "4.0.0",
|
||||
"version": "4.2.5",
|
||||
"npmClient": "yarn",
|
||||
"command": {
|
||||
"publish": {
|
||||
|
@ -58,7 +58,7 @@
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"jest-sonar-reporter": "^2.0.0",
|
||||
"jsdom": "^23.0.1",
|
||||
"lerna": "^8.0.1",
|
||||
"lerna": "^8.2.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"rimraf": "^5.0.5",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dockview-angular",
|
||||
"version": "4.0.0",
|
||||
"version": "4.2.5",
|
||||
"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": "^4.0.0"
|
||||
"dockview-core": "^4.2.5"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dockview-core",
|
||||
"version": "4.0.0",
|
||||
"version": "4.2.5",
|
||||
"description": "Zero dependency layout manager supporting tabs, grids and splitviews",
|
||||
"keywords": [
|
||||
"splitview",
|
||||
|
@ -0,0 +1,66 @@
|
||||
import { Tabs } from '../../../../dockview/components/titlebar/tabs';
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import { DockviewGroupPanel } from '../../../../dockview/dockviewGroupPanel';
|
||||
import { DockviewComponent } from '../../../../dockview/dockviewComponent';
|
||||
|
||||
describe('tabs', () => {
|
||||
describe('disableCustomScrollbars', () => {
|
||||
test('enabled by default', () => {
|
||||
const cut = new Tabs(
|
||||
fromPartial<DockviewGroupPanel>({}),
|
||||
fromPartial<DockviewComponent>({
|
||||
options: {},
|
||||
}),
|
||||
{
|
||||
showTabsOverflowControl: true,
|
||||
}
|
||||
);
|
||||
|
||||
expect(
|
||||
cut.element.querySelectorAll(
|
||||
'.dv-scrollable > .dv-tabs-container'
|
||||
).length
|
||||
).toBe(1);
|
||||
});
|
||||
|
||||
test('enabled when disabled flag is false', () => {
|
||||
const cut = new Tabs(
|
||||
fromPartial<DockviewGroupPanel>({}),
|
||||
fromPartial<DockviewComponent>({
|
||||
options: {
|
||||
scrollbars: 'custom',
|
||||
},
|
||||
}),
|
||||
{
|
||||
showTabsOverflowControl: true,
|
||||
}
|
||||
);
|
||||
|
||||
expect(
|
||||
cut.element.querySelectorAll(
|
||||
'.dv-scrollable > .dv-tabs-container'
|
||||
).length
|
||||
).toBe(1);
|
||||
});
|
||||
|
||||
test('disabled when disabled flag is true', () => {
|
||||
const cut = new Tabs(
|
||||
fromPartial<DockviewGroupPanel>({}),
|
||||
fromPartial<DockviewComponent>({
|
||||
options: {
|
||||
scrollbars: 'native',
|
||||
},
|
||||
}),
|
||||
{
|
||||
showTabsOverflowControl: true,
|
||||
}
|
||||
);
|
||||
|
||||
expect(
|
||||
cut.element.querySelectorAll(
|
||||
'.dv-scrollable > .dv-tabs-container'
|
||||
).length
|
||||
).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
@ -272,6 +272,59 @@ describe('dockviewComponent', () => {
|
||||
});
|
||||
|
||||
describe('move group', () => {
|
||||
test('that moving a popup group into the grid manages view disposals correctly', async () => {
|
||||
window.open = () => setupMockWindow();
|
||||
|
||||
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' },
|
||||
});
|
||||
|
||||
await dockview.addPopoutGroup(panel1.api.group);
|
||||
|
||||
expect(panel1.api.location.type).toBe('popout');
|
||||
expect(dockview.groups.length).toBe(4);
|
||||
expect(dockview.panels.length).toBe(3);
|
||||
|
||||
panel1.api.group.api.moveTo({
|
||||
group: panel2.api.group,
|
||||
position: 'left',
|
||||
});
|
||||
|
||||
expect(panel1.api.location.type).toBe('grid');
|
||||
expect(dockview.groups.length).toBe(3);
|
||||
expect(dockview.panels.length).toBe(3);
|
||||
|
||||
const query = dockview.element.querySelectorAll('.dv-view');
|
||||
expect(query.length).toBe(3);
|
||||
});
|
||||
|
||||
test('horizontal', () => {
|
||||
dockview = new DockviewComponent(container, {
|
||||
createComponent(options) {
|
||||
@ -6729,4 +6782,78 @@ describe('dockviewComponent', () => {
|
||||
expect(api.panels.length).toBe(3);
|
||||
expect(api.groups.length).toBe(3);
|
||||
});
|
||||
|
||||
test('add group with custom group is', () => {
|
||||
const container = document.createElement('div');
|
||||
|
||||
const dockview = new DockviewComponent(container, {
|
||||
createComponent(options) {
|
||||
switch (options.name) {
|
||||
case 'default':
|
||||
return new PanelContentPartTest(
|
||||
options.id,
|
||||
options.name
|
||||
);
|
||||
default:
|
||||
throw new Error(`unsupported`);
|
||||
}
|
||||
},
|
||||
});
|
||||
const api = new DockviewApi(dockview);
|
||||
|
||||
dockview.layout(1000, 1000);
|
||||
|
||||
const panel1 = api.addPanel({
|
||||
id: 'panel_1',
|
||||
component: 'default',
|
||||
});
|
||||
|
||||
const group1 = api.addGroup({
|
||||
id: 'group_1',
|
||||
direction: 'left',
|
||||
});
|
||||
|
||||
const group2 = api.addGroup({
|
||||
id: 'group_2',
|
||||
direction: 'left',
|
||||
referencePanel: panel1,
|
||||
});
|
||||
|
||||
const group3 = api.addGroup({
|
||||
id: 'group_3',
|
||||
direction: 'left',
|
||||
referenceGroup: panel1.api.group,
|
||||
});
|
||||
|
||||
expect(group1.api.id).toBe('group_1');
|
||||
expect(group2.api.id).toBe('group_2');
|
||||
expect(group3.api.id).toBe('group_3');
|
||||
});
|
||||
|
||||
describe('dndEdges', () => {
|
||||
test('that can init dndEdges property', () => {
|
||||
const container = document.createElement('div');
|
||||
|
||||
const dockview = new DockviewComponent(container, {
|
||||
createComponent(options) {
|
||||
switch (options.name) {
|
||||
case 'default':
|
||||
return new PanelContentPartTest(
|
||||
options.id,
|
||||
options.name
|
||||
);
|
||||
default:
|
||||
throw new Error(`unsupported`);
|
||||
}
|
||||
},
|
||||
dndEdges: {
|
||||
size: { value: 100, type: 'pixels' },
|
||||
activationSize: { value: 5, type: 'percentage' },
|
||||
},
|
||||
});
|
||||
const api = new DockviewApi(dockview);
|
||||
|
||||
dockview.layout(1000, 1000);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -3,7 +3,6 @@ import {
|
||||
Emitter,
|
||||
Event,
|
||||
addDisposableListener,
|
||||
addDisposableWindowListener,
|
||||
} from '../events';
|
||||
|
||||
describe('events', () => {
|
||||
@ -143,7 +142,7 @@ describe('events', () => {
|
||||
expect(value).toBe(3);
|
||||
});
|
||||
|
||||
it('addDisposableWindowListener with capture options', () => {
|
||||
it('addDisposableListener with capture options', () => {
|
||||
const element = {
|
||||
addEventListener: jest.fn(),
|
||||
removeEventListener: jest.fn(),
|
||||
@ -151,7 +150,7 @@ describe('events', () => {
|
||||
|
||||
const handler = jest.fn();
|
||||
|
||||
const disposable = addDisposableWindowListener(
|
||||
const disposable = addDisposableListener(
|
||||
element as any,
|
||||
'pointerdown',
|
||||
handler,
|
||||
@ -177,7 +176,7 @@ describe('events', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('addDisposableWindowListener without capture options', () => {
|
||||
it('addDisposableListener without capture options', () => {
|
||||
const element = {
|
||||
addEventListener: jest.fn(),
|
||||
removeEventListener: jest.fn(),
|
||||
@ -185,7 +184,7 @@ describe('events', () => {
|
||||
|
||||
const handler = jest.fn();
|
||||
|
||||
const disposable = addDisposableWindowListener(
|
||||
const disposable = addDisposableListener(
|
||||
element as any,
|
||||
'pointerdown',
|
||||
handler
|
||||
|
@ -198,6 +198,8 @@ describe('gridview', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(container.querySelectorAll('.dv-grid-view').length).toBe(1);
|
||||
|
||||
gridview.layout(800, 400);
|
||||
gridview.fromJSON({
|
||||
grid: {
|
||||
@ -242,6 +244,9 @@ describe('gridview', () => {
|
||||
},
|
||||
activePanel: 'panel_1',
|
||||
});
|
||||
|
||||
expect(container.querySelectorAll('.dv-grid-view').length).toBe(1);
|
||||
|
||||
gridview.layout(800, 400, true);
|
||||
|
||||
const panel1 = gridview.getPanel('panel_1')!;
|
||||
|
@ -56,22 +56,28 @@ describe('paneview', () => {
|
||||
paneview.onDidRemoveView((view) => removed.push(view))
|
||||
);
|
||||
|
||||
const view1 = new TestPanel(
|
||||
'id',
|
||||
'component',
|
||||
'headerComponent',
|
||||
Orientation.VERTICAL,
|
||||
true,
|
||||
true
|
||||
);
|
||||
const view2 = new TestPanel(
|
||||
'id2',
|
||||
'component',
|
||||
'headerComponent',
|
||||
Orientation.VERTICAL,
|
||||
true,
|
||||
true
|
||||
);
|
||||
const view1 = new TestPanel({
|
||||
id: 'id',
|
||||
component: 'component',
|
||||
headerComponent: 'headerComponent',
|
||||
orientation: Orientation.VERTICAL,
|
||||
isExpanded: true,
|
||||
isHeaderVisible: true,
|
||||
headerSize: 22,
|
||||
minimumBodySize: 0,
|
||||
maximumBodySize: Number.MAX_SAFE_INTEGER,
|
||||
});
|
||||
const view2 = new TestPanel({
|
||||
id: 'id2',
|
||||
component: 'component',
|
||||
headerComponent: 'headerComponent',
|
||||
orientation: Orientation.VERTICAL,
|
||||
isExpanded: true,
|
||||
isHeaderVisible: true,
|
||||
headerSize: 22,
|
||||
minimumBodySize: 0,
|
||||
maximumBodySize: Number.MAX_SAFE_INTEGER,
|
||||
});
|
||||
|
||||
expect(added.length).toBe(0);
|
||||
expect(removed.length).toBe(0);
|
||||
@ -106,22 +112,28 @@ describe('paneview', () => {
|
||||
orientation: Orientation.HORIZONTAL,
|
||||
});
|
||||
|
||||
const view1 = new TestPanel(
|
||||
'id',
|
||||
'component',
|
||||
'headerComponent',
|
||||
Orientation.VERTICAL,
|
||||
true,
|
||||
true
|
||||
);
|
||||
const view2 = new TestPanel(
|
||||
'id2',
|
||||
'component',
|
||||
'headerComponent',
|
||||
Orientation.VERTICAL,
|
||||
true,
|
||||
true
|
||||
);
|
||||
const view1 = new TestPanel({
|
||||
id: 'id',
|
||||
component: 'component',
|
||||
headerComponent: 'headerComponent',
|
||||
orientation: Orientation.VERTICAL,
|
||||
isExpanded: true,
|
||||
isHeaderVisible: true,
|
||||
headerSize: 22,
|
||||
minimumBodySize: 0,
|
||||
maximumBodySize: Number.MAX_SAFE_INTEGER,
|
||||
});
|
||||
const view2 = new TestPanel({
|
||||
id: 'id2',
|
||||
component: 'component',
|
||||
headerComponent: 'headerComponent',
|
||||
orientation: Orientation.VERTICAL,
|
||||
isExpanded: true,
|
||||
isHeaderVisible: true,
|
||||
headerSize: 22,
|
||||
minimumBodySize: 0,
|
||||
maximumBodySize: Number.MAX_SAFE_INTEGER,
|
||||
});
|
||||
|
||||
paneview.addPane(view1);
|
||||
paneview.addPane(view2);
|
||||
|
@ -11,7 +11,17 @@ import { Orientation } from '../../splitview/splitview';
|
||||
|
||||
class TestPanel extends PaneviewPanel {
|
||||
constructor(id: string, component: string) {
|
||||
super(id, component, 'header', Orientation.VERTICAL, false, true);
|
||||
super({
|
||||
id,
|
||||
component,
|
||||
headerComponent: 'header',
|
||||
orientation: Orientation.VERTICAL,
|
||||
isExpanded: false,
|
||||
isHeaderVisible: true,
|
||||
headerSize: 22,
|
||||
minimumBodySize: 0,
|
||||
maximumBodySize: Number.MAX_SAFE_INTEGER,
|
||||
});
|
||||
}
|
||||
|
||||
getHeaderComponent() {
|
||||
@ -59,7 +69,7 @@ class TestPanel extends PaneviewPanel {
|
||||
}
|
||||
}
|
||||
|
||||
describe('componentPaneview', () => {
|
||||
describe('paneviewComponent', () => {
|
||||
let container: HTMLElement;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -180,6 +190,8 @@ describe('componentPaneview', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(container.querySelectorAll('.dv-pane-container').length).toBe(1);
|
||||
|
||||
paneview.fromJSON({
|
||||
size: 6,
|
||||
views: [
|
||||
@ -212,6 +224,8 @@ describe('componentPaneview', () => {
|
||||
],
|
||||
});
|
||||
|
||||
expect(container.querySelectorAll('.dv-pane-container').length).toBe(1);
|
||||
|
||||
paneview.layout(400, 800);
|
||||
|
||||
const panel1 = paneview.getPanel('panel1');
|
||||
@ -255,7 +269,7 @@ describe('componentPaneview', () => {
|
||||
title: 'Panel 1',
|
||||
},
|
||||
expanded: true,
|
||||
minimumSize: 100,
|
||||
headerSize: 22,
|
||||
},
|
||||
{
|
||||
size: 22,
|
||||
@ -265,7 +279,7 @@ describe('componentPaneview', () => {
|
||||
title: 'Panel 2',
|
||||
},
|
||||
expanded: false,
|
||||
minimumSize: 100,
|
||||
headerSize: 22,
|
||||
},
|
||||
{
|
||||
size: 22,
|
||||
@ -275,7 +289,7 @@ describe('componentPaneview', () => {
|
||||
title: 'Panel 3',
|
||||
},
|
||||
expanded: false,
|
||||
minimumSize: 100,
|
||||
headerSize: 22,
|
||||
},
|
||||
],
|
||||
});
|
||||
@ -450,6 +464,7 @@ describe('componentPaneview', () => {
|
||||
component: 'default',
|
||||
title: 'Panel 1',
|
||||
},
|
||||
minimumSize: 100,
|
||||
expanded: true,
|
||||
},
|
||||
{
|
||||
@ -486,26 +501,27 @@ describe('componentPaneview', () => {
|
||||
},
|
||||
expanded: true,
|
||||
minimumSize: 100,
|
||||
headerSize: 22,
|
||||
},
|
||||
{
|
||||
size: 122,
|
||||
size: 22,
|
||||
data: {
|
||||
id: 'panel2',
|
||||
component: 'default',
|
||||
title: 'Panel 2',
|
||||
},
|
||||
expanded: true,
|
||||
minimumSize: 100,
|
||||
headerSize: 22,
|
||||
},
|
||||
{
|
||||
size: 356,
|
||||
size: 456,
|
||||
data: {
|
||||
id: 'panel3',
|
||||
component: 'default',
|
||||
title: 'Panel 3',
|
||||
},
|
||||
expanded: true,
|
||||
minimumSize: 100,
|
||||
headerSize: 22,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
@ -395,6 +395,10 @@ describe('componentSplitview', () => {
|
||||
});
|
||||
splitview.layout(400, 6);
|
||||
|
||||
expect(
|
||||
container.querySelectorAll('.dv-split-view-container').length
|
||||
).toBe(1);
|
||||
|
||||
splitview.fromJSON({
|
||||
views: [
|
||||
{
|
||||
@ -414,6 +418,10 @@ describe('componentSplitview', () => {
|
||||
activeView: 'panel1',
|
||||
});
|
||||
|
||||
expect(
|
||||
container.querySelectorAll('.dv-split-view-container').length
|
||||
).toBe(1);
|
||||
|
||||
expect(splitview.length).toBe(3);
|
||||
|
||||
expect(JSON.parse(JSON.stringify(splitview.toJSON()))).toEqual({
|
||||
|
@ -3,6 +3,8 @@ import {
|
||||
FloatingGroupOptions,
|
||||
IDockviewComponent,
|
||||
MovePanelEvent,
|
||||
PopoutGroupChangePositionEvent,
|
||||
PopoutGroupChangeSizeEvent,
|
||||
SerializedDockview,
|
||||
} from '../dockview/dockviewComponent';
|
||||
import {
|
||||
@ -629,7 +631,6 @@ export class DockviewApi implements CommonApi<SerializedDockview> {
|
||||
return this.component.totalPanels;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Invoked when the active group changes. May be undefined if no group is active.
|
||||
*/
|
||||
@ -740,6 +741,14 @@ export class DockviewApi implements CommonApi<SerializedDockview> {
|
||||
return this.component.onUnhandledDragOverEvent;
|
||||
}
|
||||
|
||||
get onDidPopoutGroupSizeChange(): Event<PopoutGroupChangeSizeEvent> {
|
||||
return this.component.onDidPopoutGroupSizeChange;
|
||||
}
|
||||
|
||||
get onDidPopoutGroupPositionChange(): Event<PopoutGroupChangePositionEvent> {
|
||||
return this.component.onDidPopoutGroupPositionChange;
|
||||
}
|
||||
|
||||
/**
|
||||
* All panel objects.
|
||||
*/
|
||||
|
@ -8,6 +8,9 @@ export function addGhostImage(
|
||||
// class dockview provides to force ghost image to be drawn on a different layer and prevent weird rendering issues
|
||||
addClasses(ghostElement, 'dv-dragged');
|
||||
|
||||
// move the element off-screen initially otherwise it may in some cases be rendered at (0,0) momentarily
|
||||
ghostElement.style.top = '-9999px';
|
||||
|
||||
document.body.appendChild(ghostElement);
|
||||
dataTransfer.setDragImage(ghostElement, options?.x ?? 0, options?.y ?? 0);
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { addDisposableWindowListener } from '../../events';
|
||||
import { shiftAbsoluteElementIntoView } from '../../dom';
|
||||
import { addDisposableListener } from '../../events';
|
||||
import {
|
||||
CompositeDisposable,
|
||||
Disposable,
|
||||
@ -29,13 +30,13 @@ export class PopupService extends CompositeDisposable {
|
||||
|
||||
openPopover(
|
||||
element: HTMLElement,
|
||||
position: { x: number; y: number }
|
||||
position: { x: number; y: number; zIndex?: string }
|
||||
): void {
|
||||
this.close();
|
||||
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.style.position = 'absolute';
|
||||
wrapper.style.zIndex = '99';
|
||||
wrapper.style.zIndex = position.zIndex ?? 'var(--dv-overlay-z-index)';
|
||||
wrapper.appendChild(element);
|
||||
|
||||
const anchorBox = this._element.getBoundingClientRect();
|
||||
@ -50,7 +51,7 @@ export class PopupService extends CompositeDisposable {
|
||||
this._active = wrapper;
|
||||
|
||||
this._activeDisposable.value = new CompositeDisposable(
|
||||
addDisposableWindowListener(window, 'pointerdown', (event) => {
|
||||
addDisposableListener(window, 'pointerdown', (event) => {
|
||||
const target = event.target;
|
||||
|
||||
if (!(target instanceof HTMLElement)) {
|
||||
@ -70,6 +71,10 @@ export class PopupService extends CompositeDisposable {
|
||||
this.close();
|
||||
})
|
||||
);
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
shiftAbsoluteElementIntoView(wrapper, this.root);
|
||||
});
|
||||
}
|
||||
|
||||
close(): void {
|
||||
|
@ -1,20 +1,11 @@
|
||||
.dv-tabs-container {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
overflow: auto;
|
||||
scrollbar-width: thin; // firefox
|
||||
|
||||
&.dv-horizontal {
|
||||
.dv-tabs-container {
|
||||
.dv-tab {
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&:not(:nth-last-child(1)) {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&:not(:first-child)::before {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
@ -28,7 +19,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
height: 3px;
|
||||
@ -45,6 +35,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
.dv-scrollable {
|
||||
> .dv-tabs-container {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.dv-tab {
|
||||
-webkit-user-drag: element;
|
||||
outline: none;
|
||||
|
@ -101,13 +101,17 @@ export class Tabs extends CompositeDisposable {
|
||||
|
||||
this.showTabsOverflowControl = options.showTabsOverflowControl;
|
||||
|
||||
if (accessor.options.scrollbars === 'native') {
|
||||
this._element = this._tabsList;
|
||||
} else {
|
||||
const scrollbar = new Scrollbar(this._tabsList);
|
||||
this._element = scrollbar.element;
|
||||
this.addDisposables(scrollbar);
|
||||
}
|
||||
|
||||
this.addDisposables(
|
||||
this._onOverflowTabsChange,
|
||||
this._observerDisposable,
|
||||
scrollbar,
|
||||
this._onWillShowOverlay,
|
||||
this._onDrop,
|
||||
this._onTabDragStart,
|
||||
|
@ -7,11 +7,16 @@
|
||||
font-size: var(--dv-tabs-and-actions-container-font-size);
|
||||
|
||||
&.dv-single-tab.dv-full-width-single-tab {
|
||||
.dv-scrollable {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.dv-tabs-container {
|
||||
flex-grow: 1;
|
||||
|
||||
.dv-tab {
|
||||
flex-grow: 1;
|
||||
padding: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ import { addDisposableListener, Emitter, Event } from '../../../events';
|
||||
import { Tab } from '../tab/tab';
|
||||
import { DockviewGroupPanel } from '../../dockviewGroupPanel';
|
||||
import { VoidContainer } from './voidContainer';
|
||||
import { toggleClass } from '../../../dom';
|
||||
import { findRelativeZIndexParent, toggleClass } from '../../../dom';
|
||||
import { IDockviewPanel } from '../../dockviewPanel';
|
||||
import { DockviewComponent } from '../../dockviewComponent';
|
||||
import { WillShowOverlayLocationEvent } from '../../dockviewGroupPanelModel';
|
||||
@ -152,6 +152,8 @@ export class TabsContainer
|
||||
this._element.appendChild(this.rightActionsContainer);
|
||||
|
||||
this.addDisposables(
|
||||
this.tabs.onDrop((e) => this._onDrop.fire(e)),
|
||||
this.tabs.onWillShowOverlay((e) => this._onWillShowOverlay.fire(e)),
|
||||
accessor.onDidOptionsChange(() => {
|
||||
this.tabs.showTabsOverflowControl =
|
||||
!accessor.options.disableTabsOverflowList;
|
||||
@ -376,7 +378,7 @@ export class TabsContainer
|
||||
!panelObject.api.isActive
|
||||
);
|
||||
|
||||
wrapper.addEventListener('mousedown', () => {
|
||||
wrapper.addEventListener('pointerdown', () => {
|
||||
this.accessor.popupService.close();
|
||||
tab.element.scrollIntoView();
|
||||
tab.panel.api.setActive();
|
||||
@ -386,9 +388,14 @@ export class TabsContainer
|
||||
el.appendChild(wrapper);
|
||||
}
|
||||
|
||||
const relativeParent = findRelativeZIndexParent(root);
|
||||
|
||||
this.accessor.popupService.openPopover(el, {
|
||||
x: event.clientX,
|
||||
y: event.clientY,
|
||||
zIndex: relativeParent?.style.zIndex
|
||||
? `calc(${relativeParent.style.zIndex} * 2)`
|
||||
: undefined,
|
||||
});
|
||||
})
|
||||
);
|
||||
|
@ -18,10 +18,8 @@
|
||||
|
||||
.dv-groupview {
|
||||
&.dv-active-group {
|
||||
> .dv-tabs-and-actions-container
|
||||
> .dv-scrollable
|
||||
> .dv-tabs-container
|
||||
> .dv-tab {
|
||||
> .dv-tabs-and-actions-container {
|
||||
.dv-tabs-container > .dv-tab {
|
||||
&.dv-active-tab {
|
||||
background-color: var(
|
||||
--dv-activegroup-visiblepanel-tab-background-color
|
||||
@ -36,11 +34,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.dv-inactive-group {
|
||||
> .dv-tabs-and-actions-container
|
||||
> .dv-scrollable
|
||||
> .dv-tabs-container
|
||||
> .dv-tab {
|
||||
> .dv-tabs-and-actions-container {
|
||||
.dv-tabs-container > .dv-tab {
|
||||
&.dv-active-tab {
|
||||
background-color: var(
|
||||
--dv-inactivegroup-visiblepanel-tab-background-color
|
||||
@ -56,6 +53,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* when a tab is dragged we lose the above stylings because they are conditional on parent elements
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
import { tail, sequenceEquals, remove } from '../array';
|
||||
import { DockviewPanel, IDockviewPanel } from './dockviewPanel';
|
||||
import { CompositeDisposable, Disposable } from '../lifecycle';
|
||||
import { Event, Emitter, addDisposableWindowListener } from '../events';
|
||||
import { Event, Emitter, addDisposableListener } from '../events';
|
||||
import { Watermark } from './components/watermark/watermark';
|
||||
import { IWatermarkRenderer, GroupviewPanelState } from './types';
|
||||
import { sequentialNumberGenerator } from '../math';
|
||||
@ -56,6 +56,8 @@ import {
|
||||
addTestId,
|
||||
Classnames,
|
||||
getDockviewTheme,
|
||||
onDidWindowResizeEnd,
|
||||
onDidWindowMoveEnd,
|
||||
toggleClass,
|
||||
watchElementResize,
|
||||
} from '../dom';
|
||||
@ -190,6 +192,18 @@ export interface DockviewMaximizedGroupChanged {
|
||||
isMaximized: boolean;
|
||||
}
|
||||
|
||||
export interface PopoutGroupChangeSizeEvent {
|
||||
width: number;
|
||||
height: number;
|
||||
group: DockviewGroupPanel;
|
||||
}
|
||||
|
||||
export interface PopoutGroupChangePositionEvent {
|
||||
screenX: number;
|
||||
screenY: number;
|
||||
group: DockviewGroupPanel;
|
||||
}
|
||||
|
||||
export interface IDockviewComponent extends IBaseGrid<DockviewGroupPanel> {
|
||||
readonly activePanel: IDockviewPanel | undefined;
|
||||
readonly totalPanels: number;
|
||||
@ -210,6 +224,8 @@ export interface IDockviewComponent extends IBaseGrid<DockviewGroupPanel> {
|
||||
readonly onUnhandledDragOverEvent: Event<DockviewDndOverlayEvent>;
|
||||
readonly onDidMovePanel: Event<MovePanelEvent>;
|
||||
readonly onDidMaximizedGroupChange: Event<DockviewMaximizedGroupChanged>;
|
||||
readonly onDidPopoutGroupSizeChange: Event<PopoutGroupChangeSizeEvent>;
|
||||
readonly onDidPopoutGroupPositionChange: Event<PopoutGroupChangePositionEvent>;
|
||||
readonly options: DockviewComponentOptions;
|
||||
updateOptions(options: DockviewOptions): void;
|
||||
moveGroupOrPanel(options: MoveGroupOrPanelOptions): void;
|
||||
@ -293,6 +309,16 @@ export class DockviewComponent
|
||||
private readonly _onDidAddPanel = new Emitter<IDockviewPanel>();
|
||||
readonly onDidAddPanel: Event<IDockviewPanel> = this._onDidAddPanel.event;
|
||||
|
||||
private readonly _onDidPopoutGroupSizeChange =
|
||||
new Emitter<PopoutGroupChangeSizeEvent>();
|
||||
readonly onDidPopoutGroupSizeChange: Event<PopoutGroupChangeSizeEvent> =
|
||||
this._onDidPopoutGroupSizeChange.event;
|
||||
|
||||
private readonly _onDidPopoutGroupPositionChange =
|
||||
new Emitter<PopoutGroupChangePositionEvent>();
|
||||
readonly onDidPopoutGroupPositionChange: Event<PopoutGroupChangePositionEvent> =
|
||||
this._onDidPopoutGroupPositionChange.event;
|
||||
|
||||
private readonly _onDidLayoutFromJSON = new Emitter<void>();
|
||||
readonly onDidLayoutFromJSON: Event<void> = this._onDidLayoutFromJSON.event;
|
||||
|
||||
@ -386,11 +412,11 @@ export class DockviewComponent
|
||||
className: options.className,
|
||||
});
|
||||
|
||||
this._options = options;
|
||||
|
||||
this.popupService = new PopupService(this.element);
|
||||
|
||||
this.updateDropTargetModel(options);
|
||||
|
||||
this._themeClassnames = new Classnames(this.element);
|
||||
this._api = new DockviewApi(this);
|
||||
|
||||
this.rootDropTargetContainer = new DropTargetAnchorContainer(
|
||||
this.element,
|
||||
@ -401,88 +427,6 @@ export class DockviewComponent
|
||||
this
|
||||
);
|
||||
|
||||
toggleClass(this.gridview.element, 'dv-dockview', true);
|
||||
toggleClass(this.element, 'dv-debug', !!options.debug);
|
||||
|
||||
if (options.debug) {
|
||||
this.addDisposables(new StrictEventsSequencing(this));
|
||||
}
|
||||
|
||||
this.addDisposables(
|
||||
this.rootDropTargetContainer,
|
||||
this.overlayRenderContainer,
|
||||
this._onWillDragPanel,
|
||||
this._onWillDragGroup,
|
||||
this._onWillShowOverlay,
|
||||
this._onDidActivePanelChange,
|
||||
this._onDidAddPanel,
|
||||
this._onDidRemovePanel,
|
||||
this._onDidLayoutFromJSON,
|
||||
this._onDidDrop,
|
||||
this._onWillDrop,
|
||||
this._onDidMovePanel,
|
||||
this._onDidAddGroup,
|
||||
this._onDidRemoveGroup,
|
||||
this._onDidActiveGroupChange,
|
||||
this._onUnhandledDragOverEvent,
|
||||
this._onDidMaximizedGroupChange,
|
||||
this._onDidOptionsChange,
|
||||
this.onDidViewVisibilityChangeMicroTaskQueue(() => {
|
||||
this.updateWatermark();
|
||||
}),
|
||||
this.onDidAdd((event) => {
|
||||
if (!this._moving) {
|
||||
this._onDidAddGroup.fire(event);
|
||||
}
|
||||
}),
|
||||
this.onDidRemove((event) => {
|
||||
if (!this._moving) {
|
||||
this._onDidRemoveGroup.fire(event);
|
||||
}
|
||||
}),
|
||||
this.onDidActiveChange((event) => {
|
||||
if (!this._moving) {
|
||||
this._onDidActiveGroupChange.fire(event);
|
||||
}
|
||||
}),
|
||||
this.onDidMaximizedChange((event) => {
|
||||
this._onDidMaximizedGroupChange.fire({
|
||||
group: event.panel,
|
||||
isMaximized: event.isMaximized,
|
||||
});
|
||||
}),
|
||||
Event.any(
|
||||
this.onDidAdd,
|
||||
this.onDidRemove
|
||||
)(() => {
|
||||
this.updateWatermark();
|
||||
}),
|
||||
Event.any<unknown>(
|
||||
this.onDidAddPanel,
|
||||
this.onDidRemovePanel,
|
||||
this.onDidAddGroup,
|
||||
this.onDidRemove,
|
||||
this.onDidMovePanel,
|
||||
this.onDidActivePanelChange
|
||||
)(() => {
|
||||
this._bufferOnDidLayoutChange.fire();
|
||||
}),
|
||||
Disposable.from(() => {
|
||||
// iterate over a copy of the array since .dispose() mutates the original array
|
||||
for (const group of [...this._floatingGroups]) {
|
||||
group.dispose();
|
||||
}
|
||||
|
||||
// iterate over a copy of the array since .dispose() mutates the original array
|
||||
for (const group of [...this._popoutGroups]) {
|
||||
group.disposable.dispose();
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
this._options = options;
|
||||
this.updateTheme();
|
||||
|
||||
this._rootDropTarget = new Droptarget(this.element, {
|
||||
className: 'dv-drop-target-edge',
|
||||
canDisplayOverlay: (event, position) => {
|
||||
@ -524,11 +468,96 @@ export class DockviewComponent
|
||||
},
|
||||
acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
|
||||
overlayModel:
|
||||
this.options.rootOverlayModel ?? DEFAULT_ROOT_OVERLAY_MODEL,
|
||||
options.rootOverlayModel ?? DEFAULT_ROOT_OVERLAY_MODEL,
|
||||
getOverrideTarget: () => this.rootDropTargetContainer?.model,
|
||||
});
|
||||
|
||||
this.updateDropTargetModel(options);
|
||||
|
||||
toggleClass(this.gridview.element, 'dv-dockview', true);
|
||||
toggleClass(this.element, 'dv-debug', !!options.debug);
|
||||
|
||||
this.updateTheme();
|
||||
this.updateWatermark();
|
||||
|
||||
if (options.debug) {
|
||||
this.addDisposables(new StrictEventsSequencing(this));
|
||||
}
|
||||
|
||||
this.addDisposables(
|
||||
this.rootDropTargetContainer,
|
||||
this.overlayRenderContainer,
|
||||
this._onWillDragPanel,
|
||||
this._onWillDragGroup,
|
||||
this._onWillShowOverlay,
|
||||
this._onDidActivePanelChange,
|
||||
this._onDidAddPanel,
|
||||
this._onDidRemovePanel,
|
||||
this._onDidLayoutFromJSON,
|
||||
this._onDidDrop,
|
||||
this._onWillDrop,
|
||||
this._onDidMovePanel,
|
||||
this._onDidAddGroup,
|
||||
this._onDidRemoveGroup,
|
||||
this._onDidActiveGroupChange,
|
||||
this._onUnhandledDragOverEvent,
|
||||
this._onDidMaximizedGroupChange,
|
||||
this._onDidOptionsChange,
|
||||
this._onDidPopoutGroupSizeChange,
|
||||
this._onDidPopoutGroupPositionChange,
|
||||
this.onDidViewVisibilityChangeMicroTaskQueue(() => {
|
||||
this.updateWatermark();
|
||||
}),
|
||||
this.onDidAdd((event) => {
|
||||
if (!this._moving) {
|
||||
this._onDidAddGroup.fire(event);
|
||||
}
|
||||
}),
|
||||
this.onDidRemove((event) => {
|
||||
if (!this._moving) {
|
||||
this._onDidRemoveGroup.fire(event);
|
||||
}
|
||||
}),
|
||||
this.onDidActiveChange((event) => {
|
||||
if (!this._moving) {
|
||||
this._onDidActiveGroupChange.fire(event);
|
||||
}
|
||||
}),
|
||||
this.onDidMaximizedChange((event) => {
|
||||
this._onDidMaximizedGroupChange.fire({
|
||||
group: event.panel,
|
||||
isMaximized: event.isMaximized,
|
||||
});
|
||||
}),
|
||||
Event.any(
|
||||
this.onDidAdd,
|
||||
this.onDidRemove
|
||||
)(() => {
|
||||
this.updateWatermark();
|
||||
}),
|
||||
Event.any<unknown>(
|
||||
this.onDidAddPanel,
|
||||
this.onDidRemovePanel,
|
||||
this.onDidAddGroup,
|
||||
this.onDidRemove,
|
||||
this.onDidMovePanel,
|
||||
this.onDidActivePanelChange,
|
||||
this.onDidPopoutGroupPositionChange,
|
||||
this.onDidPopoutGroupSizeChange
|
||||
)(() => {
|
||||
this._bufferOnDidLayoutChange.fire();
|
||||
}),
|
||||
Disposable.from(() => {
|
||||
// iterate over a copy of the array since .dispose() mutates the original array
|
||||
for (const group of [...this._floatingGroups]) {
|
||||
group.dispose();
|
||||
}
|
||||
|
||||
// iterate over a copy of the array since .dispose() mutates the original array
|
||||
for (const group of [...this._popoutGroups]) {
|
||||
group.disposable.dispose();
|
||||
}
|
||||
}),
|
||||
this._rootDropTarget,
|
||||
this._rootDropTarget.onWillShowOverlay((event) => {
|
||||
if (this.gridview.length > 0 && event.position === 'center') {
|
||||
@ -591,10 +620,6 @@ export class DockviewComponent
|
||||
}),
|
||||
this._rootDropTarget
|
||||
);
|
||||
|
||||
this._api = new DockviewApi(this);
|
||||
|
||||
this.updateWatermark();
|
||||
}
|
||||
|
||||
override setVisible(panel: DockviewGroupPanel, visible: boolean): void {
|
||||
@ -832,22 +857,37 @@ export class DockviewComponent
|
||||
},
|
||||
};
|
||||
|
||||
const _onDidWindowPositionChange = onDidWindowMoveEnd(
|
||||
_window.window!
|
||||
);
|
||||
|
||||
popoutWindowDisposable.addDisposables(
|
||||
_onDidWindowPositionChange,
|
||||
onDidWindowResizeEnd(_window.window!, () => {
|
||||
this._onDidPopoutGroupSizeChange.fire({
|
||||
width: _window.window!.innerWidth,
|
||||
height: _window.window!.innerHeight,
|
||||
group,
|
||||
});
|
||||
}),
|
||||
_onDidWindowPositionChange.event(() => {
|
||||
this._onDidPopoutGroupPositionChange.fire({
|
||||
screenX: _window.window!.screenX,
|
||||
screenY: _window.window!.screenX,
|
||||
group,
|
||||
});
|
||||
}),
|
||||
/**
|
||||
* ResizeObserver seems slow here, I do not know why but we don't need it
|
||||
* since we can reply on the window resize event as we will occupy the full
|
||||
* window dimensions
|
||||
*/
|
||||
addDisposableWindowListener(
|
||||
_window.window!,
|
||||
'resize',
|
||||
() => {
|
||||
addDisposableListener(_window.window!, 'resize', () => {
|
||||
group.layout(
|
||||
_window.window!.innerWidth,
|
||||
_window.window!.innerHeight
|
||||
);
|
||||
}
|
||||
),
|
||||
}),
|
||||
overlayRenderContainer,
|
||||
Disposable.from(() => {
|
||||
if (this.isDisposed) {
|
||||
@ -1131,7 +1171,10 @@ export class DockviewComponent
|
||||
this.updateWatermark();
|
||||
}
|
||||
|
||||
private orthogonalize(position: Position): DockviewGroupPanel {
|
||||
private orthogonalize(
|
||||
position: Position,
|
||||
options?: GroupOptions
|
||||
): DockviewGroupPanel {
|
||||
switch (position) {
|
||||
case 'top':
|
||||
case 'bottom':
|
||||
@ -1157,10 +1200,14 @@ export class DockviewComponent
|
||||
case 'top':
|
||||
case 'left':
|
||||
case 'center':
|
||||
return this.createGroupAtLocation([0]); // insert into first position
|
||||
return this.createGroupAtLocation([0], undefined, options); // insert into first position
|
||||
case 'bottom':
|
||||
case 'right':
|
||||
return this.createGroupAtLocation([this.gridview.length]); // insert into last position
|
||||
return this.createGroupAtLocation(
|
||||
[this.gridview.length],
|
||||
undefined,
|
||||
options
|
||||
); // insert into last position
|
||||
default:
|
||||
throw new Error(`unsupported position ${position}`);
|
||||
}
|
||||
@ -1835,7 +1882,8 @@ export class DockviewComponent
|
||||
}
|
||||
} else {
|
||||
const group = this.orthogonalize(
|
||||
directionToPosition(<Direction>options.direction)
|
||||
directionToPosition(<Direction>options.direction),
|
||||
options
|
||||
);
|
||||
if (!options.skipSetActive) {
|
||||
this.doSetGroupAndPanelActive(group);
|
||||
@ -2284,6 +2332,7 @@ export class DockviewComponent
|
||||
}
|
||||
}
|
||||
|
||||
if (from.api.location.type !== 'popout') {
|
||||
const referenceLocation = getGridLocation(to.element);
|
||||
const dropLocation = getRelativeLocation(
|
||||
this.gridview.orientation,
|
||||
@ -2310,6 +2359,7 @@ export class DockviewComponent
|
||||
|
||||
this.gridview.addView(from, size, dropLocation);
|
||||
}
|
||||
}
|
||||
|
||||
from.panels.forEach((panel) => {
|
||||
this._onDidMovePanel.fire({ panel, from });
|
||||
@ -2503,9 +2553,10 @@ export class DockviewComponent
|
||||
|
||||
private createGroupAtLocation(
|
||||
location: number[],
|
||||
size?: number
|
||||
size?: number,
|
||||
options?: GroupOptions
|
||||
): DockviewGroupPanel {
|
||||
const group = this.createGroup();
|
||||
const group = this.createGroup(options);
|
||||
this.doAddGroup(group, location, size);
|
||||
return group;
|
||||
}
|
||||
|
@ -69,6 +69,13 @@ export interface DockviewOptions {
|
||||
noPanelsOverlay?: 'emptyGroup' | 'watermark';
|
||||
theme?: DockviewTheme;
|
||||
disableTabsOverflowList?: boolean;
|
||||
/**
|
||||
* Select `native` to use built-in scrollbar behaviours and `custom` to use an internal implementation
|
||||
* that allows for improved scrollbar overlay UX.
|
||||
*
|
||||
* This is only applied to the tab header section. Defaults to `custom`.
|
||||
*/
|
||||
scrollbars?: 'native' | 'custom';
|
||||
}
|
||||
|
||||
export interface DockviewDndOverlayEvent extends IAcceptableEvent {
|
||||
@ -116,6 +123,7 @@ export const PROPERTY_KEYS_DOCKVIEW: (keyof DockviewOptions)[] = (() => {
|
||||
dndEdges: undefined,
|
||||
theme: undefined,
|
||||
disableTabsOverflowList: undefined,
|
||||
scrollbars: undefined,
|
||||
};
|
||||
|
||||
return Object.keys(properties) as (keyof DockviewOptions)[];
|
||||
|
@ -2,7 +2,6 @@ import {
|
||||
Event as DockviewEvent,
|
||||
Emitter,
|
||||
addDisposableListener,
|
||||
addDisposableWindowListener,
|
||||
} from './events';
|
||||
import { IDisposable, CompositeDisposable } from './lifecycle';
|
||||
|
||||
@ -112,8 +111,11 @@ export function isAncestor(
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getElementsByTagName(tag: string): HTMLElement[] {
|
||||
return Array.prototype.slice.call(document.getElementsByTagName(tag), 0);
|
||||
export function getElementsByTagName(
|
||||
tag: string,
|
||||
document: ParentNode
|
||||
): HTMLElement[] {
|
||||
return Array.prototype.slice.call(document.querySelectorAll(tag), 0);
|
||||
}
|
||||
|
||||
export interface IFocusTracker extends IDisposable {
|
||||
@ -122,7 +124,7 @@ export interface IFocusTracker extends IDisposable {
|
||||
refreshState?(): void;
|
||||
}
|
||||
|
||||
export function trackFocus(element: HTMLElement | Window): IFocusTracker {
|
||||
export function trackFocus(element: HTMLElement): IFocusTracker {
|
||||
return new FocusTracker(element);
|
||||
}
|
||||
|
||||
@ -138,7 +140,7 @@ class FocusTracker extends CompositeDisposable implements IFocusTracker {
|
||||
|
||||
private readonly _refreshStateHandler: () => void;
|
||||
|
||||
constructor(element: HTMLElement | Window) {
|
||||
constructor(element: HTMLElement) {
|
||||
super();
|
||||
|
||||
this.addDisposables(this._onDidFocus, this._onDidBlur);
|
||||
@ -181,21 +183,12 @@ class FocusTracker extends CompositeDisposable implements IFocusTracker {
|
||||
}
|
||||
};
|
||||
|
||||
if (element instanceof HTMLElement) {
|
||||
this.addDisposables(
|
||||
addDisposableListener(element, 'focus', onFocus, true)
|
||||
);
|
||||
this.addDisposables(
|
||||
addDisposableListener(element, 'blur', onBlur, true)
|
||||
);
|
||||
} else {
|
||||
this.addDisposables(
|
||||
addDisposableWindowListener(element, 'focus', onFocus, true)
|
||||
);
|
||||
this.addDisposables(
|
||||
addDisposableWindowListener(element, 'blur', onBlur, true)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
refreshState(): void {
|
||||
@ -288,11 +281,36 @@ export function addTestId(element: HTMLElement, id: string): void {
|
||||
element.setAttribute('data-testid', id);
|
||||
}
|
||||
|
||||
export function disableIframePointEvents() {
|
||||
const iframes: HTMLElement[] = [
|
||||
...getElementsByTagName('iframe'),
|
||||
...getElementsByTagName('webview'),
|
||||
];
|
||||
/**
|
||||
* Should be more efficient than element.querySelectorAll("*") since there
|
||||
* is no need to store every element in-memory using this approach
|
||||
*/
|
||||
function allTagsNamesInclusiveOfShadowDoms(tagNames: string[]) {
|
||||
const iframes: HTMLElement[] = [];
|
||||
|
||||
function findIframesInNode(node: Element) {
|
||||
if (node.nodeType === Node.ELEMENT_NODE) {
|
||||
if (tagNames.includes(node.tagName)) {
|
||||
iframes.push(node as HTMLElement);
|
||||
}
|
||||
|
||||
if (node.shadowRoot) {
|
||||
findIframesInNode(<any>node.shadowRoot);
|
||||
}
|
||||
|
||||
for (const child of node.children) {
|
||||
findIframesInNode(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
findIframesInNode(document.documentElement);
|
||||
|
||||
return iframes;
|
||||
}
|
||||
|
||||
export function disableIframePointEvents(rootNode: ParentNode = document) {
|
||||
const iframes = allTagsNamesInclusiveOfShadowDoms(['IFRAME', 'WEBVIEW']);
|
||||
|
||||
const original = new WeakMap<HTMLElement, string>(); // don't hold onto HTMLElement references longer than required
|
||||
|
||||
@ -358,6 +376,8 @@ export class Classnames {
|
||||
}
|
||||
}
|
||||
|
||||
const DEBOUCE_DELAY = 100;
|
||||
|
||||
export function isChildEntirelyVisibleWithinParent(
|
||||
child: HTMLElement,
|
||||
parent: HTMLElement
|
||||
@ -379,3 +399,102 @@ export function isChildEntirelyVisibleWithinParent(
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function onDidWindowMoveEnd(window: Window): Emitter<void> {
|
||||
const emitter = new Emitter<void>();
|
||||
|
||||
let previousScreenX = window.screenX;
|
||||
let previousScreenY = window.screenY;
|
||||
|
||||
let timeout: any;
|
||||
|
||||
const checkMovement = () => {
|
||||
if (window.closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentScreenX = window.screenX;
|
||||
const currentScreenY = window.screenY;
|
||||
|
||||
if (
|
||||
currentScreenX !== previousScreenX ||
|
||||
currentScreenY !== previousScreenY
|
||||
) {
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(() => {
|
||||
emitter.fire();
|
||||
}, DEBOUCE_DELAY);
|
||||
|
||||
previousScreenX = currentScreenX;
|
||||
previousScreenY = currentScreenY;
|
||||
}
|
||||
|
||||
requestAnimationFrame(checkMovement);
|
||||
};
|
||||
|
||||
checkMovement();
|
||||
|
||||
return emitter;
|
||||
}
|
||||
|
||||
export function onDidWindowResizeEnd(element: Window, cb: () => void) {
|
||||
let resizeTimeout: any;
|
||||
|
||||
const disposable = new CompositeDisposable(
|
||||
addDisposableListener(element, 'resize', () => {
|
||||
clearTimeout(resizeTimeout);
|
||||
resizeTimeout = setTimeout(() => {
|
||||
cb();
|
||||
}, DEBOUCE_DELAY);
|
||||
})
|
||||
);
|
||||
|
||||
return disposable;
|
||||
}
|
||||
|
||||
export function shiftAbsoluteElementIntoView(
|
||||
element: HTMLElement,
|
||||
root: HTMLElement,
|
||||
options: { buffer: number } = { buffer: 10 }
|
||||
) {
|
||||
const buffer = options.buffer;
|
||||
const rect = element.getBoundingClientRect();
|
||||
const rootRect = root.getBoundingClientRect();
|
||||
|
||||
let translateX = 0;
|
||||
let translateY = 0;
|
||||
|
||||
const left = rect.left - rootRect.left;
|
||||
const top = rect.top - rootRect.top;
|
||||
const bottom = rect.bottom - rootRect.bottom;
|
||||
const right = rect.right - rootRect.right;
|
||||
|
||||
// Check horizontal overflow
|
||||
if (left < buffer) {
|
||||
translateX = buffer - left;
|
||||
} else if (right > buffer) {
|
||||
translateX = -buffer - right;
|
||||
}
|
||||
|
||||
// Check vertical overflow
|
||||
if (top < buffer) {
|
||||
translateY = buffer - top;
|
||||
} else if (bottom > buffer) {
|
||||
translateY = -bottom - buffer;
|
||||
}
|
||||
|
||||
// Apply the translation if needed
|
||||
if (translateX !== 0 || translateY !== 0) {
|
||||
element.style.transform = `translate(${translateX}px, ${translateY}px)`;
|
||||
}
|
||||
}
|
||||
|
||||
export function findRelativeZIndexParent(el: HTMLElement): HTMLElement | null {
|
||||
let tmp: HTMLElement | null = el;
|
||||
|
||||
while (tmp && (tmp.style.zIndex === 'auto' || tmp.style.zIndex === '')) {
|
||||
tmp = tmp.parentElement;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
@ -193,32 +193,38 @@ export class Emitter<T> implements IDisposable {
|
||||
}
|
||||
}
|
||||
|
||||
export function addDisposableWindowListener<K extends keyof WindowEventMap>(
|
||||
export function addDisposableListener<K extends keyof WindowEventMap>(
|
||||
element: Window,
|
||||
type: K,
|
||||
listener: (this: Window, ev: WindowEventMap[K]) => any,
|
||||
options?: boolean | AddEventListenerOptions
|
||||
): IDisposable {
|
||||
element.addEventListener(type, listener, options);
|
||||
|
||||
return {
|
||||
dispose: () => {
|
||||
element.removeEventListener(type, listener, options);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
): IDisposable;
|
||||
export function addDisposableListener<K extends keyof HTMLElementEventMap>(
|
||||
element: HTMLElement,
|
||||
type: K,
|
||||
listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any,
|
||||
options?: boolean | AddEventListenerOptions
|
||||
): IDisposable;
|
||||
export function addDisposableListener<
|
||||
K extends keyof HTMLElementEventMap | keyof WindowEventMap
|
||||
>(
|
||||
element: HTMLElement | Window,
|
||||
type: K,
|
||||
listener: (
|
||||
this: K extends keyof HTMLElementEventMap ? HTMLElement : Window,
|
||||
ev: K extends keyof HTMLElementEventMap
|
||||
? HTMLElementEventMap[K]
|
||||
: K extends keyof WindowEventMap
|
||||
? WindowEventMap[K]
|
||||
: never
|
||||
) => any,
|
||||
options?: boolean | AddEventListenerOptions
|
||||
): IDisposable {
|
||||
element.addEventListener(type, listener, options);
|
||||
element.addEventListener(type, <any>listener, options);
|
||||
|
||||
return {
|
||||
dispose: () => {
|
||||
element.removeEventListener(type, listener, options);
|
||||
element.removeEventListener(type, <any>listener, options);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import {
|
||||
Emitter,
|
||||
Event,
|
||||
addDisposableListener,
|
||||
addDisposableWindowListener,
|
||||
} from '../events';
|
||||
import { CompositeDisposable, MutableDisposable } from '../lifecycle';
|
||||
import { clamp } from '../math';
|
||||
@ -258,7 +257,7 @@ export class Overlay extends CompositeDisposable {
|
||||
iframes.release();
|
||||
},
|
||||
},
|
||||
addDisposableWindowListener(window, 'pointermove', (e) => {
|
||||
addDisposableListener(window, 'pointermove', (e) => {
|
||||
const containerRect =
|
||||
this.options.container.getBoundingClientRect();
|
||||
const x = e.clientX - containerRect.left;
|
||||
@ -344,7 +343,7 @@ export class Overlay extends CompositeDisposable {
|
||||
|
||||
this.setBounds(bounds);
|
||||
}),
|
||||
addDisposableWindowListener(window, 'pointerup', () => {
|
||||
addDisposableListener(window, 'pointerup', () => {
|
||||
toggleClass(
|
||||
this._element,
|
||||
'dv-resize-container-dragging',
|
||||
@ -439,7 +438,7 @@ export class Overlay extends CompositeDisposable {
|
||||
const iframes = disableIframePointEvents();
|
||||
|
||||
move.value = new CompositeDisposable(
|
||||
addDisposableWindowListener(window, 'pointermove', (e) => {
|
||||
addDisposableListener(window, 'pointermove', (e) => {
|
||||
const containerRect =
|
||||
this.options.container.getBoundingClientRect();
|
||||
const overlayRect =
|
||||
@ -610,7 +609,7 @@ export class Overlay extends CompositeDisposable {
|
||||
iframes.release();
|
||||
},
|
||||
},
|
||||
addDisposableWindowListener(window, 'pointerup', () => {
|
||||
addDisposableListener(window, 'pointerup', () => {
|
||||
move.dispose();
|
||||
this._onDidChangeEnd.fire();
|
||||
})
|
||||
|
@ -38,20 +38,37 @@ export abstract class DraggablePaneviewPanel extends PaneviewPanel {
|
||||
readonly onUnhandledDragOverEvent: Event<PaneviewDndOverlayEvent> =
|
||||
this._onUnhandledDragOverEvent.event;
|
||||
|
||||
constructor(
|
||||
private readonly accessor: IPaneviewComponent,
|
||||
id: string,
|
||||
component: string,
|
||||
headerComponent: string | undefined,
|
||||
orientation: Orientation,
|
||||
isExpanded: boolean,
|
||||
disableDnd: boolean
|
||||
) {
|
||||
super(id, component, headerComponent, orientation, isExpanded, true);
|
||||
readonly accessor: IPaneviewComponent;
|
||||
|
||||
constructor(options: {
|
||||
accessor: IPaneviewComponent;
|
||||
id: string;
|
||||
component: string;
|
||||
headerComponent: string | undefined;
|
||||
orientation: Orientation;
|
||||
isExpanded: boolean;
|
||||
disableDnd: boolean;
|
||||
headerSize: number;
|
||||
minimumBodySize: number;
|
||||
maximumBodySize: number;
|
||||
}) {
|
||||
super({
|
||||
id: options.id,
|
||||
component: options.component,
|
||||
headerComponent: options.headerComponent,
|
||||
orientation: options.orientation,
|
||||
isExpanded: options.isExpanded,
|
||||
isHeaderVisible: true,
|
||||
headerSize: options.headerSize,
|
||||
minimumBodySize: options.minimumBodySize,
|
||||
maximumBodySize: options.maximumBodySize,
|
||||
});
|
||||
|
||||
this.accessor = options.accessor;
|
||||
|
||||
this.addDisposables(this._onDidDrop, this._onUnhandledDragOverEvent);
|
||||
|
||||
if (!disableDnd) {
|
||||
if (!options.disableDnd) {
|
||||
this.initDragFeatures();
|
||||
}
|
||||
}
|
||||
|
@ -21,11 +21,16 @@ import { Classnames } from '../dom';
|
||||
|
||||
const nextLayoutId = sequentialNumberGenerator();
|
||||
|
||||
const HEADER_SIZE = 22;
|
||||
const MINIMUM_BODY_SIZE = 0;
|
||||
const MAXIMUM_BODY_SIZE = Number.MAX_SAFE_INTEGER;
|
||||
|
||||
export interface SerializedPaneviewPanel {
|
||||
snap?: boolean;
|
||||
priority?: LayoutPriority;
|
||||
minimumSize?: number;
|
||||
maximumSize?: number;
|
||||
headerSize?: number;
|
||||
data: {
|
||||
id: string;
|
||||
component: string;
|
||||
@ -54,17 +59,23 @@ export class PaneFramework extends DraggablePaneviewPanel {
|
||||
isExpanded: boolean;
|
||||
disableDnd: boolean;
|
||||
accessor: IPaneviewComponent;
|
||||
headerSize: number;
|
||||
minimumBodySize: number;
|
||||
maximumBodySize: number;
|
||||
}
|
||||
) {
|
||||
super(
|
||||
options.accessor,
|
||||
options.id,
|
||||
options.component,
|
||||
options.headerComponent,
|
||||
options.orientation,
|
||||
options.isExpanded,
|
||||
options.disableDnd
|
||||
);
|
||||
super({
|
||||
accessor: options.accessor,
|
||||
id: options.id,
|
||||
component: options.component,
|
||||
headerComponent: options.headerComponent,
|
||||
orientation: options.orientation,
|
||||
isExpanded: options.isExpanded,
|
||||
disableDnd: options.disableDnd,
|
||||
headerSize: options.headerSize,
|
||||
minimumBodySize: options.minimumBodySize,
|
||||
maximumBodySize: options.maximumBodySize,
|
||||
});
|
||||
}
|
||||
|
||||
getBodyComponent() {
|
||||
@ -83,6 +94,7 @@ export interface AddPaneviewComponentOptions<T extends object = Parameters> {
|
||||
params?: T;
|
||||
minimumBodySize?: number;
|
||||
maximumBodySize?: number;
|
||||
headerSize?: number;
|
||||
isExpanded?: boolean;
|
||||
title: string;
|
||||
index?: number;
|
||||
@ -277,6 +289,9 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
|
||||
isExpanded: !!options.isExpanded,
|
||||
disableDnd: !!this.options.disableDnd,
|
||||
accessor: this,
|
||||
headerSize: options.headerSize ?? HEADER_SIZE,
|
||||
minimumBodySize: MINIMUM_BODY_SIZE,
|
||||
maximumBodySize: MAXIMUM_BODY_SIZE,
|
||||
});
|
||||
|
||||
this.doAddPanel(view);
|
||||
@ -344,6 +359,7 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
|
||||
data: view.toJSON(),
|
||||
minimumSize: minimum(view.minimumBodySize),
|
||||
maximumSize: maximum(view.maximumBodySize),
|
||||
headerSize: view.headerSize,
|
||||
expanded: view.isExpanded(),
|
||||
};
|
||||
});
|
||||
@ -403,6 +419,9 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
|
||||
isExpanded: !!view.expanded,
|
||||
disableDnd: !!this.options.disableDnd,
|
||||
accessor: this,
|
||||
headerSize: view.headerSize ?? HEADER_SIZE,
|
||||
minimumBodySize: view.minimumSize ?? MINIMUM_BODY_SIZE,
|
||||
maximumBodySize: view.maximumSize ?? MAXIMUM_BODY_SIZE,
|
||||
});
|
||||
|
||||
this.doAddPanel(panel);
|
||||
|
@ -71,22 +71,23 @@ export abstract class PaneviewPanel
|
||||
readonly onDidChange: Event<{ size?: number; orthogonalSize?: number }> =
|
||||
this._onDidChange.event;
|
||||
|
||||
private readonly headerSize = 22;
|
||||
private _orthogonalSize = 0;
|
||||
private _size = 0;
|
||||
private _minimumBodySize = 100;
|
||||
private _maximumBodySize: number = Number.POSITIVE_INFINITY;
|
||||
private _minimumBodySize: number;
|
||||
private _maximumBodySize: number;
|
||||
private _isExpanded = false;
|
||||
protected header?: HTMLElement;
|
||||
protected body?: HTMLElement;
|
||||
private bodyPart?: IPanePart;
|
||||
private headerPart?: IPanePart;
|
||||
private expandedSize = 0;
|
||||
private animationTimer: any;
|
||||
private _orientation: Orientation;
|
||||
|
||||
private _headerVisible: boolean;
|
||||
|
||||
readonly headerSize: number;
|
||||
readonly headerComponent: string | undefined;
|
||||
|
||||
set orientation(value: Orientation) {
|
||||
this._orientation = value;
|
||||
}
|
||||
@ -149,24 +150,37 @@ export abstract class PaneviewPanel
|
||||
this.header!.style.display = value ? '' : 'none';
|
||||
}
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
component: string,
|
||||
private readonly headerComponent: string | undefined,
|
||||
orientation: Orientation,
|
||||
isExpanded: boolean,
|
||||
isHeaderVisible: boolean
|
||||
) {
|
||||
super(id, component, new PaneviewPanelApiImpl(id, component));
|
||||
constructor(options: {
|
||||
id: string;
|
||||
component: string;
|
||||
headerComponent: string | undefined;
|
||||
orientation: Orientation;
|
||||
isExpanded: boolean;
|
||||
isHeaderVisible: boolean;
|
||||
headerSize: number;
|
||||
minimumBodySize: number;
|
||||
maximumBodySize: number;
|
||||
}) {
|
||||
super(
|
||||
options.id,
|
||||
options.component,
|
||||
new PaneviewPanelApiImpl(options.id, options.component)
|
||||
);
|
||||
this.api.pane = this; // TODO cannot use 'this' before 'super'
|
||||
this.api.initialize(this);
|
||||
|
||||
this._isExpanded = isExpanded;
|
||||
this._headerVisible = isHeaderVisible;
|
||||
this.headerSize = options.headerSize;
|
||||
this.headerComponent = options.headerComponent;
|
||||
|
||||
this._minimumBodySize = options.minimumBodySize;
|
||||
this._maximumBodySize = options.maximumBodySize;
|
||||
|
||||
this._isExpanded = options.isExpanded;
|
||||
this._headerVisible = options.isHeaderVisible;
|
||||
|
||||
this._onDidChangeExpansionState.fire(this.isExpanded()); // initialize value
|
||||
|
||||
this._orientation = orientation;
|
||||
this._orientation = options.orientation;
|
||||
|
||||
this.element.classList.add('dv-pane');
|
||||
|
||||
@ -260,9 +274,6 @@ export abstract class PaneviewPanel
|
||||
this.orientation === Orientation.HORIZONTAL
|
||||
? [size, orthogonalSize]
|
||||
: [orthogonalSize, size];
|
||||
if (this.isExpanded()) {
|
||||
this.expandedSize = width;
|
||||
}
|
||||
super.layout(width, height);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { addStyles } from './dom';
|
||||
import { Emitter, addDisposableWindowListener } from './events';
|
||||
import { Emitter, addDisposableListener } from './events';
|
||||
import { CompositeDisposable, Disposable, IDisposable } from './lifecycle';
|
||||
import { Box } from './types';
|
||||
|
||||
@ -101,7 +101,7 @@ export class PopoutWindow extends CompositeDisposable {
|
||||
Disposable.from(() => {
|
||||
externalWindow.close();
|
||||
}),
|
||||
addDisposableWindowListener(window, 'beforeunload', () => {
|
||||
addDisposableListener(window, 'beforeunload', () => {
|
||||
/**
|
||||
* before the main window closes we should close this popup too
|
||||
* to be good citizens
|
||||
@ -146,7 +146,7 @@ export class PopoutWindow extends CompositeDisposable {
|
||||
* beforeunload must be registered after load for reasons I could not determine
|
||||
* otherwise the beforeunload event will not fire when the window is closed
|
||||
*/
|
||||
addDisposableWindowListener(
|
||||
addDisposableListener(
|
||||
externalWindow,
|
||||
'beforeunload',
|
||||
() => {
|
||||
|
@ -122,6 +122,10 @@ export class SplitviewComponent
|
||||
}
|
||||
|
||||
set splitview(value: Splitview) {
|
||||
if (this._splitview) {
|
||||
this._splitview.dispose();
|
||||
}
|
||||
|
||||
this._splitview = value;
|
||||
|
||||
this._splitviewChangeDisposable.value = new CompositeDisposable(
|
||||
|
@ -216,8 +216,7 @@
|
||||
.dv-groupview {
|
||||
&.dv-active-group {
|
||||
> .dv-tabs-and-actions-container {
|
||||
> .dv-scrollable {
|
||||
> .dv-tabs-container {
|
||||
.dv-tabs-container {
|
||||
> .dv-tab.dv-active-tab {
|
||||
position: relative;
|
||||
|
||||
@ -235,11 +234,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.dv-inactive-group {
|
||||
> .dv-tabs-and-actions-container {
|
||||
> .dv-scrollable {
|
||||
> .dv-tabs-container {
|
||||
.dv-tabs-container {
|
||||
> .dv-tab.dv-active-tab {
|
||||
position: relative;
|
||||
|
||||
@ -259,7 +256,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dockview-theme-abyss {
|
||||
@include dockview-theme-abyss-mixin();
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dockview-react",
|
||||
"version": "4.0.0",
|
||||
"version": "4.2.5",
|
||||
"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": "^4.0.0"
|
||||
"dockview": "^4.2.5"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dockview-vue",
|
||||
"version": "4.0.0",
|
||||
"version": "4.2.5",
|
||||
"description": "Zero dependency layout manager supporting tabs, grids and splitviews",
|
||||
"keywords": [
|
||||
"splitview",
|
||||
@ -52,7 +52,7 @@
|
||||
"test:cov": "cross-env ../../node_modules/.bin/jest --selectProjects dockview-vue --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"dockview-core": "^4.0.0"
|
||||
"dockview-core": "^4.2.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.4.0"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dockview",
|
||||
"version": "4.0.0",
|
||||
"version": "4.2.5",
|
||||
"description": "Zero dependency layout manager supporting tabs, grids and splitviews",
|
||||
"keywords": [
|
||||
"splitview",
|
||||
@ -54,7 +54,7 @@
|
||||
"test:cov": "cross-env ../../node_modules/.bin/jest --selectProjects dockview --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"dockview-core": "^4.0.0"
|
||||
"dockview-core": "^4.2.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
|
@ -175,6 +175,7 @@ export const DockviewReact = React.forwardRef(
|
||||
dockviewRef.current = api;
|
||||
|
||||
return () => {
|
||||
dockviewRef.current = undefined;
|
||||
api.dispose();
|
||||
};
|
||||
}, []);
|
||||
|
@ -105,6 +105,7 @@ export const GridviewReact = React.forwardRef(
|
||||
gridviewRef.current = api;
|
||||
|
||||
return () => {
|
||||
gridviewRef.current = undefined;
|
||||
api.dispose();
|
||||
};
|
||||
}, []);
|
||||
|
@ -120,6 +120,7 @@ export const PaneviewReact = React.forwardRef(
|
||||
paneviewRef.current = api;
|
||||
|
||||
return () => {
|
||||
paneviewRef.current = undefined;
|
||||
api.dispose();
|
||||
};
|
||||
}, []);
|
||||
|
@ -105,6 +105,7 @@ export const SplitviewReact = React.forwardRef(
|
||||
splitviewRef.current = api;
|
||||
|
||||
return () => {
|
||||
splitviewRef.current = undefined;
|
||||
api.dispose();
|
||||
};
|
||||
}, []);
|
||||
|
19
packages/docs/blog/2025-03-14-dockview-4.0.1.md
Normal file
19
packages/docs/blog/2025-03-14-dockview-4.0.1.md
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
slug: dockview-4.0.1-release
|
||||
title: Dockview 4.0.1
|
||||
tags: [release]
|
||||
---
|
||||
|
||||
# Release Notes
|
||||
|
||||
Please reference docs @ [dockview.dev](https://dockview.dev).
|
||||
|
||||
## 🚀 Features
|
||||
|
||||
## 🛠 Miscs
|
||||
|
||||
- Bug: Fix full-width tab CSS [#880](https://github.com/mathuo/dockview/pull/880)
|
||||
- Bug: Fix tab divider CSS [#879](https://github.com/mathuo/dockview/pull/879)
|
||||
|
||||
## 🔥 Breaking changes
|
||||
|
23
packages/docs/blog/2025-03-16-dockview-4.1.0.md
Normal file
23
packages/docs/blog/2025-03-16-dockview-4.1.0.md
Normal file
@ -0,0 +1,23 @@
|
||||
---
|
||||
slug: dockview-4.1.0-release
|
||||
title: Dockview 4.1.0
|
||||
tags: [release]
|
||||
---
|
||||
|
||||
# Release Notes
|
||||
|
||||
Please reference docs @ [dockview.dev](https://dockview.dev).
|
||||
|
||||
## 🚀 Features
|
||||
|
||||
- Custom header size for Paneview components [#875](https://github.com/mathuo/dockview/pull/875)
|
||||
- Add events `onDidPopoutGroupSizeChange` and `onDidPopoutGroupPositionChange` [#876](https://github.com/mathuo/dockview/pull/876)
|
||||
|
||||
## 🛠 Miscs
|
||||
|
||||
- Bug: Prevent ghost DOM elements after `fromJSON` calls on Splitview components [#881](https://github.com/mathuo/dockview/pull/881)
|
||||
- Bug: Disable point-events for iframes within shadow DOMs during tab dnd events [#791](https://github.com/mathuo/dockview/pull/791)
|
||||
- Bug: Custom group id when no reference panel nor group is provided [#882](https://github.com/mathuo/dockview/pull/882)
|
||||
|
||||
## 🔥 Breaking changes
|
||||
|
20
packages/docs/blog/2025-03-17-dockview-4.2.0.md
Normal file
20
packages/docs/blog/2025-03-17-dockview-4.2.0.md
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
slug: dockview-4.2.0-release
|
||||
title: Dockview 4.2.0
|
||||
tags: [release]
|
||||
---
|
||||
|
||||
# Release Notes
|
||||
|
||||
Please reference docs @ [dockview.dev](https://dockview.dev).
|
||||
|
||||
## 🚀 Features
|
||||
|
||||
- `scrollbars` options [#885](https://github.com/mathuo/dockview/pull/885)
|
||||
|
||||
## 🛠 Miscs
|
||||
|
||||
- Bug: Fix group dnd [#885](https://github.com/mathuo/dockview/pull/885)
|
||||
|
||||
## 🔥 Breaking changes
|
||||
|
20
packages/docs/blog/2025-03-18-dockview-4.2.1.md
Normal file
20
packages/docs/blog/2025-03-18-dockview-4.2.1.md
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
slug: dockview-4.2.1-release
|
||||
title: Dockview 4.2.1
|
||||
tags: [release]
|
||||
---
|
||||
|
||||
# Release Notes
|
||||
|
||||
Please reference docs @ [dockview.dev](https://dockview.dev).
|
||||
|
||||
## 🚀 Features
|
||||
|
||||
|
||||
## 🛠 Miscs
|
||||
|
||||
- Bug: Fix styles and dnd issues [#887](https://github.com/mathuo/dockview/pull/887)
|
||||
- Bug: Fix options init issues [#888](https://github.com/mathuo/dockview/pull/888)
|
||||
|
||||
## 🔥 Breaking changes
|
||||
|
19
packages/docs/blog/2025-03-26-dockview-4.2.2.md
Normal file
19
packages/docs/blog/2025-03-26-dockview-4.2.2.md
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
slug: dockview-4.2.2-release
|
||||
title: Dockview 4.2.2
|
||||
tags: [release]
|
||||
---
|
||||
|
||||
# Release Notes
|
||||
|
||||
Please reference docs @ [dockview.dev](https://dockview.dev).
|
||||
|
||||
## 🚀 Features
|
||||
|
||||
|
||||
## 🛠 Miscs
|
||||
|
||||
- Bug: React disposable issues [#892](https://github.com/mathuo/dockview/pull/892)
|
||||
|
||||
## 🔥 Breaking changes
|
||||
|
19
packages/docs/blog/2025-04-08-dockview-4.2.3.md
Normal file
19
packages/docs/blog/2025-04-08-dockview-4.2.3.md
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
slug: dockview-4.2.3-release
|
||||
title: Dockview 4.2.3
|
||||
tags: [release]
|
||||
---
|
||||
|
||||
# Release Notes
|
||||
|
||||
Please reference docs @ [dockview.dev](https://dockview.dev).
|
||||
|
||||
## 🚀 Features
|
||||
|
||||
|
||||
## 🛠 Miscs
|
||||
|
||||
- Bug: React disposable issues [#892](https://github.com/mathuo/dockview/pull/892)
|
||||
|
||||
## 🔥 Breaking changes
|
||||
|
21
packages/docs/blog/2025-04-29-dockview-4.2.4.md
Normal file
21
packages/docs/blog/2025-04-29-dockview-4.2.4.md
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
slug: dockview-4.2.4-release
|
||||
title: Dockview 4.2.4
|
||||
tags: [release]
|
||||
---
|
||||
|
||||
# Release Notes
|
||||
|
||||
Please reference docs @ [dockview.dev](https://dockview.dev).
|
||||
|
||||
## 🚀 Features
|
||||
|
||||
|
||||
## 🛠 Miscs
|
||||
|
||||
- Bug: Ghost groups appearing when in popout mode [#917](https://github.com/mathuo/dockview/pull/917)
|
||||
- Bug: Tab overflow dropdown rendering fixes [#916](https://github.com/mathuo/dockview/pull/916)
|
||||
- Update docs [#828](https://github.com/mathuo/dockview/pull/828) [#827](https://github.com/mathuo/dockview/pull/827)
|
||||
|
||||
## 🔥 Breaking changes
|
||||
|
20
packages/docs/blog/2025-05-01-dockview-4.2.5.md
Normal file
20
packages/docs/blog/2025-05-01-dockview-4.2.5.md
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
slug: dockview-4.2.5-release
|
||||
title: Dockview 4.2.5
|
||||
tags: [release]
|
||||
---
|
||||
|
||||
# Release Notes
|
||||
|
||||
Please reference docs @ [dockview.dev](https://dockview.dev).
|
||||
|
||||
## 🚀 Features
|
||||
|
||||
|
||||
## 🛠 Miscs
|
||||
|
||||
- Bug: Tab overflow dropdown positions on boundaries of viewport [#921](https://github.com/mathuo/dockview/pull/921)
|
||||
- Bug: Dnd Ghost image rendering interactivity issues [#920](https://github.com/mathuo/dockview/pull/920)
|
||||
|
||||
## 🔥 Breaking changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dockview-docs",
|
||||
"version": "4.0.0",
|
||||
"version": "4.2.5",
|
||||
"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": "^4.0.0",
|
||||
"dockview": "^4.2.5",
|
||||
"prism-react-renderer": "^2.3.1",
|
||||
"react-dnd": "^16.0.1",
|
||||
"react-laag": "^2.0.5",
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
DockviewTheme,
|
||||
} from 'dockview';
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom/client';
|
||||
import './app.scss';
|
||||
import { defaultConfig } from './defaultLayout';
|
||||
import { GridActions } from './gridActions';
|
||||
@ -31,6 +32,20 @@ const Option = (props: {
|
||||
);
|
||||
};
|
||||
|
||||
const ShadowIframe = (props: IDockviewPanelProps) => {
|
||||
return (
|
||||
<iframe
|
||||
onMouseDown={() => {
|
||||
if (!props.api.isActive) {
|
||||
props.api.setActive();
|
||||
}
|
||||
}}
|
||||
style={{ border: 'none', width: '100%', height: '100%' }}
|
||||
src="https://dockview.dev"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const components = {
|
||||
default: (props: IDockviewPanelProps) => {
|
||||
const isDebug = React.useContext(DebugContext);
|
||||
@ -110,6 +125,7 @@ const components = {
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
border: 'none',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
}}
|
||||
@ -117,6 +133,33 @@ const components = {
|
||||
/>
|
||||
);
|
||||
},
|
||||
shadowDom: (props: IDockviewPanelProps) => {
|
||||
const ref = React.useRef<HTMLDivElement>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!ref.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
const shadow = ref.current.attachShadow({
|
||||
mode: 'open',
|
||||
});
|
||||
|
||||
const shadowRoot = document.createElement('div');
|
||||
shadowRoot.style.height = '100%';
|
||||
shadow.appendChild(shadowRoot);
|
||||
|
||||
const root = ReactDOM.createRoot(shadowRoot);
|
||||
|
||||
root.render(<ShadowIframe {...props} />);
|
||||
|
||||
return () => {
|
||||
root.unmount();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return <div style={{ height: '100%' }} ref={ref}></div>;
|
||||
},
|
||||
};
|
||||
|
||||
const headerComponents = {
|
||||
|
@ -22,9 +22,6 @@ export const Introduction = () => {
|
||||
<img src={useBaseUrl('/img/dockview_logo.svg')} height={30} />
|
||||
<span style={{ paddingLeft: '8px' }}>Dockview Live Demos</span>
|
||||
</div>
|
||||
<div style={{ padding: '20px' }}>
|
||||
<BrowserHeader />
|
||||
</div>
|
||||
<div style={{ padding: '20px' }}>
|
||||
<BrowserHeader />
|
||||
<MultiFrameworkContainer
|
||||
|
@ -2387,6 +2387,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "onDidPopoutGroupPositionChange",
|
||||
"code": "Event<PopoutGroupChangePositionEvent>",
|
||||
"kind": "accessor",
|
||||
"value": {
|
||||
"name": "onDidPopoutGroupPositionChange",
|
||||
"code": "Event<PopoutGroupChangePositionEvent>",
|
||||
"kind": "getSignature",
|
||||
"returnType": {
|
||||
"type": "reference",
|
||||
"value": "Event",
|
||||
"source": "dockview-core",
|
||||
"typeArguments": [
|
||||
{
|
||||
"type": "reference",
|
||||
"value": "PopoutGroupChangePositionEvent",
|
||||
"source": "dockview-core"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "onDidPopoutGroupSizeChange",
|
||||
"code": "Event<PopoutGroupChangeSizeEvent>",
|
||||
"kind": "accessor",
|
||||
"value": {
|
||||
"name": "onDidPopoutGroupSizeChange",
|
||||
"code": "Event<PopoutGroupChangeSizeEvent>",
|
||||
"kind": "getSignature",
|
||||
"returnType": {
|
||||
"type": "reference",
|
||||
"value": "Event",
|
||||
"source": "dockview-core",
|
||||
"typeArguments": [
|
||||
{
|
||||
"type": "reference",
|
||||
"value": "PopoutGroupChangeSizeEvent",
|
||||
"source": "dockview-core"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "onDidRemoveGroup",
|
||||
"code": "Event<DockviewGroupPanel>",
|
||||
@ -4399,6 +4443,46 @@
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "onDidPopoutGroupPositionChange",
|
||||
"code": "Event<PopoutGroupChangePositionEvent>",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "reference",
|
||||
"value": "Event",
|
||||
"source": "dockview-core",
|
||||
"typeArguments": [
|
||||
{
|
||||
"type": "reference",
|
||||
"value": "PopoutGroupChangePositionEvent",
|
||||
"source": "dockview-core"
|
||||
}
|
||||
]
|
||||
},
|
||||
"flags": {
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "onDidPopoutGroupSizeChange",
|
||||
"code": "Event<PopoutGroupChangeSizeEvent>",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "reference",
|
||||
"value": "Event",
|
||||
"source": "dockview-core",
|
||||
"typeArguments": [
|
||||
{
|
||||
"type": "reference",
|
||||
"value": "PopoutGroupChangeSizeEvent",
|
||||
"source": "dockview-core"
|
||||
}
|
||||
]
|
||||
},
|
||||
"flags": {
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "onDidRemove",
|
||||
"code": "Event<DockviewGroupPanel>",
|
||||
@ -9761,6 +9845,19 @@
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "accessor",
|
||||
"code": "IPaneviewComponent",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "reference",
|
||||
"value": "IPaneviewComponent",
|
||||
"source": "dockview-core"
|
||||
},
|
||||
"flags": {
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "api",
|
||||
"code": "PaneviewPanelApiImpl",
|
||||
@ -9816,6 +9913,39 @@
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "headerComponent",
|
||||
"code": "string | undefined",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "or",
|
||||
"values": [
|
||||
{
|
||||
"type": "intrinsic",
|
||||
"value": "string"
|
||||
},
|
||||
{
|
||||
"type": "intrinsic",
|
||||
"value": "undefined"
|
||||
}
|
||||
]
|
||||
},
|
||||
"flags": {
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "headerSize",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "id",
|
||||
"code": "string",
|
||||
@ -14987,6 +15117,19 @@
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "accessor",
|
||||
"code": "IPaneviewComponent",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "reference",
|
||||
"value": "IPaneviewComponent",
|
||||
"source": "dockview-core"
|
||||
},
|
||||
"flags": {
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "api",
|
||||
"code": "PaneviewPanelApiImpl",
|
||||
@ -15042,6 +15185,39 @@
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "headerComponent",
|
||||
"code": "string | undefined",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "or",
|
||||
"values": [
|
||||
{
|
||||
"type": "intrinsic",
|
||||
"value": "string"
|
||||
},
|
||||
{
|
||||
"type": "intrinsic",
|
||||
"value": "undefined"
|
||||
}
|
||||
]
|
||||
},
|
||||
"flags": {
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "headerSize",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "id",
|
||||
"code": "string",
|
||||
@ -18020,6 +18196,39 @@
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "headerComponent",
|
||||
"code": "string | undefined",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "or",
|
||||
"values": [
|
||||
{
|
||||
"type": "intrinsic",
|
||||
"value": "string"
|
||||
},
|
||||
{
|
||||
"type": "intrinsic",
|
||||
"value": "undefined"
|
||||
}
|
||||
]
|
||||
},
|
||||
"flags": {
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "headerSize",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "id",
|
||||
"code": "string",
|
||||
@ -22515,6 +22724,18 @@
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "headerSize",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "id",
|
||||
"code": "string",
|
||||
@ -25811,7 +26032,7 @@
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"text": "\nwill mount the overlay to root of the dockview component whereas "
|
||||
"text": "\r\nwill mount the overlay to root of the dockview component whereas "
|
||||
},
|
||||
{
|
||||
"kind": "code",
|
||||
@ -29259,6 +29480,46 @@
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "onDidPopoutGroupPositionChange",
|
||||
"code": "Event<PopoutGroupChangePositionEvent>",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "reference",
|
||||
"value": "Event",
|
||||
"source": "dockview-core",
|
||||
"typeArguments": [
|
||||
{
|
||||
"type": "reference",
|
||||
"value": "PopoutGroupChangePositionEvent",
|
||||
"source": "dockview-core"
|
||||
}
|
||||
]
|
||||
},
|
||||
"flags": {
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "onDidPopoutGroupSizeChange",
|
||||
"code": "Event<PopoutGroupChangeSizeEvent>",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "reference",
|
||||
"value": "Event",
|
||||
"source": "dockview-core",
|
||||
"typeArguments": [
|
||||
{
|
||||
"type": "reference",
|
||||
"value": "PopoutGroupChangeSizeEvent",
|
||||
"source": "dockview-core"
|
||||
}
|
||||
]
|
||||
},
|
||||
"flags": {
|
||||
"isReadonly": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "onDidRemoveGroup",
|
||||
"code": "Event<DockviewGroupPanel>",
|
||||
@ -39967,6 +40228,82 @@
|
||||
"code": "",
|
||||
"kind": "interface"
|
||||
},
|
||||
"PopoutGroupChangePositionEvent": {
|
||||
"kind": "interface",
|
||||
"name": "PopoutGroupChangePositionEvent",
|
||||
"children": [
|
||||
{
|
||||
"name": "group",
|
||||
"code": "DockviewGroupPanel",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "reference",
|
||||
"value": "DockviewGroupPanel",
|
||||
"source": "dockview-core"
|
||||
},
|
||||
"flags": {}
|
||||
},
|
||||
{
|
||||
"name": "screenX",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {}
|
||||
},
|
||||
{
|
||||
"name": "screenY",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {}
|
||||
}
|
||||
],
|
||||
"extends": []
|
||||
},
|
||||
"PopoutGroupChangeSizeEvent": {
|
||||
"kind": "interface",
|
||||
"name": "PopoutGroupChangeSizeEvent",
|
||||
"children": [
|
||||
{
|
||||
"name": "group",
|
||||
"code": "DockviewGroupPanel",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "reference",
|
||||
"value": "DockviewGroupPanel",
|
||||
"source": "dockview-core"
|
||||
},
|
||||
"flags": {}
|
||||
},
|
||||
{
|
||||
"name": "height",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {}
|
||||
},
|
||||
{
|
||||
"name": "width",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {}
|
||||
}
|
||||
],
|
||||
"extends": []
|
||||
},
|
||||
"RendererChangedEvent": {
|
||||
"kind": "interface",
|
||||
"name": "RendererChangedEvent",
|
||||
@ -40485,6 +40822,18 @@
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "headerSize",
|
||||
"code": "number",
|
||||
"kind": "property",
|
||||
"type": {
|
||||
"type": "intrinsic",
|
||||
"value": "number"
|
||||
},
|
||||
"flags": {
|
||||
"isOptional": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "maximumSize",
|
||||
"code": "number",
|
||||
|
Loading…
Reference in New Issue
Block a user