Compare commits

...

63 Commits

Author SHA1 Message Date
mathuo
1e63da807b
chore(release): publish v4.2.5 2025-05-01 17:59:15 +01:00
mathuo
68d7947dea
chore: v4.2.5 docs 2025-05-01 17:58:55 +01:00
mathuo
093a034738
Merge pull request #921 from mathuo/883-tab-overflow-dropdown-doesnt-collide-with-edge-of-screen
883 tab overflow dropdown doesnt collide with edge of screen
2025-04-30 20:43:39 +01:00
mathuo
f9ca5b99d5
Merge pull request #920 from mathuo/891-first-tab-does-not-drag-drop-when-there-is-not-enough-space-above-the-dockview-area
bug: fix ghost image rendering
2025-04-30 20:43:16 +01:00
mathuo
420466398d
bug: popout service overflow handle 2025-04-29 22:01:27 +01:00
mathuo
20b5c844f3
Merge branch 'master' of https://github.com/mathuo/dockview into 883-tab-overflow-dropdown-doesnt-collide-with-edge-of-screen 2025-04-29 22:00:44 +01:00
mathuo
6d2f2f1012
bug: fix ghost image rendering 2025-04-29 21:45:23 +01:00
mathuo
3ddea55834
chore(release): publish v4.2.4 2025-04-29 21:01:28 +01:00
mathuo
2f334c63c1
chore: v4.2.4 docs 2025-04-29 21:01:04 +01:00
mathuo
8334f9795c
Merge pull request #917 from mathuo/913-returning-group-in-popout-to-main-window-via-drag-creates-empty-space-ghost-group
bug: ghost groups appearing
2025-04-28 21:32:47 +01:00
mathuo
7ea3154946
Merge pull request #828 from dzek69/patch-1
Fix provenance npm link
2025-04-28 21:27:28 +01:00
mathuo
1ef3dc06ce
Merge pull request #827 from AlexErrant/patch-1
drop extraneous <BrowserHeader />
2025-04-28 21:25:47 +01:00
mathuo
1ff74f2e65
Merge pull request #916 from mathuo/903-popover-overflow-when-hovering-right-aligned-more-icon-in-panel-group
903 popover overflow when hovering right aligned more icon in panel group
2025-04-28 21:24:40 +01:00
mathuo
a82aac09bc
bug: ghost groups appearing 2025-04-23 20:57:35 +01:00
mathuo
d1239a5ee5
bug: popup within floating panel 2025-04-23 20:35:46 +01:00
mathuo
22deb851dc
bug: popup overflow 2025-04-15 19:24:23 +01:00
mathuo
87f257df1e
chore(release): publish v4.2.3 2025-04-08 18:23:57 +01:00
mathuo
a92a056981
chore: correct versions 2025-04-08 18:23:44 +01:00
mathuo
c3e203f420
chore: update lerna 2025-04-08 18:22:33 +01:00
mathuo
8bdd15161c
chore: v4.2.3 docs 2025-04-08 18:19:12 +01:00
mathuo
8a3a7e5063
chore(release): publish v4.2.2 2025-03-26 22:15:46 +00:00
mathuo
65d95f1271
chore: v4.2.2 docs 2025-03-26 22:15:14 +00:00
mathuo
3ec6627013
Merge pull request #892 from mathuo/889-splitviewreact-and-gridviewreact-encounter-error-invalid-operation-resource-is-already-disposed
bug: remove reference to component once disposed preventing further u…
2025-03-26 22:14:59 +00:00
mathuo
c0227d620c
bug: remove reference to component once disposed preventing further usage 2025-03-26 22:08:31 +00:00
mathuo
aad168da84
chore(release): publish v4.2.1 2025-03-18 19:52:39 +00:00
mathuo
dfee4111a2
chore: v4.2.1 docs 2025-03-18 19:46:05 +00:00
mathuo
712f3f860d
Merge pull request #888 from mathuo/886-drag-and-drop-broken-after-latest-version-420
bug: fix options init
2025-03-18 19:45:23 +00:00
mathuo
f545a0a5c7
Merge pull request #887 from mathuo/884-cant-drop-tabs-between-panels-and-some-other-issues-with-v4-1
bug: dnd issues
2025-03-18 19:40:21 +00:00
mathuo
e3d39fd2ed
bug: fix options init 2025-03-18 19:38:32 +00:00
mathuo
dca0eb0df7
bug: dnd issues 2025-03-18 19:32:54 +00:00
mathuo
8188fd9429
chore(release): publish v4.2.0 2025-03-17 19:49:00 +00:00
mathuo
54a51ed10b
Merge branch 'master' of https://github.com/mathuo/dockview 2025-03-17 19:48:49 +00:00
mathuo
1a11a4ba2c
chore: docs 2025-03-17 19:48:37 +00:00
mathuo
b6d83df1aa
chore: v4.2.0 docs 2025-03-17 19:47:34 +00:00
mathuo
6444e4cb7d
Merge pull request #885 from mathuo/884-cant-drop-tabs-between-panels-and-some-other-issues-with-v4
feat: disableCustomScrollbars option
2025-03-17 19:47:13 +00:00
mathuo
ca7bd0a86d
bug: popover z-index 2025-03-17 19:29:06 +00:00
mathuo
dc828b7658
feat: disableCustomScrollbars option 2025-03-17 19:28:36 +00:00
mathuo
6e02e59fec
chore: v4.1.0 docs 2025-03-16 21:09:38 +00:00
mathuo
f79bbe0a6a
chore(release): publish v4.1.0 2025-03-16 21:08:08 +00:00
mathuo
12448e006f
chore: v4.1.0 docs 2025-03-16 21:07:51 +00:00
mathuo
5e380affe7
Merge pull request #882 from mathuo/676-is-it-possiable-that-the-id-and-title-of-group-can-be-assigned
676 is it possiable that the id and title of group can be assigned
2025-03-16 21:01:18 +00:00
mathuo
a44fc01f34
Merge branch 'master' of https://github.com/mathuo/dockview into 676-is-it-possiable-that-the-id-and-title-of-group-can-be-assigned 2025-03-16 20:48:41 +00:00
mathuo
8e03e584a7
Merge pull request #876 from mathuo/857-ondidrepositionpopoutgroup-event
feat: popout group resize events
2025-03-16 20:45:40 +00:00
mathuo
1ddcaefe80
test: add tests 2025-03-16 20:43:04 +00:00
mathuo
d086dfd081
Merge pull request #864 from dqhieuu/master
Make `id` option in addGroup without referenceGroup/referencePanel work
2025-03-16 20:40:54 +00:00
mathuo
b231367e44
Merge pull request #791 from mathuo/774-drag-and-drop-not-working-for-iframe-panels-within-a-shadow-dom
bug: disable iframes within shadowdom during dnd
2025-03-16 20:33:07 +00:00
mathuo
bba22fedd4
feat: popout group resize events 2025-03-16 20:28:35 +00:00
mathuo
3ebcb8eaef
Merge pull request #875 from mathuo/863-headercomponents-for-paneviewreact-is-never-used-and-cannot-set-height-because-harcoded-to-22px
feat: custom paneview header height
2025-03-16 20:26:33 +00:00
mathuo
39dd5f0759
feat: more efficient search 2025-03-16 20:23:39 +00:00
mathuo
e4f07dfbda
Merge pull request #881 from mathuo/721-loading-of-splitview-state-from-json-adds-extra-div-containers-that-break-layout
bug: remove splitview dom element
2025-03-16 20:09:31 +00:00
mathuo
d30263af67
bug: remove splitview dom element 2025-03-14 22:12:22 +00:00
mathuo
54ae457ccd
chore(release): publish v4.0.1 2025-03-14 22:01:56 +00:00
mathuo
416039bc99
chore: v4.0.1 docs 2025-03-14 21:59:59 +00:00
mathuo
e8fdabba08
Merge pull request #880 from mathuo/878-fullwidth-tabs-are-not-rendered-full-width-in-40
bug: fix full-width css
2025-03-14 21:59:08 +00:00
mathuo
9373802115
Merge pull request #879 from mathuo/877-missing-tab-divider-in-40
bug: fix tab divider css
2025-03-14 21:59:03 +00:00
mathuo
759dcc7b05
bug: fix full-width css 2025-03-14 21:57:37 +00:00
mathuo
f8faca731d
bug: fix tab divider css 2025-03-14 21:55:33 +00:00
mathuo
d168356344
Merge branch 'master' of https://github.com/mathuo/dockview into 774-drag-and-drop-not-working-for-iframe-panels-within-a-shadow-dom 2025-03-12 21:23:46 +00:00
mathuo
64e11a880c
bug: disable iframes within shadowdom during dnd 2025-03-12 21:16:21 +00:00
mathuo
a306742508
feat: custom paneview header height 2025-03-12 21:03:05 +00:00
Hieu
6511b8d936
Make addGroup wiithout reference panel/group allow id option 2025-02-24 04:54:01 +07:00
Jacek Nowacki
0c1b8ce4d7
Fix provenance npm link 2025-01-12 12:12:26 +01:00
Alex Errant
f40532f272
drop extraneous <BrowserHeader /> 2025-01-11 16:17:34 -06:00
51 changed files with 2224 additions and 1076 deletions

