Merge branch 'master' of https://github.com/mathuo/dockview into 936-handle-browser-blocked-popups

This commit is contained in:
mathuo 2025-06-15 21:59:18 +01:00
commit b28245b4af
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
16 changed files with 150 additions and 42 deletions

View File

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

View File

@ -1,6 +1,6 @@
{
"name": "dockview-angular",
"version": "4.2.5",
"version": "4.3.1",
"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.2.5"
"dockview-core": "^4.3.1"
}
}

View File

@ -1,6 +1,6 @@
{
"name": "dockview-core",
"version": "4.2.5",
"version": "4.3.1",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews",
"keywords": [
"splitview",

View File

@ -5597,6 +5597,67 @@ describe('dockviewComponent', () => {
expect(dockview.groups.length).toBe(0);
});
test('popout single panel -> save layout -> load layout', async () => {
const container = document.createElement('div');
window.open = () => setupMockWindow();
const dockview = new DockviewComponent(container, {
createComponent(options) {
switch (options.name) {
case 'default':
return new PanelContentPartTest(
options.id,
options.name
);
default:
throw new Error(`unsupported`);
}
},
});
dockview.layout(1000, 500);
const panel1 = dockview.addPanel({
id: 'panel_1',
component: 'default',
});
const panel2 = dockview.addPanel({
id: 'panel_2',
component: 'default',
});
const panel3 = dockview.addPanel({
id: 'panel_3',
component: 'default',
});
const panel4 = dockview.addPanel({
id: 'panel_4',
component: 'default',
position: { direction: 'right' },
});
expect(dockview.panels.length).toBe(4);
expect(dockview.groups.length).toBe(2);
expect(await dockview.addPopoutGroup(panel1)).toBeTruthy();
expect(dockview.panels.length).toBe(4);
expect(dockview.groups.length).toBe(3);
expect(panel1.api.location.type).toBe('popout');
dockview.fromJSON(dockview.toJSON());
await new Promise((resolve) => setTimeout(resolve, 0)); // popout views are completed as a promise so must complete microtask-queue
expect(dockview.panels.length).toBe(4);
expect(dockview.groups.length).toBe(3);
expect(dockview.groups.every((g) => g.api.isVisible)).toBeTruthy();
});
test('move from fixed to popout group and back', async () => {
const container = document.createElement('div');

View File

@ -1,9 +1,4 @@
import {
AsapEvent,
Emitter,
Event,
addDisposableListener,
} from '../events';
import { AsapEvent, Emitter, Event, addDisposableListener } from '../events';
describe('events', () => {
describe('emitter', () => {
@ -67,7 +62,7 @@ describe('events', () => {
expect(value).toBeUndefined();
});
it('should relay last value in replay mode', () => {
it('should replay last value in replay mode', () => {
const emitter = new Emitter<number>({ replay: true });
let value: number | undefined = undefined;
@ -80,6 +75,20 @@ describe('events', () => {
stream.dispose();
});
it('should not replay last value in replay mode', () => {
const emitter = new Emitter<number>();
let value: number | undefined = undefined;
emitter.fire(1);
const stream = emitter.event((x) => {
value = x;
});
expect(value).toBeUndefined();
stream.dispose();
});
});
describe('asapEvent', () => {

View File

@ -168,10 +168,10 @@ export class Droptarget extends CompositeDisposable {
onDragOver: (e) => {
Droptarget.ACTUAL_TARGET = this;
const overrideTraget = this.options.getOverrideTarget?.();
const overrideTarget = this.options.getOverrideTarget?.();
if (this._acceptedTargetZonesSet.size === 0) {
if (overrideTraget) {
if (overrideTarget) {
return;
}
this.removeDropTarget();
@ -214,7 +214,7 @@ export class Droptarget extends CompositeDisposable {
}
if (!this.options.canDisplayOverlay(e, quadrant)) {
if (overrideTraget) {
if (overrideTarget) {
return;
}
this.removeDropTarget();
@ -239,7 +239,7 @@ export class Droptarget extends CompositeDisposable {
this.markAsUsed(e);
if (overrideTraget) {
if (overrideTarget) {
//
} else if (!this.targetElement) {
this.targetElement = document.createElement('div');

View File

@ -13,7 +13,7 @@ import { DockviewGroupPanelModel } from '../../dockviewGroupPanelModel';
export class VoidContainer extends CompositeDisposable {
private readonly _element: HTMLElement;
private readonly dropTraget: Droptarget;
private readonly dropTarget: Droptarget;
private readonly _onDrop = new Emitter<DroptargetEvent>();
readonly onDrop: Event<DroptargetEvent> = this._onDrop.event;
@ -48,7 +48,7 @@ export class VoidContainer extends CompositeDisposable {
const handler = new GroupDragHandler(this._element, accessor, group);
this.dropTraget = new Droptarget(this._element, {
this.dropTarget = new Droptarget(this._element, {
acceptedTargetZones: ['center'],
canDisplayOverlay: (event, position) => {
const data = getPanelData();
@ -66,17 +66,17 @@ export class VoidContainer extends CompositeDisposable {
getOverrideTarget: () => group.model.dropTargetContainer?.model,
});
this.onWillShowOverlay = this.dropTraget.onWillShowOverlay;
this.onWillShowOverlay = this.dropTarget.onWillShowOverlay;
this.addDisposables(
handler,
handler.onDragStart((event) => {
this._onDragStart.fire(event);
}),
this.dropTraget.onDrop((event) => {
this.dropTarget.onDrop((event) => {
this._onDrop.fire(event);
}),
this.dropTraget
this.dropTarget
);
}
}

View File

@ -116,6 +116,7 @@ export interface DockviewPopoutGroupOptions {
* Defaults to `/popout.html` if not provided
*/
popoutUrl?: string;
referenceGroup?: DockviewGroupPanel;
onDidOpen?: (event: { id: string; window: Window }) => void;
onWillClose?: (event: { id: string; window: Window }) => void;
overridePopoutGroup?: DockviewGroupPanel;
@ -329,7 +330,7 @@ export class DockviewComponent
private readonly _onDidActivePanelChange = new Emitter<
IDockviewPanel | undefined
>();
>({ replay: true });
readonly onDidActivePanelChange: Event<IDockviewPanel | undefined> =
this._onDidActivePanelChange.event;
@ -1510,18 +1511,14 @@ export class DockviewComponent
const group = createGroupFromSerializedState(data);
this.addPopoutGroup(
(gridReferenceGroup
this.addPopoutGroup(group, {
position: position ?? undefined,
overridePopoutGroup: gridReferenceGroup ? group : undefined,
referenceGroup: gridReferenceGroup
? this.getPanel(gridReferenceGroup)
: undefined) ?? group,
{
position: position ?? undefined,
overridePopoutGroup: gridReferenceGroup
? group
: undefined,
popoutUrl: url,
}
);
: undefined,
popoutUrl: url,
});
}
for (const floatingGroup of this._floatingGroups) {

View File

@ -160,7 +160,9 @@ export class Emitter<T> implements IDisposable {
}
public fire(e: T): void {
this._last = e;
if(this.options?.replay){
this._last = e;
}
for (const listener of this._listeners) {
listener.callback(e);
}

View File

@ -1,6 +1,6 @@
{
"name": "dockview-react",
"version": "4.2.5",
"version": "4.3.1",
"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.2.5"
"dockview": "^4.3.1"
}
}

View File

@ -1,6 +1,6 @@
{
"name": "dockview-vue",
"version": "4.2.5",
"version": "4.3.1",
"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.2.5"
"dockview-core": "^4.3.1"
},
"peerDependencies": {
"vue": "^3.4.0"

View File

@ -1,6 +1,6 @@
{
"name": "dockview",
"version": "4.2.5",
"version": "4.3.1",
"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.2.5"
"dockview-core": "^4.3.1"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"

View File

@ -0,0 +1,21 @@
---
slug: dockview-4.3.0-release
title: Dockview 4.3.0
tags: [release]
---
# Release Notes
Please reference docs @ [dockview.dev](https://dockview.dev).
## 🚀 Features
- Hide group private methods from public API [#925](https://github.com/mathuo/dockview/pull/925)
## 🛠 Miscs
- Bug: Fix the restoring of popout groups from layout [#933](https://github.com/mathuo/dockview/pull/933)
- Internals: Variable name typo [#940](https://github.com/mathuo/dockview/pull/940)
## 🔥 Breaking changes

View File

@ -0,0 +1,18 @@
---
slug: dockview-4.3.1-release
title: Dockview 4.3.1
tags: [release]
---
# Release Notes
Please reference docs @ [dockview.dev](https://dockview.dev).
## 🚀 Features
## 🛠 Miscs
- Internal: Improve GC cleanup by only retaining previously emitted event values when event is in replay mode [#947](https://github.com/mathuo/dockview/pull/947)
## 🔥 Breaking changes

View File

@ -1,6 +1,6 @@
{
"name": "dockview-docs",
"version": "4.2.5",
"version": "4.3.1",
"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.2.5",
"dockview": "^4.3.1",
"prism-react-renderer": "^2.3.1",
"react-dnd": "^16.0.1",
"react-laag": "^2.0.5",

View File

@ -19,7 +19,7 @@ export default function Home(): JSX.Element {
<div className="splashscreen-title">
<h1>Fully Featured Docking Layout Manager</h1>
<h2>
Zero dependency layout managment and docking
Zero dependency layout management and docking
controls
</h2>
</div>