View File

@ -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).

View File

@ -2,7 +2,7 @@
"packages": [
"packages/*"
],
"version": "4.0.0",
"version": "4.2.5",
"npmClient": "yarn",
"command": {
"publish": {

View File

@ -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",

View File

@ -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"
}
}

View File

@ -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",

View File

@ -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);
});
});
});

View File

@ -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);
});
});
});

View File

@ -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

View File

@ -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')!;

View File

@ -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);

View File

@ -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,
},
],
});

View File

@ -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({

View File

@ -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.
*/

View File

@ -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);

View File

@ -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 {

View File

@ -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;

View File

@ -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,

View File

@ -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;
}
}

View File

@ -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,
});
})
);

View File

@ -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
@ -55,6 +52,7 @@
}
}
}
}
}
/**

View File

@ -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;
}

View File

@ -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)[];

View File

@ -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;
}

View File

@ -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);
},
};
}

View File

@ -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();
})

View File

@ -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();
}
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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',
() => {

View File

@ -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(

View File

@ -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;
@ -258,7 +255,6 @@
}
}
}
}
}
.dockview-theme-abyss {

View File

@ -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"
}
}

View File

@ -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"

View File

@ -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"

View File

@ -175,6 +175,7 @@ export const DockviewReact = React.forwardRef(
dockviewRef.current = api;
return () => {
dockviewRef.current = undefined;
api.dispose();
};
}, []);

View File

@ -105,6 +105,7 @@ export const GridviewReact = React.forwardRef(
gridviewRef.current = api;
return () => {
gridviewRef.current = undefined;
api.dispose();
};
}, []);

View File

@ -120,6 +120,7 @@ export const PaneviewReact = React.forwardRef(
paneviewRef.current = api;
return () => {
paneviewRef.current = undefined;
api.dispose();
};
}, []);

View File

@ -105,6 +105,7 @@ export const SplitviewReact = React.forwardRef(
splitviewRef.current = api;
return () => {
splitviewRef.current = undefined;
api.dispose();
};
}, []);

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@ -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",

View File

@ -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 = {

View File

@ -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

View File

@ -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",

1518
yarn.lock

File diff suppressed because it is too large Load Diff