From 36299d08f9575250269bfa9ac3415b0c4a399f94 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Wed, 10 May 2023 22:06:12 +0100
Subject: [PATCH 01/23] feat: add typedocs
---
.github/workflows/deploy-docs.yml | 6 ++++--
.gitignore | 1 +
package.json | 7 +++++--
packages/dockview-core/typedoc.json | 7 ++-----
packages/dockview/package.json | 3 +--
packages/dockview/tsconfig.json | 3 ---
packages/dockview/typedoc.json | 8 +++-----
packages/docs/package.json | 3 +--
packages/docs/scripts/package-docs.js | 8 --------
scripts/package-docs.js | 9 ++++++---
scripts/package.js | 15 --------------
tsconfig.json | 11 ++++++++++
typedoc.base.json | 4 ++++
typedoc.json | 7 +++++++
yarn.lock | 29 +++++++++++++++++----------
15 files changed, 63 insertions(+), 58 deletions(-)
delete mode 100644 packages/docs/scripts/package-docs.js
delete mode 100644 scripts/package.js
create mode 100644 tsconfig.json
create mode 100644 typedoc.base.json
create mode 100644 typedoc.json
diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml
index 9c242d324..6b82733a6 100644
--- a/.github/workflows/deploy-docs.yml
+++ b/.github/workflows/deploy-docs.yml
@@ -33,8 +33,10 @@ jobs:
working-directory: packages/dockview
- run: npm run build
working-directory: packages/docs
- - run: npm run deploy-docs
- working-directory: packages/docs
+ - run: npm run docs
+ working-directory: .
+ - run: npm run package-docs
+ working-directory: .
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@3.7.1
with:
diff --git a/.gitignore b/.gitignore
index 5f1ae726d..a38d78f1f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,4 @@ test-report.xml
*.code-workspace
yarn-error.log
/build
+docs/
diff --git a/package.json b/package.json
index 8d35430d0..cf33e48ae 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,9 @@
"bootstrap": "lerna bootstrap",
"test:cov": "jest --coverage",
"version-beta-build": "lerna version prerelease --preid beta",
- "publish-app": "lerna publish"
+ "publish-app": "lerna publish",
+ "docs": "typedoc",
+ "package-docs": "node scripts/package-docs.js"
},
"repository": {
"type": "git",
@@ -56,6 +58,7 @@
"ts-jest": "^29.0.5",
"ts-loader": "^9.4.2",
"tslib": "^2.5.0",
+ "typedoc": "^0.24.7",
"typescript": "^4.9.5",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1",
@@ -65,4 +68,4 @@
"jest": "^29.5.0",
"ts-node": "^10.9.1"
}
-}
\ No newline at end of file
+}
diff --git a/packages/dockview-core/typedoc.json b/packages/dockview-core/typedoc.json
index 51c05e659..952d2032e 100644
--- a/packages/dockview-core/typedoc.json
+++ b/packages/dockview-core/typedoc.json
@@ -1,7 +1,4 @@
{
- "out": "typedocs",
- "entryPoints": ["./src/index.ts"],
- "exclude": ["**/_test/**/*.*", "**/index.ts"],
- "excludeExternals": true,
- "excludePrivate": true
+ "extends": ["../../typedoc.base.json"],
+ "entryPoints": ["src/index.ts"]
}
diff --git a/packages/dockview/package.json b/packages/dockview/package.json
index 5f538135d..19ec29c99 100644
--- a/packages/dockview/package.json
+++ b/packages/dockview/package.json
@@ -71,7 +71,6 @@
"react-dom": "^18.2.0",
"rimraf": "^4.1.2",
"rollup": "^3.15.0",
- "rollup-plugin-postcss": "^4.0.2",
- "typedoc": "^0.23.25"
+ "rollup-plugin-postcss": "^4.0.2"
}
}
diff --git a/packages/dockview/tsconfig.json b/packages/dockview/tsconfig.json
index f1a6f570c..023097d12 100644
--- a/packages/dockview/tsconfig.json
+++ b/packages/dockview/tsconfig.json
@@ -6,9 +6,6 @@
"jsx": "react",
"rootDir": "src"
},
- "paths": {
- "dockview-core": "../dockview-core"
- },
"include": ["src"],
"exclude": ["**/node_modules", "src/__tests__"]
}
diff --git a/packages/dockview/typedoc.json b/packages/dockview/typedoc.json
index 51c05e659..b97dde02c 100644
--- a/packages/dockview/typedoc.json
+++ b/packages/dockview/typedoc.json
@@ -1,7 +1,5 @@
{
- "out": "typedocs",
- "entryPoints": ["./src/index.ts"],
- "exclude": ["**/_test/**/*.*", "**/index.ts"],
- "excludeExternals": true,
- "excludePrivate": true
+ "extends": ["../../typedoc.base.json"],
+ "entryPoints": ["src/index.ts"],
+ "exclude": ["**/dist/**"]
}
diff --git a/packages/docs/package.json b/packages/docs/package.json
index c230bb45b..a5a509892 100644
--- a/packages/docs/package.json
+++ b/packages/docs/package.json
@@ -12,8 +12,7 @@
"serve": "docusaurus serve",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids",
- "typecheck": "tsc",
- "deploy-docs": "node scripts/package-docs.js"
+ "typecheck": "tsc"
},
"dependencies": {
"@docusaurus/core": "^2.4.0",
diff --git a/packages/docs/scripts/package-docs.js b/packages/docs/scripts/package-docs.js
deleted file mode 100644
index 23ce40038..000000000
--- a/packages/docs/scripts/package-docs.js
+++ /dev/null
@@ -1,8 +0,0 @@
-const fs = require('fs-extra');
-const path = require('path');
-
-const output = path.join(__dirname, '../../../build');
-
-const docsDir = path.join(__dirname, '../build');
-
-fs.copySync(docsDir, path.join(output));
diff --git a/scripts/package-docs.js b/scripts/package-docs.js
index 11ac3cf51..92c469bac 100644
--- a/scripts/package-docs.js
+++ b/scripts/package-docs.js
@@ -1,8 +1,11 @@
const fs = require('fs-extra');
const path = require('path');
-const output = path.join(__dirname, '../');
+const output = path.join(__dirname, '../build');
-const docsDir = path.join(__dirname, '../docs/build');
+const websiteDir = path.join(__dirname, '../packages/docs/build');
-fs.copySync(docsDir, path.join(output, 'docs'));
+const docsDir = path.join(__dirname, '../docs');
+
+fs.copySync(websiteDir, output);
+fs.copySync(docsDir, path.join(output, 'typedocs'));
diff --git a/scripts/package.js b/scripts/package.js
deleted file mode 100644
index 9b0238063..000000000
--- a/scripts/package.js
+++ /dev/null
@@ -1,15 +0,0 @@
-const fs = require('fs-extra');
-const path = require('path');
-
-const output = path.join(__dirname, '../output');
-
-const docsDir = path.join(__dirname, '../packages/dockview/typedocs');
-const webpackAppDir = path.join(__dirname, '../packages/dockview-demo/dist');
-// const storybookAppDir = path.join(
-// __dirname,
-// '../packages/dockview-demo/storybook-static'
-// );
-
-fs.copySync(docsDir, path.join(output, 'typedocs'));
-fs.copySync(webpackAppDir, path.join(output, 'build'));
-// fs.copySync(storybookAppDir, path.join(output, 'storybook-static'));
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 000000000..a9ac894b9
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./packages/dockview"
+ },
+ {
+ "path": "./packages/dockview-core"
+ }
+ ]
+}
diff --git a/typedoc.base.json b/typedoc.base.json
new file mode 100644
index 000000000..34bcb3e09
--- /dev/null
+++ b/typedoc.base.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://typedoc.org/schema.json",
+ "includeVersion": true
+}
\ No newline at end of file
diff --git a/typedoc.json b/typedoc.json
new file mode 100644
index 000000000..5b8c53b5d
--- /dev/null
+++ b/typedoc.json
@@ -0,0 +1,7 @@
+{
+ "entryPoints": ["packages/dockview", "packages/dockview-core"],
+ "name": "Dockview",
+ "entryPointStrategy": "packages",
+ "includeVersion": true,
+ "logLevel": "Verbose"
+}
diff --git a/yarn.lock b/yarn.lock
index f28480a93..cf1e11427 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9918,7 +9918,7 @@ markdown-escapes@^1.0.0:
resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535"
integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==
-marked@^4.2.12:
+marked@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3"
integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==
@@ -10136,13 +10136,20 @@ minimatch@^6.1.6:
dependencies:
brace-expansion "^2.0.1"
-minimatch@^7.1.3, minimatch@^7.4.1, minimatch@^7.4.2:
+minimatch@^7.4.1, minimatch@^7.4.2:
version "7.4.3"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.3.tgz#012cbf110a65134bb354ae9773b55256cdb045a2"
integrity sha512-5UB4yYusDtkRPbRiy1cqZ1IpGNcJCGlEMG17RKzPddpyiPKoCdwohbED8g4QXT0ewCt8LTkQXuljsUfQ3FKM4A==
dependencies:
brace-expansion "^2.0.1"
+minimatch@^9.0.0:
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.0.tgz#bfc8e88a1c40ffd40c172ddac3decb8451503b56"
+ integrity sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==
+ dependencies:
+ brace-expansion "^2.0.1"
+
minimist-options@4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619"
@@ -13180,9 +13187,9 @@ shelljs@^0.8.5:
rechoir "^0.6.2"
shiki@^0.14.1:
- version "0.14.1"
- resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.14.1.tgz#9fbe082d0a8aa2ad63df4fbf2ee11ec924aa7ee1"
- integrity sha512-+Jz4nBkCBe0mEDqo1eKRcCdjRtrCjozmcbTUjbPTX7OOJfEbTZzlUWlZtGe3Gb5oV1/jnojhG//YZc3rs9zSEw==
+ version "0.14.2"
+ resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.14.2.tgz#d51440800b701392b31ce2336036058e338247a1"
+ integrity sha512-ltSZlSLOuSY0M0Y75KA+ieRaZ0Trf5Wl3gutE7jzLuIcWxLp5i/uEnLoQWNvgKXQ5OMpGkJnVMRLAuzjc0LJ2A==
dependencies:
ansi-sequence-parser "^1.1.0"
jsonc-parser "^3.2.0"
@@ -14249,14 +14256,14 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
-typedoc@^0.23.25:
- version "0.23.28"
- resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.23.28.tgz#3ce9c36ef1c273fa849d2dea18651855100d3ccd"
- integrity sha512-9x1+hZWTHEQcGoP7qFmlo4unUoVJLB0H/8vfO/7wqTnZxg4kPuji9y3uRzEu0ZKez63OJAUmiGhUrtukC6Uj3w==
+typedoc@^0.24.7:
+ version "0.24.7"
+ resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.24.7.tgz#7eeb272a1894b3789acc1a94b3f2ae8e7330ee39"
+ integrity sha512-zzfKDFIZADA+XRIp2rMzLe9xZ6pt12yQOhCr7cD7/PBTjhPmMyMvGrkZ2lPNJitg3Hj1SeiYFNzCsSDrlpxpKw==
dependencies:
lunr "^2.3.9"
- marked "^4.2.12"
- minimatch "^7.1.3"
+ marked "^4.3.0"
+ minimatch "^9.0.0"
shiki "^0.14.1"
"typescript@^3 || ^4", typescript@^4.9.5:
From 3c24579e905c39ddbc07d54f91790476591f19c4 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Mon, 22 May 2023 21:10:43 +0100
Subject: [PATCH 02/23] chore: docs: plain typescript examples
---
.codesandbox/ci.json | 2 +-
packages/docs/docs/components/dockview.mdx | 37 ++---
.../javascript/simple-dockview/package.json | 27 ++++
.../simple-dockview}/public/index.html | 0
.../javascript/simple-dockview/src/app.ts | 114 ++++++++++++++
.../simple-dockview/src/index.tsx} | 0
.../simple-dockview}/src/styles.css | 0
.../simple-dockview}/tsconfig.json | 0
.../vanilla-dockview/package.json | 0
.../vanilla-dockview/public/index.html | 44 ++++++
.../vanilla-dockview/src/app.ts | 0
.../javascript/vanilla-dockview/src/index.ts | 10 ++
.../vanilla-dockview/src/styles.css | 16 ++
.../javascript/vanilla-dockview/tsconfig.json | 20 +++
.../updatetitle-dockview/src/app.tsx | 9 +-
.../docs/src/components/ui/container.scss | 0
packages/docs/src/components/ui/container.tsx | 147 ++++++++++++++++++
.../docs/src/components/ui/referenceTable.tsx | 42 +++++
packages/docs/src/components/ui/spinner.scss | 55 +++++++
packages/docs/src/components/ui/spinner.tsx | 13 ++
packages/docs/static/img/js-icon.svg | 4 +
packages/docs/static/img/react-icon.svg | 9 ++
.../version-1.7.2/components/dockview.mdx | 4 +-
23 files changed, 526 insertions(+), 27 deletions(-)
create mode 100644 packages/docs/sandboxes/javascript/simple-dockview/package.json
rename packages/docs/sandboxes/{vanilla-dockview => javascript/simple-dockview}/public/index.html (100%)
create mode 100644 packages/docs/sandboxes/javascript/simple-dockview/src/app.ts
rename packages/docs/sandboxes/{vanilla-dockview/src/index.ts => javascript/simple-dockview/src/index.tsx} (100%)
rename packages/docs/sandboxes/{vanilla-dockview => javascript/simple-dockview}/src/styles.css (100%)
rename packages/docs/sandboxes/{vanilla-dockview => javascript/simple-dockview}/tsconfig.json (100%)
rename packages/docs/sandboxes/{ => javascript}/vanilla-dockview/package.json (100%)
create mode 100644 packages/docs/sandboxes/javascript/vanilla-dockview/public/index.html
rename packages/docs/sandboxes/{ => javascript}/vanilla-dockview/src/app.ts (100%)
create mode 100644 packages/docs/sandboxes/javascript/vanilla-dockview/src/index.ts
create mode 100644 packages/docs/sandboxes/javascript/vanilla-dockview/src/styles.css
create mode 100644 packages/docs/sandboxes/javascript/vanilla-dockview/tsconfig.json
create mode 100644 packages/docs/src/components/ui/container.scss
create mode 100644 packages/docs/src/components/ui/referenceTable.tsx
create mode 100644 packages/docs/src/components/ui/spinner.scss
create mode 100644 packages/docs/src/components/ui/spinner.tsx
create mode 100644 packages/docs/static/img/js-icon.svg
create mode 100644 packages/docs/static/img/react-icon.svg
diff --git a/.codesandbox/ci.json b/.codesandbox/ci.json
index 4d276169b..be48bfccc 100644
--- a/.codesandbox/ci.json
+++ b/.codesandbox/ci.json
@@ -22,7 +22,7 @@
"/packages/docs/sandboxes/simple-dockview",
"/packages/docs/sandboxes/tabheight-dockview",
"/packages/docs/sandboxes/updatetitle-dockview",
- "/packages/docs/sandboxes/vanilla-dockview",
+ "/packages/docs/sandboxes/typescript/vanilla-dockview",
"/packages/docs/sandboxes/watermark-dockview"
],
"node": "16"
diff --git a/packages/docs/docs/components/dockview.mdx b/packages/docs/docs/components/dockview.mdx
index b6d1a3e46..8a4807c11 100644
--- a/packages/docs/docs/components/dockview.mdx
+++ b/packages/docs/docs/components/dockview.mdx
@@ -2,7 +2,10 @@
description: Dockview Documentation
---
-import { Container } from '@site/src/components/ui/container';
+import {
+ Container,
+ MultiFrameworkContainer,
+} from '@site/src/components/ui/container';
import Link from '@docusaurus/Link';
import useBaseUrl from '@docusaurus/useBaseUrl';
@@ -24,7 +27,9 @@ import RenderingDockview from '@site/sandboxes/rendering-dockview/src/app';
import DockviewExternalDnd from '@site/sandboxes/externaldnd-dockview/src/app';
import DockviewResizeContainer from '@site/sandboxes/resizecontainer-dockview/src/app';
import DockviewTabheight from '@site/sandboxes/tabheight-dockview/src/app';
-import { attach as attachDockviewVanilla } from '@site/sandboxes/vanilla-dockview/src/app';
+
+import { attach as attachDockviewVanilla } from '@site/sandboxes/javascript/vanilla-dockview/src/app';
+import { attach as attachSimpleDockview } from '@site/sandboxes/javascript/simple-dockview/src/app';
# Dockview
@@ -32,12 +37,16 @@ import { attach as attachDockviewVanilla } from '@site/sandboxes/vanilla-dockvie
Dockview is an abstraction built on top of [Gridviews](./gridview) where each view is a container of many tabbed panels.
-
-
-
+
-You can access the panels associated group through the `panel.group` variable.
-The group will always be defined and will change if a panel is moved into another group.
+
+
+> You can access the panels associated group through the `panel.group` variable.
+> The group will always be defined and will change if a panel is moved into another group.
## DockviewReact Component
@@ -705,19 +714,11 @@ If you wish to interact with the drop event from one dockview instance in anothe
-### Example
-
-hello
+### Window-like mananger with tabs
-hello 2
-
-
-
-## VanillaJS
+## Vanilla JS
> Note: This section is experimental and support for Vanilla JS is a work in progress.
@@ -728,6 +729,6 @@ The core library is published as an independant package under the name `dockview
> `dockview-core` is a dependency of `dockview` and automatically installed during the installation process of `dockview` via `npm install dockview`.
diff --git a/packages/docs/sandboxes/javascript/simple-dockview/package.json b/packages/docs/sandboxes/javascript/simple-dockview/package.json
new file mode 100644
index 000000000..bc36e6b5d
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/simple-dockview/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "javascript-simple-dockview",
+ "description": "",
+ "keywords": [
+ "dockview"
+ ],
+ "version": "1.0.0",
+ "main": "src/index.ts",
+ "dependencies": {
+ "dockview-core": "*"
+ },
+ "devDependencies": {
+ "typescript": "^4.9.5"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test --env=jsdom",
+ "eject": "react-scripts eject"
+ },
+ "browserslist": [
+ ">0.2%",
+ "not dead",
+ "not ie <= 11",
+ "not op_mini all"
+ ]
+}
\ No newline at end of file
diff --git a/packages/docs/sandboxes/vanilla-dockview/public/index.html b/packages/docs/sandboxes/javascript/simple-dockview/public/index.html
similarity index 100%
rename from packages/docs/sandboxes/vanilla-dockview/public/index.html
rename to packages/docs/sandboxes/javascript/simple-dockview/public/index.html
diff --git a/packages/docs/sandboxes/javascript/simple-dockview/src/app.ts b/packages/docs/sandboxes/javascript/simple-dockview/src/app.ts
new file mode 100644
index 000000000..e368f3e42
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/simple-dockview/src/app.ts
@@ -0,0 +1,114 @@
+import {
+ DockviewComponent,
+ IContentRenderer,
+ IGroupPanelInitParameters,
+} from 'dockview-core';
+
+class DefaultPanel implements IContentRenderer {
+ private _element: HTMLElement;
+
+ get element(): HTMLElement {
+ return this._element;
+ }
+
+ constructor() {
+ this._element = document.createElement('div');
+ this._element.style.padding = '20px';
+ this._element.style.color = 'white';
+ }
+
+ init(params: IGroupPanelInitParameters): void {
+ this._element.textContent = params.params.title;
+ }
+}
+
+export function attach(parent: HTMLElement): {
+ dispose: () => void;
+} {
+ const element = document.createElement('div');
+ element.className = 'dockview-theme-abyss';
+ element.style.height = '100%';
+ element.style.width = '100%';
+
+ const dockview = new DockviewComponent({
+ components: {
+ default: DefaultPanel,
+ },
+ parentElement: element,
+ });
+
+ parent.appendChild(element);
+
+ const { clientWidth, clientHeight } = parent;
+ dockview.layout(clientWidth, clientHeight);
+
+ const panel = dockview.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ title: 'Panel 1',
+ },
+ });
+
+ panel.group.locked = true;
+ panel.group.header.hidden = true;
+
+ dockview.addPanel({
+ id: 'panel_2',
+ component: 'default',
+ params: {
+ title: 'Panel 2',
+ },
+ });
+
+ dockview.addPanel({
+ id: 'panel_3',
+ component: 'default',
+ params: {
+ title: 'Panel 3',
+ },
+ });
+
+ dockview.addPanel({
+ id: 'panel_4',
+ component: 'default',
+ params: {
+ title: 'Panel 4',
+ },
+ position: { referencePanel: 'panel_1', direction: 'right' },
+ });
+
+ const panel5 = dockview.addPanel({
+ id: 'panel_5',
+ component: 'default',
+ params: {
+ title: 'Panel 5',
+ },
+ position: { referencePanel: 'panel_3', direction: 'right' },
+ });
+
+ dockview.addPanel({
+ id: 'panel_6',
+ component: 'default',
+ params: {
+ title: 'Panel 6',
+ },
+ position: { referencePanel: 'panel_5', direction: 'below' },
+ });
+
+ dockview.addPanel({
+ id: 'panel_7',
+ component: 'default',
+ params: {
+ title: 'Panel 7',
+ },
+ position: { referencePanel: 'panel_6', direction: 'right' },
+ });
+
+ return {
+ dispose: () => {
+ dockview.dispose();
+ element.remove();
+ },
+ };
+}
diff --git a/packages/docs/sandboxes/vanilla-dockview/src/index.ts b/packages/docs/sandboxes/javascript/simple-dockview/src/index.tsx
similarity index 100%
rename from packages/docs/sandboxes/vanilla-dockview/src/index.ts
rename to packages/docs/sandboxes/javascript/simple-dockview/src/index.tsx
diff --git a/packages/docs/sandboxes/vanilla-dockview/src/styles.css b/packages/docs/sandboxes/javascript/simple-dockview/src/styles.css
similarity index 100%
rename from packages/docs/sandboxes/vanilla-dockview/src/styles.css
rename to packages/docs/sandboxes/javascript/simple-dockview/src/styles.css
diff --git a/packages/docs/sandboxes/vanilla-dockview/tsconfig.json b/packages/docs/sandboxes/javascript/simple-dockview/tsconfig.json
similarity index 100%
rename from packages/docs/sandboxes/vanilla-dockview/tsconfig.json
rename to packages/docs/sandboxes/javascript/simple-dockview/tsconfig.json
diff --git a/packages/docs/sandboxes/vanilla-dockview/package.json b/packages/docs/sandboxes/javascript/vanilla-dockview/package.json
similarity index 100%
rename from packages/docs/sandboxes/vanilla-dockview/package.json
rename to packages/docs/sandboxes/javascript/vanilla-dockview/package.json
diff --git a/packages/docs/sandboxes/javascript/vanilla-dockview/public/index.html b/packages/docs/sandboxes/javascript/vanilla-dockview/public/index.html
new file mode 100644
index 000000000..1f8a52426
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/vanilla-dockview/public/index.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ React App
+
+
+
+
+
+
+
+
+
diff --git a/packages/docs/sandboxes/vanilla-dockview/src/app.ts b/packages/docs/sandboxes/javascript/vanilla-dockview/src/app.ts
similarity index 100%
rename from packages/docs/sandboxes/vanilla-dockview/src/app.ts
rename to packages/docs/sandboxes/javascript/vanilla-dockview/src/app.ts
diff --git a/packages/docs/sandboxes/javascript/vanilla-dockview/src/index.ts b/packages/docs/sandboxes/javascript/vanilla-dockview/src/index.ts
new file mode 100644
index 000000000..249b56017
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/vanilla-dockview/src/index.ts
@@ -0,0 +1,10 @@
+import './styles.css';
+import 'dockview-core/dist/styles/dockview.css';
+
+import { attach } from './app';
+
+const rootElement = document.getElementById('root');
+
+if (rootElement) {
+ attach(rootElement);
+}
diff --git a/packages/docs/sandboxes/javascript/vanilla-dockview/src/styles.css b/packages/docs/sandboxes/javascript/vanilla-dockview/src/styles.css
new file mode 100644
index 000000000..92b6a1b36
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/vanilla-dockview/src/styles.css
@@ -0,0 +1,16 @@
+body {
+ margin: 0px;
+ color: white;
+ font-family: sans-serif;
+ text-align: center;
+}
+
+#root {
+ height: 100vh;
+ width: 100vw;
+}
+
+.app {
+ height: 100%;
+
+}
diff --git a/packages/docs/sandboxes/javascript/vanilla-dockview/tsconfig.json b/packages/docs/sandboxes/javascript/vanilla-dockview/tsconfig.json
new file mode 100644
index 000000000..6e13e47b5
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/vanilla-dockview/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "suppressImplicitAnyIndexErrors": true,
+ "noUnusedLocals": true
+ }
+}
diff --git a/packages/docs/sandboxes/updatetitle-dockview/src/app.tsx b/packages/docs/sandboxes/updatetitle-dockview/src/app.tsx
index 93a3b1762..8c9115df6 100644
--- a/packages/docs/sandboxes/updatetitle-dockview/src/app.tsx
+++ b/packages/docs/sandboxes/updatetitle-dockview/src/app.tsx
@@ -6,10 +6,8 @@ import {
import * as React from 'react';
const components = {
- default: (
- props: IDockviewPanelProps<{ title: string; myValue: string }>
- ) => {
- const [title, setTitle] = React.useState(props.params.title);
+ default: (props: IDockviewPanelProps<{ myValue: string }>) => {
+ const [title, setTitle] = React.useState(props.api.title);
const onChange = (event: React.ChangeEvent) => {
setTitle(event.target.value);
@@ -27,6 +25,7 @@ const components = {
+ {JSON.stringify(Object.keys(props.params))}
);
},
@@ -44,7 +43,6 @@ export const App: React.FC = () => {
id: 'panel_2',
component: 'default',
title: 'Panel 2',
-
position: { referencePanel: panel },
});
@@ -60,7 +58,6 @@ export const App: React.FC = () => {
id: 'panel_4',
component: 'default',
title: 'Panel 4',
-
position: { referencePanel: panel3 },
});
};
diff --git a/packages/docs/src/components/ui/container.scss b/packages/docs/src/components/ui/container.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/packages/docs/src/components/ui/container.tsx b/packages/docs/src/components/ui/container.tsx
index 1345315bf..5ad78067e 100644
--- a/packages/docs/src/components/ui/container.tsx
+++ b/packages/docs/src/components/ui/container.tsx
@@ -1,5 +1,8 @@
import * as React from 'react';
import { CodeSandboxButton } from './codeSandboxButton';
+import useBaseUrl from '@docusaurus/useBaseUrl';
+import './container.scss';
+import { Spinner } from './spinner';
export const Container = (props: {
children?: React.ReactNode;
@@ -41,3 +44,147 @@ export const Container = (props: {
>
);
};
+
+const ReactIcon = (props: { height: number; width: number }) => {
+ return (
+
+ );
+};
+
+const JavascriptIcon = (props: { height: number; width: number }) => {
+ return (
+
+ );
+};
+
+export const MultiFrameworkContainer = (props: {
+ react: React.FC;
+ typescript: (parent: HTMLElement) => { dispose: () => void };
+ sandboxId: string;
+ height?: number;
+}) => {
+ const ref = React.useRef(null);
+
+ const [framework, setFramework] = React.useState('React');
+
+ const [animation, setAnimation] = React.useState(false);
+
+ React.useEffect(() => {
+ setAnimation(true);
+
+ setTimeout(() => {
+ setAnimation(false);
+ }, 500);
+ }, [framework]);
+
+ React.useEffect(() => {
+ if (!ref.current) {
+ return;
+ }
+
+ if (framework === 'Javascript') {
+ const disposable = props.typescript(ref.current);
+
+ return () => {
+ disposable.dispose();
+ };
+ }
+
+ return;
+ }, [props.typescript, framework]);
+
+ const sandboxId = React.useMemo(() => {
+ if (framework === 'Javascript') {
+ return `javascript/${props.sandboxId}`;
+ }
+ return props.sandboxId;
+ }, [props.sandboxId, framework]);
+
+ return (
+ <>
+
+ {animation && (
+
+
+
+ )}
+ {framework === 'React' &&
}
+
+
+
+ {framework === 'React' ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+ >
+ );
+};
diff --git a/packages/docs/src/components/ui/referenceTable.tsx b/packages/docs/src/components/ui/referenceTable.tsx
new file mode 100644
index 000000000..1423122cc
--- /dev/null
+++ b/packages/docs/src/components/ui/referenceTable.tsx
@@ -0,0 +1,42 @@
+import * as React from 'react';
+
+export interface ReferenceProps {
+ props: {
+ prop: string;
+ default?: string;
+ type: string;
+ }[];
+}
+
+export const ReferenceTable = (props: ReferenceProps) => {
+ return (
+
+
+
+ Property |
+ Type |
+ Default |
+
+
+
+ {props.props.map((property) => {
+ return (
+
+
+ {property.prop}
+ |
+
+ {property.type}
+ |
+
+ {property.default !== undefined && (
+ {property.default}
+ )}
+ |
+
+ );
+ })}
+
+
+ );
+};
diff --git a/packages/docs/src/components/ui/spinner.scss b/packages/docs/src/components/ui/spinner.scss
new file mode 100644
index 000000000..847ee4d22
--- /dev/null
+++ b/packages/docs/src/components/ui/spinner.scss
@@ -0,0 +1,55 @@
+.lds-ellipsis {
+ display: inline-block;
+ position: relative;
+ width: 80px;
+ height: 80px;
+}
+.lds-ellipsis div {
+ position: absolute;
+ top: 33px;
+ width: 13px;
+ height: 13px;
+ border-radius: 50%;
+ background: #fff;
+ animation-timing-function: cubic-bezier(0, 1, 1, 0);
+}
+.lds-ellipsis div:nth-child(1) {
+ left: 8px;
+ animation: lds-ellipsis1 0.6s infinite;
+}
+.lds-ellipsis div:nth-child(2) {
+ left: 8px;
+ animation: lds-ellipsis2 0.6s infinite;
+}
+.lds-ellipsis div:nth-child(3) {
+ left: 32px;
+ animation: lds-ellipsis2 0.6s infinite;
+}
+.lds-ellipsis div:nth-child(4) {
+ left: 56px;
+ animation: lds-ellipsis3 0.6s infinite;
+}
+@keyframes lds-ellipsis1 {
+ 0% {
+ transform: scale(0);
+ }
+ 100% {
+ transform: scale(1);
+ }
+}
+@keyframes lds-ellipsis3 {
+ 0% {
+ transform: scale(1);
+ }
+ 100% {
+ transform: scale(0);
+ }
+}
+@keyframes lds-ellipsis2 {
+ 0% {
+ transform: translate(0, 0);
+ }
+ 100% {
+ transform: translate(24px, 0);
+ }
+}
diff --git a/packages/docs/src/components/ui/spinner.tsx b/packages/docs/src/components/ui/spinner.tsx
new file mode 100644
index 000000000..9627e3762
--- /dev/null
+++ b/packages/docs/src/components/ui/spinner.tsx
@@ -0,0 +1,13 @@
+import * as React from 'react';
+import './spinner.scss';
+
+export const Spinner = () => {
+ return (
+
+ );
+};
diff --git a/packages/docs/static/img/js-icon.svg b/packages/docs/static/img/js-icon.svg
new file mode 100644
index 000000000..9650ca78e
--- /dev/null
+++ b/packages/docs/static/img/js-icon.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/packages/docs/static/img/react-icon.svg b/packages/docs/static/img/react-icon.svg
new file mode 100644
index 000000000..ea77a618d
--- /dev/null
+++ b/packages/docs/static/img/react-icon.svg
@@ -0,0 +1,9 @@
+
diff --git a/packages/docs/versioned_docs/version-1.7.2/components/dockview.mdx b/packages/docs/versioned_docs/version-1.7.2/components/dockview.mdx
index b6d1a3e46..8097910eb 100644
--- a/packages/docs/versioned_docs/version-1.7.2/components/dockview.mdx
+++ b/packages/docs/versioned_docs/version-1.7.2/components/dockview.mdx
@@ -24,7 +24,7 @@ import RenderingDockview from '@site/sandboxes/rendering-dockview/src/app';
import DockviewExternalDnd from '@site/sandboxes/externaldnd-dockview/src/app';
import DockviewResizeContainer from '@site/sandboxes/resizecontainer-dockview/src/app';
import DockviewTabheight from '@site/sandboxes/tabheight-dockview/src/app';
-import { attach as attachDockviewVanilla } from '@site/sandboxes/vanilla-dockview/src/app';
+import { attach as attachDockviewVanilla } from '@site/sandboxes/javascript/vanilla-dockview/src/app';
# Dockview
@@ -728,6 +728,6 @@ The core library is published as an independant package under the name `dockview
> `dockview-core` is a dependency of `dockview` and automatically installed during the installation process of `dockview` via `npm install dockview`.
From 32746e248d81efb40106e9e9de9a35b8465831f7 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Mon, 22 May 2023 21:37:50 +0100
Subject: [PATCH 03/23] chore: docs (plain ts examples)
---
.codesandbox/ci.json | 7 +-
.gitignore | 2 +-
packages/docs/docs/components/dockview.mdx | 18 +-
.../constraints-dockview/tsconfig.json | 35 ++--
.../customheader-dockview/tsconfig.json | 35 ++--
.../sandboxes/demo-dockview/tsconfig.json | 35 ++--
.../docs/sandboxes/dnd-dockview/tsconfig.json | 35 ++--
.../docs/sandboxes/dockview-app/tsconfig.json | 35 ++--
.../sandboxes/events-dockview/tsconfig.json | 35 ++--
.../externaldnd-dockview/tsconfig.json | 35 ++--
.../fullwidthtab-dockview/tsconfig.json | 35 ++--
.../groupcontrol-dockview/tsconfig.json | 35 ++--
.../fullwidthtab-dockview/package.json | 27 +++
.../fullwidthtab-dockview/public/index.html | 44 +++++
.../fullwidthtab-dockview/src/app.scss | 17 ++
.../fullwidthtab-dockview/src/app.ts | 171 ++++++++++++++++++
.../src/index.ts} | 0
.../fullwidthtab-dockview/src/styles.css | 16 ++
.../fullwidthtab-dockview/tsconfig.json | 19 ++
.../javascript/simple-dockview/src/app.ts | 6 +
.../javascript/simple-dockview/src/index.ts | 10 +
.../javascript/simple-dockview/tsconfig.json | 35 ++--
.../tabheight-dockview/package.json | 27 +++
.../tabheight-dockview/public/index.html | 44 +++++
.../tabheight-dockview/src/app.scss | 3 +
.../javascript/tabheight-dockview/src/app.ts | 110 +++++++++++
.../tabheight-dockview/src/index.ts | 10 +
.../tabheight-dockview/src/styles.css | 16 ++
.../tabheight-dockview/tsconfig.json | 19 ++
.../javascript/vanilla-dockview/tsconfig.json | 1 -
.../sandboxes/layout-dockview/tsconfig.json | 35 ++--
.../nativeapp-dockview/tsconfig.json | 35 ++--
.../sandboxes/nested-dockview/tsconfig.json | 35 ++--
.../rendering-dockview/tsconfig.json | 35 ++--
.../sandboxes/resize-dockview/tsconfig.json | 35 ++--
.../resizecontainer-dockview/tsconfig.json | 35 ++--
.../sandboxes/simple-dockview/tsconfig.json | 35 ++--
.../tabheight-dockview/tsconfig.json | 35 ++--
.../updatetitle-dockview/tsconfig.json | 35 ++--
.../watermark-dockview/tsconfig.json | 35 ++--
40 files changed, 897 insertions(+), 370 deletions(-)
create mode 100644 packages/docs/sandboxes/javascript/fullwidthtab-dockview/package.json
create mode 100644 packages/docs/sandboxes/javascript/fullwidthtab-dockview/public/index.html
create mode 100644 packages/docs/sandboxes/javascript/fullwidthtab-dockview/src/app.scss
create mode 100644 packages/docs/sandboxes/javascript/fullwidthtab-dockview/src/app.ts
rename packages/docs/sandboxes/javascript/{simple-dockview/src/index.tsx => fullwidthtab-dockview/src/index.ts} (100%)
create mode 100644 packages/docs/sandboxes/javascript/fullwidthtab-dockview/src/styles.css
create mode 100644 packages/docs/sandboxes/javascript/fullwidthtab-dockview/tsconfig.json
create mode 100644 packages/docs/sandboxes/javascript/simple-dockview/src/index.ts
create mode 100644 packages/docs/sandboxes/javascript/tabheight-dockview/package.json
create mode 100644 packages/docs/sandboxes/javascript/tabheight-dockview/public/index.html
create mode 100644 packages/docs/sandboxes/javascript/tabheight-dockview/src/app.scss
create mode 100644 packages/docs/sandboxes/javascript/tabheight-dockview/src/app.ts
create mode 100644 packages/docs/sandboxes/javascript/tabheight-dockview/src/index.ts
create mode 100644 packages/docs/sandboxes/javascript/tabheight-dockview/src/styles.css
create mode 100644 packages/docs/sandboxes/javascript/tabheight-dockview/tsconfig.json
diff --git a/.codesandbox/ci.json b/.codesandbox/ci.json
index be48bfccc..a6a13434a 100644
--- a/.codesandbox/ci.json
+++ b/.codesandbox/ci.json
@@ -22,8 +22,11 @@
"/packages/docs/sandboxes/simple-dockview",
"/packages/docs/sandboxes/tabheight-dockview",
"/packages/docs/sandboxes/updatetitle-dockview",
- "/packages/docs/sandboxes/typescript/vanilla-dockview",
- "/packages/docs/sandboxes/watermark-dockview"
+ "/packages/docs/sandboxes/watermark-dockview",
+ "/packages/docs/sandboxes/typescript/fullwidthtab-dockview",
+ "/packages/docs/sandboxes/typescript/simple-dockview",
+ "/packages/docs/sandboxes/typescript/tabheight-dockview",
+ "/packages/docs/sandboxes/typescript/vanilla-dockview"
],
"node": "16"
}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index a38d78f1f..e3f290550 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,4 +13,4 @@ test-report.xml
*.code-workspace
yarn-error.log
/build
-docs/
+/docs/
diff --git a/packages/docs/docs/components/dockview.mdx b/packages/docs/docs/components/dockview.mdx
index d32c08a9b..835dee189 100644
--- a/packages/docs/docs/components/dockview.mdx
+++ b/packages/docs/docs/components/dockview.mdx
@@ -30,6 +30,8 @@ import DockviewTabheight from '@site/sandboxes/tabheight-dockview/src/app';
import { attach as attachDockviewVanilla } from '@site/sandboxes/javascript/vanilla-dockview/src/app';
import { attach as attachSimpleDockview } from '@site/sandboxes/javascript/simple-dockview/src/app';
+import { attach as attachTabHeightDockview } from '@site/sandboxes/javascript/tabheight-dockview/src/app';
+import { attach as attachNativeDockview } from '@site/sandboxes/javascript/fullwidthtab-dockview/src/app';
# Dockview
@@ -617,17 +619,21 @@ to the entire width of the group. For example:
```
-
-
-
+
### Tab Height
Tab height can be controlled through CSS.
-
-
-
+
## Groups
diff --git a/packages/docs/sandboxes/constraints-dockview/tsconfig.json b/packages/docs/sandboxes/constraints-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/constraints-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/constraints-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/customheader-dockview/tsconfig.json b/packages/docs/sandboxes/customheader-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/customheader-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/customheader-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/demo-dockview/tsconfig.json b/packages/docs/sandboxes/demo-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/demo-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/demo-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/dnd-dockview/tsconfig.json b/packages/docs/sandboxes/dnd-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/dnd-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/dnd-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/dockview-app/tsconfig.json b/packages/docs/sandboxes/dockview-app/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/dockview-app/tsconfig.json
+++ b/packages/docs/sandboxes/dockview-app/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/events-dockview/tsconfig.json b/packages/docs/sandboxes/events-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/events-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/events-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/externaldnd-dockview/tsconfig.json b/packages/docs/sandboxes/externaldnd-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/externaldnd-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/externaldnd-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/fullwidthtab-dockview/tsconfig.json b/packages/docs/sandboxes/fullwidthtab-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/fullwidthtab-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/fullwidthtab-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/groupcontrol-dockview/tsconfig.json b/packages/docs/sandboxes/groupcontrol-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/groupcontrol-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/groupcontrol-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/javascript/fullwidthtab-dockview/package.json b/packages/docs/sandboxes/javascript/fullwidthtab-dockview/package.json
new file mode 100644
index 000000000..c4d975c1a
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/fullwidthtab-dockview/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "javascript-fullwidthtab-dockview",
+ "description": "",
+ "keywords": [
+ "dockview"
+ ],
+ "version": "1.0.0",
+ "main": "src/index.ts",
+ "dependencies": {
+ "dockview-core": "*"
+ },
+ "devDependencies": {
+ "typescript": "^4.9.5"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test --env=jsdom",
+ "eject": "react-scripts eject"
+ },
+ "browserslist": [
+ ">0.2%",
+ "not dead",
+ "not ie <= 11",
+ "not op_mini all"
+ ]
+}
\ No newline at end of file
diff --git a/packages/docs/sandboxes/javascript/fullwidthtab-dockview/public/index.html b/packages/docs/sandboxes/javascript/fullwidthtab-dockview/public/index.html
new file mode 100644
index 000000000..1f8a52426
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/fullwidthtab-dockview/public/index.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ React App
+
+
+
+
+
+
+
+
+
diff --git a/packages/docs/sandboxes/javascript/fullwidthtab-dockview/src/app.scss b/packages/docs/sandboxes/javascript/fullwidthtab-dockview/src/app.scss
new file mode 100644
index 000000000..1b1438ec2
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/fullwidthtab-dockview/src/app.scss
@@ -0,0 +1,17 @@
+.my-custom-tab {
+ padding: 0px 8px;
+ width: 100%;
+ display: flex;
+ height: 100%;
+ align-items: center;
+ background-color: var(--dv-tabs-and-actions-container-background-color);
+
+ .my-custom-tab-icon {
+ font-size: 16px;
+
+ &:hover {
+ border-radius: 2px;
+ background-color: var(--dv-icon-hover-background-color);
+ }
+ }
+}
diff --git a/packages/docs/sandboxes/javascript/fullwidthtab-dockview/src/app.ts b/packages/docs/sandboxes/javascript/fullwidthtab-dockview/src/app.ts
new file mode 100644
index 000000000..40eba745d
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/fullwidthtab-dockview/src/app.ts
@@ -0,0 +1,171 @@
+import {
+ IGroupPanelInitParameters,
+ IContentRenderer,
+ PanelUpdateEvent,
+ Parameters,
+ ITabRenderer,
+ DockviewComponent,
+} from 'dockview-core';
+import './app.scss';
+
+class DefaultPanel implements IContentRenderer {
+ private _element: HTMLElement;
+ private _titleElement: HTMLElement;
+ private _paramsElement: HTMLElement;
+
+ get element(): HTMLElement {
+ return this._element;
+ }
+
+ constructor() {
+ this._element = document.createElement('div');
+ this._element.style.display = 'flex';
+ this._element.style.justifyContent = 'center';
+ this._element.style.alignItems = 'center';
+ this._element.style.color = 'white';
+ this._element.style.height = '100%';
+
+ this._titleElement = document.createElement('span');
+ this._paramsElement = document.createElement('span');
+
+ this._element.appendChild(this._titleElement);
+ }
+
+ init(params: IGroupPanelInitParameters): void {
+ this.render(params.params);
+ }
+
+ update(event: PanelUpdateEvent): void {
+ this.render(event.params);
+ }
+
+ private render(params: Record) {
+ this._titleElement.textContent = params.title;
+
+ if (params.x) {
+ if (!this._paramsElement.parentElement) {
+ this._element.appendChild(this._paramsElement);
+ }
+ this._paramsElement.textContent = params.x;
+ } else {
+ this._paramsElement.parentElement?.removeChild(this._paramsElement);
+ }
+ }
+}
+
+class DefaultTab implements ITabRenderer {
+ private _element: HTMLElement;
+ private _title: HTMLElement;
+
+ get element(): HTMLElement {
+ return this._element;
+ }
+
+ constructor() {
+ this._element = document.createElement('div');
+ this._element.className = 'my-custom-tab';
+
+ this._title = document.createElement('span');
+
+ const spacer = document.createElement('span');
+ spacer.style.flexGrow = '1';
+
+ const btn1 = document.createElement('span');
+ btn1.className = 'my-custom-tab-icon material-symbols-outlined';
+ btn1.textContent = 'minimize';
+
+ const btn2 = document.createElement('span');
+ btn2.className = 'my-custom-tab-icon material-symbols-outlined';
+ btn2.textContent = 'maximize';
+
+ const btn3 = document.createElement('span');
+ btn3.className = 'my-custom-tab-icon material-symbols-outlined';
+ btn3.textContent = 'close';
+
+ this._element.appendChild(this._title);
+ this._element.appendChild(spacer);
+ this._element.appendChild(btn1);
+ this._element.appendChild(btn2);
+ this._element.appendChild(btn3);
+ }
+
+ init(params: IGroupPanelInitParameters): void {
+ this.render(params.params);
+ }
+
+ update(event: PanelUpdateEvent): void {
+ this.render(event.params);
+ }
+
+ private render(params: Record) {
+ this._title = params.title;
+ }
+}
+
+export function attach(parent: HTMLElement): {
+ dispose: () => void;
+} {
+ const element = document.createElement('div');
+ element.className = 'dockview-theme-abyss';
+ element.style.height = '100%';
+ element.style.width = '100%';
+
+ const dockview = new DockviewComponent({
+ components: {
+ default: DefaultPanel,
+ },
+ tabComponents: {
+ default: DefaultTab,
+ },
+ singleTabMode: 'fullwidth',
+ parentElement: element,
+ });
+
+ parent.appendChild(element);
+
+ const { clientWidth, clientHeight } = parent;
+ dockview.layout(clientWidth, clientHeight);
+
+ const panel1 = dockview.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ tabComponent: 'default',
+ params: {
+ title: 'Window 1',
+ },
+ });
+ panel1.group.locked = true;
+
+ const panel2 = dockview.addPanel({
+ id: 'panel_2',
+ component: 'default',
+ tabComponent: 'default',
+ params: {
+ title: 'Window 2',
+ },
+ position: {
+ direction: 'right',
+ },
+ });
+ panel2.group.locked = true;
+
+ const panel3 = dockview.addPanel({
+ id: 'panel_3',
+ component: 'default',
+ tabComponent: 'default',
+ params: {
+ title: 'Window 3',
+ },
+ position: {
+ direction: 'below',
+ },
+ });
+ panel3.group.locked = true;
+
+ return {
+ dispose: () => {
+ dockview.dispose();
+ element.remove();
+ },
+ };
+}
diff --git a/packages/docs/sandboxes/javascript/simple-dockview/src/index.tsx b/packages/docs/sandboxes/javascript/fullwidthtab-dockview/src/index.ts
similarity index 100%
rename from packages/docs/sandboxes/javascript/simple-dockview/src/index.tsx
rename to packages/docs/sandboxes/javascript/fullwidthtab-dockview/src/index.ts
diff --git a/packages/docs/sandboxes/javascript/fullwidthtab-dockview/src/styles.css b/packages/docs/sandboxes/javascript/fullwidthtab-dockview/src/styles.css
new file mode 100644
index 000000000..92b6a1b36
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/fullwidthtab-dockview/src/styles.css
@@ -0,0 +1,16 @@
+body {
+ margin: 0px;
+ color: white;
+ font-family: sans-serif;
+ text-align: center;
+}
+
+#root {
+ height: 100vh;
+ width: 100vw;
+}
+
+.app {
+ height: 100%;
+
+}
diff --git a/packages/docs/sandboxes/javascript/fullwidthtab-dockview/tsconfig.json b/packages/docs/sandboxes/javascript/fullwidthtab-dockview/tsconfig.json
new file mode 100644
index 000000000..8aebe3efe
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/fullwidthtab-dockview/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
+}
diff --git a/packages/docs/sandboxes/javascript/simple-dockview/src/app.ts b/packages/docs/sandboxes/javascript/simple-dockview/src/app.ts
index e368f3e42..ecce95e0e 100644
--- a/packages/docs/sandboxes/javascript/simple-dockview/src/app.ts
+++ b/packages/docs/sandboxes/javascript/simple-dockview/src/app.ts
@@ -2,6 +2,8 @@ import {
DockviewComponent,
IContentRenderer,
IGroupPanelInitParameters,
+ PanelUpdateEvent,
+ Parameters,
} from 'dockview-core';
class DefaultPanel implements IContentRenderer {
@@ -20,6 +22,10 @@ class DefaultPanel implements IContentRenderer {
init(params: IGroupPanelInitParameters): void {
this._element.textContent = params.params.title;
}
+
+ update(event: PanelUpdateEvent): void {
+ this._element.textContent = event.params.title;
+ }
}
export function attach(parent: HTMLElement): {
diff --git a/packages/docs/sandboxes/javascript/simple-dockview/src/index.ts b/packages/docs/sandboxes/javascript/simple-dockview/src/index.ts
new file mode 100644
index 000000000..249b56017
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/simple-dockview/src/index.ts
@@ -0,0 +1,10 @@
+import './styles.css';
+import 'dockview-core/dist/styles/dockview.css';
+
+import { attach } from './app';
+
+const rootElement = document.getElementById('root');
+
+if (rootElement) {
+ attach(rootElement);
+}
diff --git a/packages/docs/sandboxes/javascript/simple-dockview/tsconfig.json b/packages/docs/sandboxes/javascript/simple-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/javascript/simple-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/javascript/simple-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/javascript/tabheight-dockview/package.json b/packages/docs/sandboxes/javascript/tabheight-dockview/package.json
new file mode 100644
index 000000000..5aeba5d4d
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/tabheight-dockview/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "javascript-tabheight-dockview",
+ "description": "",
+ "keywords": [
+ "dockview"
+ ],
+ "version": "1.0.0",
+ "main": "src/index.ts",
+ "dependencies": {
+ "dockview-core": "*"
+ },
+ "devDependencies": {
+ "typescript": "^4.9.5"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test --env=jsdom",
+ "eject": "react-scripts eject"
+ },
+ "browserslist": [
+ ">0.2%",
+ "not dead",
+ "not ie <= 11",
+ "not op_mini all"
+ ]
+}
\ No newline at end of file
diff --git a/packages/docs/sandboxes/javascript/tabheight-dockview/public/index.html b/packages/docs/sandboxes/javascript/tabheight-dockview/public/index.html
new file mode 100644
index 000000000..1f8a52426
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/tabheight-dockview/public/index.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ React App
+
+
+
+
+
+
+
+
+
diff --git a/packages/docs/sandboxes/javascript/tabheight-dockview/src/app.scss b/packages/docs/sandboxes/javascript/tabheight-dockview/src/app.scss
new file mode 100644
index 000000000..315d564ac
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/tabheight-dockview/src/app.scss
@@ -0,0 +1,3 @@
+.skinny-tabs {
+ --dv-tabs-and-actions-container-height: 20px;
+}
diff --git a/packages/docs/sandboxes/javascript/tabheight-dockview/src/app.ts b/packages/docs/sandboxes/javascript/tabheight-dockview/src/app.ts
new file mode 100644
index 000000000..ca3535611
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/tabheight-dockview/src/app.ts
@@ -0,0 +1,110 @@
+import {
+ DockviewComponent,
+ IContentRenderer,
+ IGroupPanelInitParameters,
+ PanelUpdateEvent,
+ Parameters,
+} from 'dockview-core';
+import './app.scss';
+
+class DefaultPanel implements IContentRenderer {
+ private _element: HTMLElement;
+
+ get element(): HTMLElement {
+ return this._element;
+ }
+
+ constructor() {
+ this._element = document.createElement('div');
+ this._element.style.padding = '20px';
+ this._element.style.color = 'white';
+ }
+
+ init(params: IGroupPanelInitParameters): void {
+ this._element.textContent = params.params.title;
+ }
+
+ update(event: PanelUpdateEvent): void {
+ this._element.textContent = event.params.title;
+ }
+}
+
+export function attach(parent: HTMLElement): {
+ dispose: () => void;
+} {
+ const element = document.createElement('div');
+ element.className = 'dockview-theme-abyss skinny-tabs';
+ element.style.height = '100%';
+ element.style.width = '100%';
+
+ const dockview = new DockviewComponent({
+ components: {
+ default: DefaultPanel,
+ },
+ parentElement: element,
+ });
+
+ parent.appendChild(element);
+
+ const { clientWidth, clientHeight } = parent;
+ dockview.layout(clientWidth, clientHeight);
+
+ dockview.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ title: 'Panel 1',
+ },
+ });
+
+ dockview.addPanel({
+ id: 'panel_2',
+ component: 'default',
+ params: {
+ title: 'Panel 2',
+ },
+ });
+
+ dockview.addPanel({
+ id: 'panel_3',
+ component: 'default',
+ params: {
+ title: 'Panel 3',
+ },
+ position: { referencePanel: 'panel_1', direction: 'right' },
+ });
+
+ dockview.addPanel({
+ id: 'panel_4',
+ component: 'default',
+ params: {
+ title: 'Panel 4',
+ },
+ position: { referencePanel: 'panel_3', direction: 'right' },
+ });
+
+ dockview.addPanel({
+ id: 'panel_5',
+ component: 'default',
+ params: {
+ title: 'Panel 5',
+ },
+ position: { referencePanel: 'panel_4', direction: 'below' },
+ });
+
+ dockview.addPanel({
+ id: 'panel_6',
+ component: 'default',
+ params: {
+ title: 'Panel 6',
+ },
+ position: { referencePanel: 'panel_5', direction: 'right' },
+ });
+
+ return {
+ dispose: () => {
+ dockview.dispose();
+ element.remove();
+ },
+ };
+}
diff --git a/packages/docs/sandboxes/javascript/tabheight-dockview/src/index.ts b/packages/docs/sandboxes/javascript/tabheight-dockview/src/index.ts
new file mode 100644
index 000000000..249b56017
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/tabheight-dockview/src/index.ts
@@ -0,0 +1,10 @@
+import './styles.css';
+import 'dockview-core/dist/styles/dockview.css';
+
+import { attach } from './app';
+
+const rootElement = document.getElementById('root');
+
+if (rootElement) {
+ attach(rootElement);
+}
diff --git a/packages/docs/sandboxes/javascript/tabheight-dockview/src/styles.css b/packages/docs/sandboxes/javascript/tabheight-dockview/src/styles.css
new file mode 100644
index 000000000..a1d49a9b6
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/tabheight-dockview/src/styles.css
@@ -0,0 +1,16 @@
+body {
+ margin: 0px;
+ color: white;
+ font-family: sans-serif;
+ text-align: center;
+}
+
+#root {
+ height: 100vh;
+ width: 100vw;
+}
+
+.app {
+ height: 100%;
+}
+
diff --git a/packages/docs/sandboxes/javascript/tabheight-dockview/tsconfig.json b/packages/docs/sandboxes/javascript/tabheight-dockview/tsconfig.json
new file mode 100644
index 000000000..8aebe3efe
--- /dev/null
+++ b/packages/docs/sandboxes/javascript/tabheight-dockview/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
+}
diff --git a/packages/docs/sandboxes/javascript/vanilla-dockview/tsconfig.json b/packages/docs/sandboxes/javascript/vanilla-dockview/tsconfig.json
index 6e13e47b5..728865f76 100644
--- a/packages/docs/sandboxes/javascript/vanilla-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/javascript/vanilla-dockview/tsconfig.json
@@ -14,7 +14,6 @@
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true
}
}
diff --git a/packages/docs/sandboxes/layout-dockview/tsconfig.json b/packages/docs/sandboxes/layout-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/layout-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/layout-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/nativeapp-dockview/tsconfig.json b/packages/docs/sandboxes/nativeapp-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/nativeapp-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/nativeapp-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/nested-dockview/tsconfig.json b/packages/docs/sandboxes/nested-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/nested-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/nested-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/rendering-dockview/tsconfig.json b/packages/docs/sandboxes/rendering-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/rendering-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/rendering-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/resize-dockview/tsconfig.json b/packages/docs/sandboxes/resize-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/resize-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/resize-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/resizecontainer-dockview/tsconfig.json b/packages/docs/sandboxes/resizecontainer-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/resizecontainer-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/resizecontainer-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/simple-dockview/tsconfig.json b/packages/docs/sandboxes/simple-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/simple-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/simple-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/tabheight-dockview/tsconfig.json b/packages/docs/sandboxes/tabheight-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/tabheight-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/tabheight-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/updatetitle-dockview/tsconfig.json b/packages/docs/sandboxes/updatetitle-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/updatetitle-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/updatetitle-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
diff --git a/packages/docs/sandboxes/watermark-dockview/tsconfig.json b/packages/docs/sandboxes/watermark-dockview/tsconfig.json
index 6e13e47b5..8aebe3efe 100644
--- a/packages/docs/sandboxes/watermark-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/watermark-dockview/tsconfig.json
@@ -1,20 +1,19 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "suppressImplicitAnyIndexErrors": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "noUnusedLocals": true
+ }
}
From 1cf23f04baf54b46c835b13932a7d7dbf4b1ff58 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Wed, 31 May 2023 19:32:14 +0100
Subject: [PATCH 04/23] bug: fix conflicts between panel.title and
panel.params.title (user provided title)
---
.../dockview/dockviewComponent.spec.ts | 87 +++++++++++++++++++
.../__tests__/dockview/dockviewPanel.spec.ts | 2 +-
.../dockview-core/src/api/dockviewPanelApi.ts | 4 +-
.../src/dockview/dockviewPanel.ts | 19 ++--
4 files changed, 99 insertions(+), 13 deletions(-)
diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts
index 253cd4f1e..173bd788e 100644
--- a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts
+++ b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts
@@ -2295,4 +2295,91 @@ describe('dockviewComponent', () => {
panels: {},
});
});
+
+ test('that title and params.title do not conflict', () => {
+ const container = document.createElement('div');
+
+ const dockview = new DockviewComponent({
+ parentElement: container,
+ components: {
+ default: PanelContentPartTest,
+ },
+ tabComponents: {
+ test_tab_id: PanelTabPartTest,
+ },
+ orientation: Orientation.HORIZONTAL,
+ });
+
+ dockview.layout(100, 100);
+
+ dockview.addPanel({
+ id: 'panel1',
+ component: 'default',
+ title: 'Panel 1',
+ params: {
+ title: 'Panel 1',
+ },
+ });
+
+ dockview.addPanel({
+ id: 'panel2',
+ component: 'default',
+ title: 'Panel 2',
+ });
+
+ dockview.addPanel({
+ id: 'panel3',
+ component: 'default',
+ params: {
+ title: 'Panel 3',
+ },
+ });
+
+ expect(JSON.parse(JSON.stringify(dockview.toJSON()))).toEqual({
+ grid: {
+ root: {
+ type: 'branch',
+ data: [
+ {
+ type: 'leaf',
+ data: {
+ views: ['panel1', 'panel2', 'panel3'],
+ activeView: 'panel3',
+ id: '1',
+ },
+ size: 100,
+ },
+ ],
+ size: 100,
+ },
+ width: 100,
+ height: 100,
+ orientation: 'HORIZONTAL',
+ },
+ panels: {
+ panel1: {
+ id: 'panel1',
+ contentComponent: 'default',
+ params: {
+ title: 'Panel 1',
+ },
+ title: 'Panel 1',
+ },
+ panel2: {
+ id: 'panel2',
+ contentComponent: 'default',
+ title: 'Panel 2',
+ },
+ panel3: {
+ id: 'panel3',
+ contentComponent: 'default',
+ params: {
+ title: 'Panel 3',
+ },
+ title: 'panel3',
+ },
+ },
+ activeGroup: '1',
+ });
+ });
});
diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewPanel.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewPanel.spec.ts
index e6d7ab10e..d87ac438b 100644
--- a/packages/dockview-core/src/__tests__/dockview/dockviewPanel.spec.ts
+++ b/packages/dockview-core/src/__tests__/dockview/dockviewPanel.spec.ts
@@ -37,7 +37,7 @@ describe('dockviewPanel', () => {
latestTitle = event.title;
});
- expect(cut.title).toBe('');
+ expect(cut.title).toBeUndefined();
cut.init({ title: 'new title', params: {} });
expect(latestTitle).toBe('new title');
diff --git a/packages/dockview-core/src/api/dockviewPanelApi.ts b/packages/dockview-core/src/api/dockviewPanelApi.ts
index 48978c688..d42ac65a4 100644
--- a/packages/dockview-core/src/api/dockviewPanelApi.ts
+++ b/packages/dockview-core/src/api/dockviewPanelApi.ts
@@ -19,7 +19,7 @@ export interface DockviewPanelApi
> {
readonly group: DockviewGroupPanel;
readonly isGroupActive: boolean;
- readonly title: string;
+ readonly title: string | undefined;
readonly onDidActiveGroupChange: Event;
readonly onDidGroupChange: Event;
close(): void;
@@ -43,7 +43,7 @@ export class DockviewPanelApiImpl
private readonly disposable = new MutableDisposable();
- get title(): string {
+ get title(): string | undefined {
return this.panel.title;
}
diff --git a/packages/dockview-core/src/dockview/dockviewPanel.ts b/packages/dockview-core/src/dockview/dockviewPanel.ts
index 66ac5be5f..cc34b1545 100644
--- a/packages/dockview-core/src/dockview/dockviewPanel.ts
+++ b/packages/dockview-core/src/dockview/dockviewPanel.ts
@@ -18,7 +18,7 @@ export interface IDockviewPanel extends IDisposable, IPanel {
readonly view: IDockviewPanelModel;
readonly group: DockviewGroupPanel;
readonly api: DockviewPanelApi;
- readonly title: string;
+ readonly title: string | undefined;
readonly params: Record | undefined;
updateParentGroup(group: DockviewGroupPanel, isGroupActive: boolean): void;
init(params: IGroupPanelInitParameters): void;
@@ -34,13 +34,13 @@ export class DockviewPanel
private _group: DockviewGroupPanel;
private _params?: Parameters;
- private _title: string;
+ private _title: string | undefined;
get params(): Parameters | undefined {
return this._params;
}
- get title(): string {
+ get title(): string | undefined {
return this._title;
}
@@ -56,7 +56,6 @@ export class DockviewPanel
readonly view: IDockviewPanelModel
) {
super();
- this._title = '';
this._group = group;
this.api = new DockviewPanelApiImpl(this, this._group);
@@ -76,13 +75,13 @@ export class DockviewPanel
public init(params: IGroupPanelInitParameters): void {
this._params = params.params;
- this.setTitle(params.title);
-
this.view.init({
...params,
api: this.api,
containerApi: this.containerApi,
});
+
+ this.setTitle(params.title);
}
focus(): void {
@@ -103,12 +102,12 @@ export class DockviewPanel
}
setTitle(title: string): void {
- const didTitleChange = title !== this._params?.title;
+ const didTitleChange = title !== this.title;
if (didTitleChange) {
this._title = title;
- this.view?.update({
+ this.view.update({
params: {
params: this._params,
title: this.title,
@@ -128,10 +127,10 @@ export class DockviewPanel
if (params.title !== this.title) {
this._title = params.title;
- this.api._onDidTitleChange.fire({ title: this.title });
+ this.api._onDidTitleChange.fire({ title: params.title });
}
- this.view?.update({
+ this.view.update({
params: {
params: this._params,
title: this.title,
From b49e2e5d10256b6cca869b171a4db4842494007d Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Sat, 3 Jun 2023 20:26:45 +0100
Subject: [PATCH 05/23] chore: generate docs for v1.7.3
---
.../docs/blog/2023-06-03-dockview-1.7.3.md | 17 ++++++
.../basics.mdx | 1 -
.../components/_category_.json | 0
.../components/dockview.mdx | 59 +++++++++++--------
.../components/gridview.mdx | 0
.../components/paneview.mdx | 0
.../components/splitview.mdx | 0
.../index.mdx | 0
.../theme.mdx | 0
...ebars.json => version-1.7.3-sidebars.json} | 0
packages/docs/versions.json | 4 +-
11 files changed, 54 insertions(+), 27 deletions(-)
create mode 100644 packages/docs/blog/2023-06-03-dockview-1.7.3.md
rename packages/docs/versioned_docs/{version-1.7.2 => version-1.7.3}/basics.mdx (99%)
rename packages/docs/versioned_docs/{version-1.7.2 => version-1.7.3}/components/_category_.json (100%)
rename packages/docs/versioned_docs/{version-1.7.2 => version-1.7.3}/components/dockview.mdx (95%)
rename packages/docs/versioned_docs/{version-1.7.2 => version-1.7.3}/components/gridview.mdx (100%)
rename packages/docs/versioned_docs/{version-1.7.2 => version-1.7.3}/components/paneview.mdx (100%)
rename packages/docs/versioned_docs/{version-1.7.2 => version-1.7.3}/components/splitview.mdx (100%)
rename packages/docs/versioned_docs/{version-1.7.2 => version-1.7.3}/index.mdx (100%)
rename packages/docs/versioned_docs/{version-1.7.2 => version-1.7.3}/theme.mdx (100%)
rename packages/docs/versioned_sidebars/{version-1.7.2-sidebars.json => version-1.7.3-sidebars.json} (100%)
diff --git a/packages/docs/blog/2023-06-03-dockview-1.7.3.md b/packages/docs/blog/2023-06-03-dockview-1.7.3.md
new file mode 100644
index 000000000..7a4e6cba8
--- /dev/null
+++ b/packages/docs/blog/2023-06-03-dockview-1.7.3.md
@@ -0,0 +1,17 @@
+---
+slug: dockview-1.7.3-release
+title: Dockview 1.7.3
+tags: [release]
+---
+
+# Release Notes
+
+Please reference to docs @ [dockview.dev](https://dockview.dev).
+
+## 🚀 Features
+
+## 🛠Miscs
+
+- Fix bug custom params named 'title' conflicting with built-in tab 'title' object [#258](https://github.com/mathuo/dockview/issues/258)
+
+## 🔥 Breaking changes
diff --git a/packages/docs/versioned_docs/version-1.7.2/basics.mdx b/packages/docs/versioned_docs/version-1.7.3/basics.mdx
similarity index 99%
rename from packages/docs/versioned_docs/version-1.7.2/basics.mdx
rename to packages/docs/versioned_docs/version-1.7.3/basics.mdx
index 33d0270c0..b2c8ebcdb 100644
--- a/packages/docs/versioned_docs/version-1.7.2/basics.mdx
+++ b/packages/docs/versioned_docs/version-1.7.3/basics.mdx
@@ -8,7 +8,6 @@ import { SimpleSplitview2 } from '@site/src/components/simpleSplitview2';
# Basics
-asd
This section will take you through a number of concepts that can be applied to all dockview components.
## Panels
diff --git a/packages/docs/versioned_docs/version-1.7.2/components/_category_.json b/packages/docs/versioned_docs/version-1.7.3/components/_category_.json
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.2/components/_category_.json
rename to packages/docs/versioned_docs/version-1.7.3/components/_category_.json
diff --git a/packages/docs/versioned_docs/version-1.7.2/components/dockview.mdx b/packages/docs/versioned_docs/version-1.7.3/components/dockview.mdx
similarity index 95%
rename from packages/docs/versioned_docs/version-1.7.2/components/dockview.mdx
rename to packages/docs/versioned_docs/version-1.7.3/components/dockview.mdx
index 8097910eb..835dee189 100644
--- a/packages/docs/versioned_docs/version-1.7.2/components/dockview.mdx
+++ b/packages/docs/versioned_docs/version-1.7.3/components/dockview.mdx
@@ -2,7 +2,10 @@
description: Dockview Documentation
---
-import { Container } from '@site/src/components/ui/container';
+import {
+ Container,
+ MultiFrameworkContainer,
+} from '@site/src/components/ui/container';
import Link from '@docusaurus/Link';
import useBaseUrl from '@docusaurus/useBaseUrl';
@@ -24,7 +27,11 @@ import RenderingDockview from '@site/sandboxes/rendering-dockview/src/app';
import DockviewExternalDnd from '@site/sandboxes/externaldnd-dockview/src/app';
import DockviewResizeContainer from '@site/sandboxes/resizecontainer-dockview/src/app';
import DockviewTabheight from '@site/sandboxes/tabheight-dockview/src/app';
+
import { attach as attachDockviewVanilla } from '@site/sandboxes/javascript/vanilla-dockview/src/app';
+import { attach as attachSimpleDockview } from '@site/sandboxes/javascript/simple-dockview/src/app';
+import { attach as attachTabHeightDockview } from '@site/sandboxes/javascript/tabheight-dockview/src/app';
+import { attach as attachNativeDockview } from '@site/sandboxes/javascript/fullwidthtab-dockview/src/app';
# Dockview
@@ -32,12 +39,16 @@ import { attach as attachDockviewVanilla } from '@site/sandboxes/javascript/vani
Dockview is an abstraction built on top of [Gridviews](./gridview) where each view is a container of many tabbed panels.
-
-
-
+
-You can access the panels associated group through the `panel.group` variable.
-The group will always be defined and will change if a panel is moved into another group.
+
+
+> You can access the panels associated group through the `panel.group` variable.
+> The group will always be defined and will change if a panel is moved into another group.
## DockviewReact Component
@@ -340,7 +351,9 @@ return (
### Third Party Dnd Libraries
-To be completed...
+This shows a simple example of a third-party library used inside a panel that relies on drag
+and drop functionalities. This examples serves to show that `dockview` doesn't interfer with
+any drag and drop logic for other controls.
@@ -606,15 +619,21 @@ to the entire width of the group. For example:
```
-
-
-
+
### Tab Height
-
-
-
+Tab height can be controlled through CSS.
+
+
## Groups
@@ -705,19 +724,11 @@ If you wish to interact with the drop event from one dockview instance in anothe
-### Example
-
-hello
+### Window-like mananger with tabs
-hello 2
-
-
-
-## VanillaJS
+## Vanilla JS
> Note: This section is experimental and support for Vanilla JS is a work in progress.
@@ -728,6 +739,6 @@ The core library is published as an independant package under the name `dockview
> `dockview-core` is a dependency of `dockview` and automatically installed during the installation process of `dockview` via `npm install dockview`.
diff --git a/packages/docs/versioned_docs/version-1.7.2/components/gridview.mdx b/packages/docs/versioned_docs/version-1.7.3/components/gridview.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.2/components/gridview.mdx
rename to packages/docs/versioned_docs/version-1.7.3/components/gridview.mdx
diff --git a/packages/docs/versioned_docs/version-1.7.2/components/paneview.mdx b/packages/docs/versioned_docs/version-1.7.3/components/paneview.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.2/components/paneview.mdx
rename to packages/docs/versioned_docs/version-1.7.3/components/paneview.mdx
diff --git a/packages/docs/versioned_docs/version-1.7.2/components/splitview.mdx b/packages/docs/versioned_docs/version-1.7.3/components/splitview.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.2/components/splitview.mdx
rename to packages/docs/versioned_docs/version-1.7.3/components/splitview.mdx
diff --git a/packages/docs/versioned_docs/version-1.7.2/index.mdx b/packages/docs/versioned_docs/version-1.7.3/index.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.2/index.mdx
rename to packages/docs/versioned_docs/version-1.7.3/index.mdx
diff --git a/packages/docs/versioned_docs/version-1.7.2/theme.mdx b/packages/docs/versioned_docs/version-1.7.3/theme.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.2/theme.mdx
rename to packages/docs/versioned_docs/version-1.7.3/theme.mdx
diff --git a/packages/docs/versioned_sidebars/version-1.7.2-sidebars.json b/packages/docs/versioned_sidebars/version-1.7.3-sidebars.json
similarity index 100%
rename from packages/docs/versioned_sidebars/version-1.7.2-sidebars.json
rename to packages/docs/versioned_sidebars/version-1.7.3-sidebars.json
diff --git a/packages/docs/versions.json b/packages/docs/versions.json
index 519af9b47..900dc7f77 100644
--- a/packages/docs/versions.json
+++ b/packages/docs/versions.json
@@ -1,3 +1,3 @@
[
- "1.7.2"
-]
+ "1.7.3"
+]
\ No newline at end of file
From 1964d6b30661ae4a1ea891053123a26b3b9aad58 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Sun, 4 Jun 2023 10:20:29 +0100
Subject: [PATCH 06/23] chore: update sandbox metadata
---
.codesandbox/ci.json | 10 +++---
.../constraints-dockview/package.json | 3 +-
.../constraints-dockview/tsconfig.json | 3 +-
.../customheader-dockview/package.json | 3 +-
.../customheader-dockview/tsconfig.json | 3 +-
.../docs/sandboxes/demo-dockview/package.json | 3 +-
.../sandboxes/demo-dockview/tsconfig.json | 3 +-
.../docs/sandboxes/dnd-dockview/package.json | 3 +-
.../docs/sandboxes/dnd-dockview/tsconfig.json | 3 +-
.../docs/sandboxes/dockview-app/package.json | 3 +-
.../docs/sandboxes/dockview-app/tsconfig.json | 3 +-
.../sandboxes/events-dockview/package.json | 3 +-
.../sandboxes/events-dockview/tsconfig.json | 3 +-
.../externaldnd-dockview/package.json | 3 +-
.../externaldnd-dockview/tsconfig.json | 3 +-
.../fullwidthtab-dockview/package.json | 3 +-
.../fullwidthtab-dockview/tsconfig.json | 3 +-
.../groupcontrol-dockview/package.json | 3 +-
.../groupcontrol-dockview/tsconfig.json | 3 +-
.../fullwidthtab-dockview/package.json | 3 +-
.../fullwidthtab-dockview/tsconfig.json | 3 +-
.../javascript/simple-dockview/package.json | 3 +-
.../javascript/simple-dockview/tsconfig.json | 3 +-
.../tabheight-dockview/package.json | 3 +-
.../tabheight-dockview/tsconfig.json | 3 +-
.../javascript/vanilla-dockview/package.json | 12 +++++--
.../javascript/vanilla-dockview/tsconfig.json | 33 +++++++++----------
.../sandboxes/layout-dockview/package.json | 3 +-
.../sandboxes/layout-dockview/tsconfig.json | 3 +-
.../sandboxes/nativeapp-dockview/package.json | 3 +-
.../nativeapp-dockview/tsconfig.json | 3 +-
.../sandboxes/nested-dockview/package.json | 3 +-
.../sandboxes/nested-dockview/tsconfig.json | 3 +-
.../sandboxes/rendering-dockview/package.json | 3 +-
.../rendering-dockview/tsconfig.json | 3 +-
.../sandboxes/resize-dockview/package.json | 3 +-
.../sandboxes/resize-dockview/tsconfig.json | 3 +-
.../resizecontainer-dockview/package.json | 3 +-
.../resizecontainer-dockview/tsconfig.json | 3 +-
.../sandboxes/simple-dockview/package.json | 3 +-
.../sandboxes/simple-dockview/tsconfig.json | 3 +-
.../sandboxes/tabheight-dockview/package.json | 5 +--
.../tabheight-dockview/tsconfig.json | 3 +-
.../updatetitle-dockview/package.json | 3 +-
.../updatetitle-dockview/tsconfig.json | 3 +-
.../sandboxes/watermark-dockview/package.json | 3 +-
.../watermark-dockview/tsconfig.json | 3 +-
47 files changed, 97 insertions(+), 92 deletions(-)
diff --git a/.codesandbox/ci.json b/.codesandbox/ci.json
index a6a13434a..856df6dc8 100644
--- a/.codesandbox/ci.json
+++ b/.codesandbox/ci.json
@@ -23,10 +23,10 @@
"/packages/docs/sandboxes/tabheight-dockview",
"/packages/docs/sandboxes/updatetitle-dockview",
"/packages/docs/sandboxes/watermark-dockview",
- "/packages/docs/sandboxes/typescript/fullwidthtab-dockview",
- "/packages/docs/sandboxes/typescript/simple-dockview",
- "/packages/docs/sandboxes/typescript/tabheight-dockview",
- "/packages/docs/sandboxes/typescript/vanilla-dockview"
+ "/packages/docs/sandboxes/javascript/fullwidthtab-dockview",
+ "/packages/docs/sandboxes/javascript/simple-dockview",
+ "/packages/docs/sandboxes/javascript/tabheight-dockview",
+ "/packages/docs/sandboxes/javascript/vanilla-dockview"
],
"node": "16"
-}
\ No newline at end of file
+}
diff --git a/packages/docs/sandboxes/constraints-dockview/package.json b/packages/docs/sandboxes/constraints-dockview/package.json
index e1497330a..3a34098c8 100644
--- a/packages/docs/sandboxes/constraints-dockview/package.json
+++ b/packages/docs/sandboxes/constraints-dockview/package.json
@@ -14,7 +14,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/constraints-dockview/tsconfig.json b/packages/docs/sandboxes/constraints-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/constraints-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/constraints-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/customheader-dockview/package.json b/packages/docs/sandboxes/customheader-dockview/package.json
index 8bf9bd86d..d3ede7462 100644
--- a/packages/docs/sandboxes/customheader-dockview/package.json
+++ b/packages/docs/sandboxes/customheader-dockview/package.json
@@ -14,7 +14,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/customheader-dockview/tsconfig.json b/packages/docs/sandboxes/customheader-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/customheader-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/customheader-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/demo-dockview/package.json b/packages/docs/sandboxes/demo-dockview/package.json
index 99ba4505f..fe47d8659 100644
--- a/packages/docs/sandboxes/demo-dockview/package.json
+++ b/packages/docs/sandboxes/demo-dockview/package.json
@@ -16,7 +16,8 @@
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"@types/uuid": "^9.0.0",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/demo-dockview/tsconfig.json b/packages/docs/sandboxes/demo-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/demo-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/demo-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/dnd-dockview/package.json b/packages/docs/sandboxes/dnd-dockview/package.json
index f9ef48454..fec39fd83 100644
--- a/packages/docs/sandboxes/dnd-dockview/package.json
+++ b/packages/docs/sandboxes/dnd-dockview/package.json
@@ -14,7 +14,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/dnd-dockview/tsconfig.json b/packages/docs/sandboxes/dnd-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/dnd-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/dnd-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/dockview-app/package.json b/packages/docs/sandboxes/dockview-app/package.json
index b4c4e1d29..edc8773be 100644
--- a/packages/docs/sandboxes/dockview-app/package.json
+++ b/packages/docs/sandboxes/dockview-app/package.json
@@ -14,7 +14,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/dockview-app/tsconfig.json b/packages/docs/sandboxes/dockview-app/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/dockview-app/tsconfig.json
+++ b/packages/docs/sandboxes/dockview-app/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/events-dockview/package.json b/packages/docs/sandboxes/events-dockview/package.json
index d32c8451d..176fc41c3 100644
--- a/packages/docs/sandboxes/events-dockview/package.json
+++ b/packages/docs/sandboxes/events-dockview/package.json
@@ -14,7 +14,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/events-dockview/tsconfig.json b/packages/docs/sandboxes/events-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/events-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/events-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/externaldnd-dockview/package.json b/packages/docs/sandboxes/externaldnd-dockview/package.json
index 10ab655c5..fba6c4e59 100644
--- a/packages/docs/sandboxes/externaldnd-dockview/package.json
+++ b/packages/docs/sandboxes/externaldnd-dockview/package.json
@@ -16,7 +16,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/externaldnd-dockview/tsconfig.json b/packages/docs/sandboxes/externaldnd-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/externaldnd-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/externaldnd-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/fullwidthtab-dockview/package.json b/packages/docs/sandboxes/fullwidthtab-dockview/package.json
index 5fddc50b3..ade7f643e 100644
--- a/packages/docs/sandboxes/fullwidthtab-dockview/package.json
+++ b/packages/docs/sandboxes/fullwidthtab-dockview/package.json
@@ -14,7 +14,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/fullwidthtab-dockview/tsconfig.json b/packages/docs/sandboxes/fullwidthtab-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/fullwidthtab-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/fullwidthtab-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/groupcontrol-dockview/package.json b/packages/docs/sandboxes/groupcontrol-dockview/package.json
index 21e91b3a4..7c88c11f1 100644
--- a/packages/docs/sandboxes/groupcontrol-dockview/package.json
+++ b/packages/docs/sandboxes/groupcontrol-dockview/package.json
@@ -14,7 +14,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/groupcontrol-dockview/tsconfig.json b/packages/docs/sandboxes/groupcontrol-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/groupcontrol-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/groupcontrol-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/javascript/fullwidthtab-dockview/package.json b/packages/docs/sandboxes/javascript/fullwidthtab-dockview/package.json
index c4d975c1a..14c42f556 100644
--- a/packages/docs/sandboxes/javascript/fullwidthtab-dockview/package.json
+++ b/packages/docs/sandboxes/javascript/fullwidthtab-dockview/package.json
@@ -10,7 +10,8 @@
"dockview-core": "*"
},
"devDependencies": {
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/javascript/fullwidthtab-dockview/tsconfig.json b/packages/docs/sandboxes/javascript/fullwidthtab-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/javascript/fullwidthtab-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/javascript/fullwidthtab-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/javascript/simple-dockview/package.json b/packages/docs/sandboxes/javascript/simple-dockview/package.json
index bc36e6b5d..d06484078 100644
--- a/packages/docs/sandboxes/javascript/simple-dockview/package.json
+++ b/packages/docs/sandboxes/javascript/simple-dockview/package.json
@@ -10,7 +10,8 @@
"dockview-core": "*"
},
"devDependencies": {
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/javascript/simple-dockview/tsconfig.json b/packages/docs/sandboxes/javascript/simple-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/javascript/simple-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/javascript/simple-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/javascript/tabheight-dockview/package.json b/packages/docs/sandboxes/javascript/tabheight-dockview/package.json
index 5aeba5d4d..754b48268 100644
--- a/packages/docs/sandboxes/javascript/tabheight-dockview/package.json
+++ b/packages/docs/sandboxes/javascript/tabheight-dockview/package.json
@@ -10,7 +10,8 @@
"dockview-core": "*"
},
"devDependencies": {
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/javascript/tabheight-dockview/tsconfig.json b/packages/docs/sandboxes/javascript/tabheight-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/javascript/tabheight-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/javascript/tabheight-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/javascript/vanilla-dockview/package.json b/packages/docs/sandboxes/javascript/vanilla-dockview/package.json
index b6bf01665..73bc3df0a 100644
--- a/packages/docs/sandboxes/javascript/vanilla-dockview/package.json
+++ b/packages/docs/sandboxes/javascript/vanilla-dockview/package.json
@@ -1,5 +1,5 @@
{
- "name": "vanilla-dockview",
+ "name": "javascript-vanilla-dockview",
"description": "",
"keywords": [
"dockview"
@@ -10,9 +10,15 @@
"dockview-core": "*"
},
"devDependencies": {
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test --env=jsdom",
+ "eject": "react-scripts eject"
},
- "scripts": {},
"browserslist": [
">0.2%",
"not dead",
diff --git a/packages/docs/sandboxes/javascript/vanilla-dockview/tsconfig.json b/packages/docs/sandboxes/javascript/vanilla-dockview/tsconfig.json
index 728865f76..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/javascript/vanilla-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/javascript/vanilla-dockview/tsconfig.json
@@ -1,19 +1,18 @@
{
- "compilerOptions": {
- "outDir": "build/dist",
- "module": "esnext",
- "target": "es5",
- "lib": ["es6", "dom"],
- "sourceMap": true,
- "allowJs": true,
- "jsx": "react-jsx",
- "moduleResolution": "node",
- "rootDir": "src",
- "forceConsistentCasingInFileNames": true,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
- }
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true
+ }
}
diff --git a/packages/docs/sandboxes/layout-dockview/package.json b/packages/docs/sandboxes/layout-dockview/package.json
index 309473289..f8aafc4e2 100644
--- a/packages/docs/sandboxes/layout-dockview/package.json
+++ b/packages/docs/sandboxes/layout-dockview/package.json
@@ -14,7 +14,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/layout-dockview/tsconfig.json b/packages/docs/sandboxes/layout-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/layout-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/layout-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/nativeapp-dockview/package.json b/packages/docs/sandboxes/nativeapp-dockview/package.json
index ad8d43fcc..9ebe7692a 100644
--- a/packages/docs/sandboxes/nativeapp-dockview/package.json
+++ b/packages/docs/sandboxes/nativeapp-dockview/package.json
@@ -14,7 +14,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/nativeapp-dockview/tsconfig.json b/packages/docs/sandboxes/nativeapp-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/nativeapp-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/nativeapp-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/nested-dockview/package.json b/packages/docs/sandboxes/nested-dockview/package.json
index 4914f99c2..8732f49ac 100644
--- a/packages/docs/sandboxes/nested-dockview/package.json
+++ b/packages/docs/sandboxes/nested-dockview/package.json
@@ -14,7 +14,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/nested-dockview/tsconfig.json b/packages/docs/sandboxes/nested-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/nested-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/nested-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/rendering-dockview/package.json b/packages/docs/sandboxes/rendering-dockview/package.json
index c9c6b849a..79f8f007d 100644
--- a/packages/docs/sandboxes/rendering-dockview/package.json
+++ b/packages/docs/sandboxes/rendering-dockview/package.json
@@ -14,7 +14,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/rendering-dockview/tsconfig.json b/packages/docs/sandboxes/rendering-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/rendering-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/rendering-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/resize-dockview/package.json b/packages/docs/sandboxes/resize-dockview/package.json
index a8f59f461..451e6f516 100644
--- a/packages/docs/sandboxes/resize-dockview/package.json
+++ b/packages/docs/sandboxes/resize-dockview/package.json
@@ -14,7 +14,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/resize-dockview/tsconfig.json b/packages/docs/sandboxes/resize-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/resize-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/resize-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/resizecontainer-dockview/package.json b/packages/docs/sandboxes/resizecontainer-dockview/package.json
index 9763e5795..fb2418926 100644
--- a/packages/docs/sandboxes/resizecontainer-dockview/package.json
+++ b/packages/docs/sandboxes/resizecontainer-dockview/package.json
@@ -14,7 +14,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/resizecontainer-dockview/tsconfig.json b/packages/docs/sandboxes/resizecontainer-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/resizecontainer-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/resizecontainer-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/simple-dockview/package.json b/packages/docs/sandboxes/simple-dockview/package.json
index 217115b06..ab2f1757f 100644
--- a/packages/docs/sandboxes/simple-dockview/package.json
+++ b/packages/docs/sandboxes/simple-dockview/package.json
@@ -14,7 +14,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/simple-dockview/tsconfig.json b/packages/docs/sandboxes/simple-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/simple-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/simple-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/tabheight-dockview/package.json b/packages/docs/sandboxes/tabheight-dockview/package.json
index af6d19d63..9b315f76e 100644
--- a/packages/docs/sandboxes/tabheight-dockview/package.json
+++ b/packages/docs/sandboxes/tabheight-dockview/package.json
@@ -14,7 +14,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
@@ -28,4 +29,4 @@
"not ie <= 11",
"not op_mini all"
]
-}
+}
\ No newline at end of file
diff --git a/packages/docs/sandboxes/tabheight-dockview/tsconfig.json b/packages/docs/sandboxes/tabheight-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/tabheight-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/tabheight-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/updatetitle-dockview/package.json b/packages/docs/sandboxes/updatetitle-dockview/package.json
index 1c7c2ac45..1fcbb4f55 100644
--- a/packages/docs/sandboxes/updatetitle-dockview/package.json
+++ b/packages/docs/sandboxes/updatetitle-dockview/package.json
@@ -14,7 +14,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/updatetitle-dockview/tsconfig.json b/packages/docs/sandboxes/updatetitle-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/updatetitle-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/updatetitle-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
diff --git a/packages/docs/sandboxes/watermark-dockview/package.json b/packages/docs/sandboxes/watermark-dockview/package.json
index c04cc2521..faa017e11 100644
--- a/packages/docs/sandboxes/watermark-dockview/package.json
+++ b/packages/docs/sandboxes/watermark-dockview/package.json
@@ -14,7 +14,8 @@
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
- "typescript": "^4.9.5"
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
diff --git a/packages/docs/sandboxes/watermark-dockview/tsconfig.json b/packages/docs/sandboxes/watermark-dockview/tsconfig.json
index 8aebe3efe..cdc4fb5f5 100644
--- a/packages/docs/sandboxes/watermark-dockview/tsconfig.json
+++ b/packages/docs/sandboxes/watermark-dockview/tsconfig.json
@@ -13,7 +13,6 @@
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
- "strictNullChecks": true,
- "noUnusedLocals": true
+ "strictNullChecks": true
}
}
From 3d47c8e2c550624bec76ed8f055577c93bd2c35e Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Sun, 4 Jun 2023 10:22:22 +0100
Subject: [PATCH 07/23] chore(release): publish v1.7.3
---
lerna.json | 2 +-
packages/dockview-core/package.json | 2 +-
packages/dockview/package.json | 4 ++--
packages/docs/package.json | 4 ++--
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/lerna.json b/lerna.json
index b2d59ced6..5d0c99866 100644
--- a/lerna.json
+++ b/lerna.json
@@ -3,7 +3,7 @@
"packages/*"
],
"useWorkspaces": true,
- "version": "1.7.2",
+ "version": "1.7.3",
"npmClient": "yarn",
"command": {
"publish": {
diff --git a/packages/dockview-core/package.json b/packages/dockview-core/package.json
index cdceee251..e8bbfe657 100644
--- a/packages/dockview-core/package.json
+++ b/packages/dockview-core/package.json
@@ -1,6 +1,6 @@
{
"name": "dockview-core",
- "version": "1.7.2",
+ "version": "1.7.3",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support",
"main": "./dist/cjs/index.js",
"types": "./dist/cjs/index.d.ts",
diff --git a/packages/dockview/package.json b/packages/dockview/package.json
index 19ec29c99..975e2e48c 100644
--- a/packages/dockview/package.json
+++ b/packages/dockview/package.json
@@ -1,6 +1,6 @@
{
"name": "dockview",
- "version": "1.7.2",
+ "version": "1.7.3",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support",
"main": "./dist/cjs/index.js",
"types": "./dist/cjs/index.d.ts",
@@ -56,7 +56,7 @@
"author": "https://github.com/mathuo",
"license": "MIT",
"dependencies": {
- "dockview-core": "^1.7.2"
+ "dockview-core": "^1.7.3"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^15.0.1",
diff --git a/packages/docs/package.json b/packages/docs/package.json
index a5a509892..a1a77a4bb 100644
--- a/packages/docs/package.json
+++ b/packages/docs/package.json
@@ -1,6 +1,6 @@
{
"name": "dockview-docs",
- "version": "1.7.2",
+ "version": "1.7.3",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
@@ -22,7 +22,7 @@
"@minoru/react-dnd-treeview": "^3.4.3",
"axios": "^1.3.3",
"clsx": "^1.2.1",
- "dockview": "^1.7.2",
+ "dockview": "^1.7.3",
"prism-react-renderer": "^1.3.5",
"react": "^18.2.0",
"react-dnd": "^16.0.1",
From 0cb621e86007c1128101b8753b9c0a4295897159 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Mon, 15 May 2023 20:11:41 +0100
Subject: [PATCH 08/23] cleanup event listeners after use
---
package.json | 7 +-
.../dockview/dockviewComponent.spec.ts | 82 +++++++-
.../src/__tests__/splitview/splitview.spec.ts | 9 +-
.../splitview/splitviewComponent.spec.ts | 40 ++++
packages/dockview-core/src/api/panelApi.ts | 20 +-
.../src/dnd/abstractDragHandler.ts | 3 +
packages/dockview-core/src/dnd/droptarget.ts | 1 +
.../dockview-core/src/dnd/groupDragHandler.ts | 4 -
.../src/dockview/components/panel/content.ts | 7 +-
.../src/dockview/components/tab/tab.ts | 14 +-
.../components/titlebar/tabsContainer.ts | 9 +-
.../src/dockview/dockviewComponent.ts | 58 +++---
.../src/dockview/dockviewGroupPanelModel.ts | 14 +-
.../src/dockview/dockviewPanel.ts | 2 +-
packages/dockview-core/src/dom.ts | 9 +-
packages/dockview-core/src/events.ts | 98 +++++++++-
.../src/gridview/baseComponentGridview.ts | 9 +-
.../src/gridview/basePanelView.ts | 13 +-
.../dockview-core/src/gridview/branchNode.ts | 9 +-
.../dockview-core/src/gridview/gridview.ts | 31 +--
.../src/gridview/gridviewPanel.ts | 4 +-
packages/dockview-core/src/lifecycle.ts | 8 +-
.../dockview-core/src/splitview/splitview.ts | 180 +++++++++---------
.../src/splitview/splitviewComponent.ts | 47 +++--
.../src/splitview/splitviewPanel.ts | 1 +
25 files changed, 450 insertions(+), 229 deletions(-)
diff --git a/package.json b/package.json
index 8d35430d0..b4938b069 100644
--- a/package.json
+++ b/package.json
@@ -44,6 +44,7 @@
"gulp": "^4.0.2",
"gulp-concat": "^2.6.1",
"gulp-dart-sass": "^1.0.2",
+ "jest": "^29.5.0",
"jest-environment-jsdom": "^29.4.3",
"jest-sonar-reporter": "^2.0.0",
"jsdom": "^21.1.0",
@@ -56,13 +57,11 @@
"ts-jest": "^29.0.5",
"ts-loader": "^9.4.2",
"tslib": "^2.5.0",
+ "ts-node": "^10.9.1",
"typescript": "^4.9.5",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.11.1"
},
- "dependencies": {
- "jest": "^29.5.0",
- "ts-node": "^10.9.1"
- }
+ "dependencies": {}
}
\ No newline at end of file
diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts
index 253cd4f1e..c65b960ee 100644
--- a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts
+++ b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts
@@ -46,6 +46,7 @@ class PanelContentPartTest implements IContentRenderer {
dispose(): void {
this.isDisposed = true;
this._onDidDispose.fire();
+ this._onDidDispose.dispose();
}
}
@@ -80,6 +81,7 @@ class PanelTabPartTest implements ITabRenderer {
dispose(): void {
this.isDisposed = true;
this._onDidDispose.fire();
+ this._onDidDispose.dispose();
}
}
@@ -98,6 +100,68 @@ describe('dockviewComponent', () => {
});
});
+ test('event leakage', () => {
+ Emitter.setLeakageMonitorEnabled(true);
+
+ dockview = new DockviewComponent({
+ parentElement: container,
+ components: {
+ default: PanelContentPartTest,
+ },
+ });
+
+ dockview.layout(500, 1000);
+
+ dockview.addPanel({
+ id: 'panel1',
+ component: 'default',
+ });
+
+ const panel2 = dockview.addPanel({
+ id: 'panel2',
+ component: 'default',
+ });
+
+ dockview.removePanel(panel2);
+
+ const panel3 = dockview.addPanel({
+ id: 'panel3',
+ component: 'default',
+ position: {
+ direction: 'right',
+ referencePanel: 'panel1',
+ },
+ });
+
+ const panel4 = dockview.addPanel({
+ id: 'panel4',
+ component: 'default',
+ position: {
+ direction: 'above',
+ },
+ });
+
+ dockview.moveGroupOrPanel(
+ panel4.group,
+ panel3.group.id,
+ panel3.id,
+ 'center'
+ );
+
+ dockview.dispose();
+
+ if (Emitter.MEMORY_LEAK_WATCHER.size > 0) {
+ for (const entry of Array.from(
+ Emitter.MEMORY_LEAK_WATCHER.events
+ )) {
+ console.log('disposal', entry[1]);
+ }
+ throw new Error('not all listeners disposed');
+ }
+
+ Emitter.setLeakageMonitorEnabled(false);
+ });
+
test('duplicate panel', () => {
dockview.layout(500, 1000);
@@ -112,6 +176,8 @@ describe('dockviewComponent', () => {
component: 'default',
});
}).toThrowError('panel with id panel1 already exists');
+
+ dockview.dispose();
});
test('set active panel', () => {
@@ -1285,21 +1351,21 @@ describe('dockviewComponent', () => {
tabComponent: 'default',
});
- const panel2 = dockview.addPanel({
- id: 'panel2',
- component: 'default',
- tabComponent: 'default',
- });
+ // const panel2 = dockview.addPanel({
+ // id: 'panel2',
+ // component: 'default',
+ // tabComponent: 'default',
+ // });
- expect(panel1.group).toEqual(panel2.group);
+ // expect(panel1.group).toEqual(panel2.group);
const panel1Spy = jest.spyOn(panel1, 'dispose');
- const panel2Spy = jest.spyOn(panel2, 'dispose');
+ // const panel2Spy = jest.spyOn(panel2, 'dispose');
dockview.dispose();
expect(panel1Spy).toBeCalledTimes(1);
- expect(panel2Spy).toBeCalledTimes(1);
+ // expect(panel2Spy).toBeCalledTimes(1);
});
test('panel is disposed of when from JSON is called', () => {
diff --git a/packages/dockview-core/src/__tests__/splitview/splitview.spec.ts b/packages/dockview-core/src/__tests__/splitview/splitview.spec.ts
index 60d94d513..23c9b1df8 100644
--- a/packages/dockview-core/src/__tests__/splitview/splitview.spec.ts
+++ b/packages/dockview-core/src/__tests__/splitview/splitview.spec.ts
@@ -585,8 +585,15 @@ describe('splitview', () => {
expect(container.childNodes.length).toBeGreaterThan(0);
- splitview.dispose();
+ let anyEvents = false;
+ const listener = splitview.onDidRemoveView((e) => {
+ anyEvents = true; // disposing of the splitview shouldn't fire onDidRemoveView events
+ });
+ splitview.dispose();
+ listener.dispose();
+
+ expect(anyEvents).toBeFalsy();
expect(container.childNodes.length).toBe(0);
});
});
diff --git a/packages/dockview-core/src/__tests__/splitview/splitviewComponent.spec.ts b/packages/dockview-core/src/__tests__/splitview/splitviewComponent.spec.ts
index e3c16e751..e43c94239 100644
--- a/packages/dockview-core/src/__tests__/splitview/splitviewComponent.spec.ts
+++ b/packages/dockview-core/src/__tests__/splitview/splitviewComponent.spec.ts
@@ -1,4 +1,5 @@
import { PanelDimensionChangeEvent } from '../../api/panelApi';
+import { Emitter } from '../../events';
import { CompositeDisposable } from '../../lifecycle';
import { Orientation } from '../../splitview/splitview';
import { SplitviewComponent } from '../../splitview/splitviewComponent';
@@ -25,6 +26,45 @@ describe('componentSplitview', () => {
container.className = 'container';
});
+ test('event leakage', () => {
+ Emitter.setLeakageMonitorEnabled(true);
+
+ const splitview = new SplitviewComponent({
+ parentElement: container,
+ orientation: Orientation.VERTICAL,
+ components: {
+ testPanel: TestPanel,
+ },
+ });
+ splitview.layout(600, 400);
+
+ const panel1 = splitview.addPanel({
+ id: 'panel1',
+ component: 'testPanel',
+ });
+ const panel2 = splitview.addPanel({
+ id: 'panel2',
+ component: 'testPanel',
+ });
+
+ splitview.movePanel(0, 1);
+
+ splitview.removePanel(panel1);
+
+ splitview.dispose();
+
+ if (Emitter.MEMORY_LEAK_WATCHER.size > 0) {
+ for (const entry of Array.from(
+ Emitter.MEMORY_LEAK_WATCHER.events
+ )) {
+ console.log(entry[1]);
+ }
+ throw new Error('not all listeners disposed');
+ }
+
+ Emitter.setLeakageMonitorEnabled(false);
+ });
+
test('remove panel', () => {
const splitview = new SplitviewComponent({
parentElement: container,
diff --git a/packages/dockview-core/src/api/panelApi.ts b/packages/dockview-core/src/api/panelApi.ts
index 37648cd84..795ac1589 100644
--- a/packages/dockview-core/src/api/panelApi.ts
+++ b/packages/dockview-core/src/api/panelApi.ts
@@ -126,15 +126,6 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
super();
this.addDisposables(
- this.panelUpdatesDisposable,
- this._onDidDimensionChange,
- this._onDidChangeFocus,
- this._onDidVisibilityChange,
- this._onDidActiveChange,
- this._onFocusEvent,
- this._onActiveChange,
- this._onVisibilityChange,
- this._onUpdateParameters,
this.onDidFocusChange((event) => {
this._isFocused = event.isFocused;
}),
@@ -147,7 +138,16 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
this.onDidDimensionsChange((event) => {
this._width = event.width;
this._height = event.height;
- })
+ }),
+ this.panelUpdatesDisposable,
+ this._onDidDimensionChange,
+ this._onDidChangeFocus,
+ this._onDidVisibilityChange,
+ this._onDidActiveChange,
+ this._onFocusEvent,
+ this._onActiveChange,
+ this._onVisibilityChange,
+ this._onUpdateParameters
);
}
diff --git a/packages/dockview-core/src/dnd/abstractDragHandler.ts b/packages/dockview-core/src/dnd/abstractDragHandler.ts
index 2120b8fc5..df3f49177 100644
--- a/packages/dockview-core/src/dnd/abstractDragHandler.ts
+++ b/packages/dockview-core/src/dnd/abstractDragHandler.ts
@@ -16,6 +16,9 @@ export abstract class DragHandler extends CompositeDisposable {
constructor(protected readonly el: HTMLElement) {
super();
+
+ this.addDisposables(this._onDragStart);
+
this.configure();
}
diff --git a/packages/dockview-core/src/dnd/droptarget.ts b/packages/dockview-core/src/dnd/droptarget.ts
index cac6d30ad..12fcb0ea0 100644
--- a/packages/dockview-core/src/dnd/droptarget.ts
+++ b/packages/dockview-core/src/dnd/droptarget.ts
@@ -177,6 +177,7 @@ export class Droptarget extends CompositeDisposable {
public dispose(): void {
this.removeDropTarget();
+ super.dispose();
}
private toggleClasses(
diff --git a/packages/dockview-core/src/dnd/groupDragHandler.ts b/packages/dockview-core/src/dnd/groupDragHandler.ts
index e7f99e062..bdd183182 100644
--- a/packages/dockview-core/src/dnd/groupDragHandler.ts
+++ b/packages/dockview-core/src/dnd/groupDragHandler.ts
@@ -53,8 +53,4 @@ export class GroupDragHandler extends DragHandler {
},
};
}
-
- public dispose(): void {
- //
- }
}
diff --git a/packages/dockview-core/src/dockview/components/panel/content.ts b/packages/dockview-core/src/dockview/components/panel/content.ts
index 75859e4d2..9934c5ec4 100644
--- a/packages/dockview-core/src/dockview/components/panel/content.ts
+++ b/packages/dockview-core/src/dockview/components/panel/content.ts
@@ -77,11 +77,12 @@ export class ContentContainer
const _onDidFocus = this.panel.view.content.onDidFocus;
const _onDidBlur = this.panel.view.content.onDidBlur;
- const { onDidFocus, onDidBlur } = trackFocus(this._element);
+ const focusTracker = trackFocus(this._element);
disposable.addDisposables(
- onDidFocus(() => this._onDidFocus.fire()),
- onDidBlur(() => this._onDidBlur.fire())
+ focusTracker,
+ focusTracker.onDidFocus(() => this._onDidFocus.fire()),
+ focusTracker.onDidBlur(() => this._onDidBlur.fire())
);
if (_onDidFocus) {
diff --git a/packages/dockview-core/src/dockview/components/tab/tab.ts b/packages/dockview-core/src/dockview/components/tab/tab.ts
index 550752e53..15c81206b 100644
--- a/packages/dockview-core/src/dockview/components/tab/tab.ts
+++ b/packages/dockview-core/src/dockview/components/tab/tab.ts
@@ -12,7 +12,7 @@ import { DockviewGroupPanel } from '../../dockviewGroupPanel';
import { DroptargetEvent, Droptarget } from '../../../dnd/droptarget';
import { DragHandler } from '../../../dnd/abstractDragHandler';
-export interface ITab {
+export interface ITab extends IDisposable {
readonly panelId: string;
readonly element: HTMLElement;
setContent: (element: ITabRenderer) => void;
@@ -43,8 +43,6 @@ export class Tab extends CompositeDisposable implements ITab {
) {
super();
- this.addDisposables(this._onChanged, this._onDropped);
-
this._element = document.createElement('div');
this._element.className = 'tab';
this._element.tabIndex = 0;
@@ -53,6 +51,8 @@ export class Tab extends CompositeDisposable implements ITab {
toggleClass(this.element, 'inactive-tab', true);
this.addDisposables(
+ this._onChanged,
+ this._onDropped,
new (class Handler extends DragHandler {
private readonly panelTransfer =
LocalSelectionTransfer.getInstance();
@@ -71,10 +71,6 @@ export class Tab extends CompositeDisposable implements ITab {
},
};
}
-
- public dispose(): void {
- //
- }
})(this._element)
);
@@ -127,7 +123,8 @@ export class Tab extends CompositeDisposable implements ITab {
this.addDisposables(
this.droptarget.onDrop((event) => {
this._onDropped.fire(event);
- })
+ }),
+ this.droptarget
);
}
@@ -146,6 +143,5 @@ export class Tab extends CompositeDisposable implements ITab {
public dispose(): void {
super.dispose();
- this.droptarget.dispose();
}
}
diff --git a/packages/dockview-core/src/dockview/components/titlebar/tabsContainer.ts b/packages/dockview-core/src/dockview/components/titlebar/tabsContainer.ts
index debdf42e0..68d8cfe1b 100644
--- a/packages/dockview-core/src/dockview/components/titlebar/tabsContainer.ts
+++ b/packages/dockview-core/src/dockview/components/titlebar/tabsContainer.ts
@@ -216,6 +216,7 @@ export class TabsContainer
const { value, disposable } = tabToRemove;
disposable.dispose();
+ value.dispose();
value.element.remove();
}
@@ -275,9 +276,11 @@ export class TabsContainer
public dispose(): void {
super.dispose();
- this.tabs.forEach((tab) => {
- tab.disposable.dispose();
- });
+ for (const { value, disposable } of this.tabs) {
+ disposable.dispose();
+ value.dispose();
+ }
+
this.tabs = [];
}
}
diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts
index 6d58c0b67..c180ad022 100644
--- a/packages/dockview-core/src/dockview/dockviewComponent.ts
+++ b/packages/dockview-core/src/dockview/dockviewComponent.ts
@@ -250,7 +250,6 @@ export class DockviewComponent
});
this.addDisposables(
- dropTarget,
dropTarget.onDrop((event) => {
const data = getPanelData();
@@ -269,7 +268,8 @@ export class DockviewComponent
getData: getPanelData,
});
}
- })
+ }),
+ dropTarget
);
this._api = new DockviewApi(this);
@@ -705,43 +705,49 @@ export class DockviewComponent
}
moveGroupOrPanel(
- referenceGroup: DockviewGroupPanel,
- groupId: string,
- itemId: string | undefined,
- target: Position,
- index?: number
+ destinationGroup: DockviewGroupPanel,
+ sourceGroupId: string,
+ sourceItemId: string | undefined,
+ destinationTarget: Position,
+ destinationIndex?: number
): void {
- const sourceGroup = groupId
- ? this._groups.get(groupId)?.value
+ const sourceGroup = sourceGroupId
+ ? this._groups.get(sourceGroupId)?.value
: undefined;
- if (itemId === undefined) {
+ if (sourceItemId === undefined) {
if (sourceGroup) {
- this.moveGroup(sourceGroup, referenceGroup, target);
+ this.moveGroup(
+ sourceGroup,
+ destinationGroup,
+ destinationTarget
+ );
}
return;
}
- if (!target || target === 'center') {
+ if (!destinationTarget || destinationTarget === 'center') {
const groupItem: IDockviewPanel | undefined =
- sourceGroup?.model.removePanel(itemId) ||
- this.panels.find((panel) => panel.id === itemId);
+ sourceGroup?.model.removePanel(sourceItemId) ||
+ this.panels.find((panel) => panel.id === sourceItemId);
if (!groupItem) {
- throw new Error(`No panel with id ${itemId}`);
+ throw new Error(`No panel with id ${sourceItemId}`);
}
if (sourceGroup?.model.size === 0) {
this.doRemoveGroup(sourceGroup);
}
- referenceGroup.model.openPanel(groupItem, { index });
+ destinationGroup.model.openPanel(groupItem, {
+ index: destinationIndex,
+ });
} else {
- const referenceLocation = getGridLocation(referenceGroup.element);
+ const referenceLocation = getGridLocation(destinationGroup.element);
const targetLocation = getRelativeLocation(
this.gridview.orientation,
referenceLocation,
- target
+ destinationTarget
);
if (sourceGroup && sourceGroup.size < 2) {
@@ -765,28 +771,28 @@ export class DockviewComponent
// after deleting the group we need to re-evaulate the ref location
const updatedReferenceLocation = getGridLocation(
- referenceGroup.element
+ destinationGroup.element
);
const location = getRelativeLocation(
this.gridview.orientation,
updatedReferenceLocation,
- target
+ destinationTarget
);
this.doAddGroup(targetGroup, location);
}
} else {
const groupItem: IDockviewPanel | undefined =
- sourceGroup?.model.removePanel(itemId) ||
- this.panels.find((panel) => panel.id === itemId);
+ sourceGroup?.model.removePanel(sourceItemId) ||
+ this.panels.find((panel) => panel.id === sourceItemId);
if (!groupItem) {
- throw new Error(`No panel with id ${itemId}`);
+ throw new Error(`No panel with id ${sourceItemId}`);
}
const dropLocation = getRelativeLocation(
this.gridview.orientation,
referenceLocation,
- target
+ destinationTarget
);
const group = this.createGroupAtLocation(dropLocation);
@@ -952,11 +958,11 @@ export class DockviewComponent
}
public dispose(): void {
- super.dispose();
-
this._onDidActivePanelChange.dispose();
this._onDidAddPanel.dispose();
this._onDidRemovePanel.dispose();
this._onDidLayoutFromJSON.dispose();
+
+ super.dispose();
}
}
diff --git a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts
index 5e9773a73..11bed8de9 100644
--- a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts
+++ b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts
@@ -282,12 +282,6 @@ export class DockviewGroupPanelModel
this.locked = !!options.locked;
this.addDisposables(
- this._onMove,
- this._onDidChange,
- this._onDidDrop,
- this._onDidAddPanel,
- this._onDidRemovePanel,
- this._onDidActivePanelChange,
this.tabsContainer.onDrop((event) => {
this.handleDropEvent(event.event, 'center', event.index);
}),
@@ -299,7 +293,13 @@ export class DockviewGroupPanelModel
}),
this.dropTarget.onDrop((event) => {
this.handleDropEvent(event.nativeEvent, event.position);
- })
+ }),
+ this._onMove,
+ this._onDidChange,
+ this._onDidDrop,
+ this._onDidAddPanel,
+ this._onDidRemovePanel,
+ this._onDidActivePanelChange
);
}
diff --git a/packages/dockview-core/src/dockview/dockviewPanel.ts b/packages/dockview-core/src/dockview/dockviewPanel.ts
index 66ac5be5f..c058c0015 100644
--- a/packages/dockview-core/src/dockview/dockviewPanel.ts
+++ b/packages/dockview-core/src/dockview/dockviewPanel.ts
@@ -108,7 +108,7 @@ export class DockviewPanel
if (didTitleChange) {
this._title = title;
- this.view?.update({
+ this.view.update({
params: {
params: this._params,
title: this.title,
diff --git a/packages/dockview-core/src/dom.ts b/packages/dockview-core/src/dom.ts
index eb1a37c05..4a36f4bde 100644
--- a/packages/dockview-core/src/dom.ts
+++ b/packages/dockview-core/src/dom.ts
@@ -111,6 +111,8 @@ class FocusTracker extends CompositeDisposable implements IFocusTracker {
constructor(element: HTMLElement | Window) {
super();
+ this.addDisposables(this._onDidFocus, this._onDidBlur);
+
let hasFocus = isAncestor(document.activeElement, element);
let loosingFocus = false;
@@ -169,11 +171,4 @@ class FocusTracker extends CompositeDisposable implements IFocusTracker {
refreshState(): void {
this._refreshStateHandler();
}
-
- public dispose(): void {
- super.dispose();
-
- this._onDidBlur.dispose();
- this._onDidFocus.dispose();
- }
}
diff --git a/packages/dockview-core/src/events.ts b/packages/dockview-core/src/events.ts
index 7f6b07ebf..13b8b3382 100644
--- a/packages/dockview-core/src/events.ts
+++ b/packages/dockview-core/src/events.ts
@@ -24,24 +24,76 @@ export namespace Event {
};
}
-// dumb event emitter with better typings than nodes event emitter
-// https://github.com/microsoft/vscode/blob/master/src/vs/base/common/event.ts
+class LeakageMonitor {
+ readonly events = new Map, Stacktrace>();
+
+ get size(): number {
+ return this.events.size;
+ }
+
+ add(event: Event, stacktrace: Stacktrace): void {
+ this.events.set(event, stacktrace);
+ }
+
+ delete(event: Event): void {
+ this.events.delete(event);
+ }
+
+ clear(): void {
+ this.events.clear();
+ }
+}
+
+class Stacktrace {
+ static create(): Stacktrace {
+ return new Stacktrace(new Error().stack ?? '');
+ }
+
+ private constructor(readonly value: string) {}
+
+ print(): void {
+ console.warn(this.value);
+ }
+}
+
+class Listener {
+ constructor(
+ readonly callback: (t: T) => void,
+ readonly stacktrace: Stacktrace | undefined
+ ) {}
+}
+
+// relatively simple event emitter taken from https://github.com/microsoft/vscode/blob/master/src/vs/base/common/event.ts
export class Emitter implements IDisposable {
private _event?: Event;
private _last?: T;
- private _listeners: Array<(e: T) => any> = [];
+ private _listeners: Listener[] = [];
private _disposed = false;
+ static ENABLE_TRACKING = false;
+ static readonly MEMORY_LEAK_WATCHER = new LeakageMonitor();
+
+ static setLeakageMonitorEnabled(isEnabled: boolean) {
+ if (isEnabled !== Emitter.ENABLE_TRACKING) {
+ Emitter.MEMORY_LEAK_WATCHER.clear();
+ }
+ Emitter.ENABLE_TRACKING = isEnabled;
+ }
+
constructor(private readonly options?: EmitterOptions) {}
get event(): Event {
if (!this._event) {
- this._event = (listener: (e: T) => void): IDisposable => {
+ this._event = (callback: (e: T) => void): IDisposable => {
if (this.options?.replay && this._last !== undefined) {
- listener(this._last);
+ callback(this._last);
}
+ const listener = new Listener(
+ callback,
+ Emitter.ENABLE_TRACKING ? Stacktrace.create() : undefined
+ );
this._listeners.push(listener);
return {
@@ -49,10 +101,22 @@ export class Emitter implements IDisposable {
const index = this._listeners.indexOf(listener);
if (index > -1) {
this._listeners.splice(index, 1);
+ } else if (Emitter.ENABLE_TRACKING) {
+ console.warn(
+ `Listener already disposed`,
+ Stacktrace.create().print()
+ );
}
},
};
};
+
+ if (Emitter.ENABLE_TRACKING) {
+ Emitter.MEMORY_LEAK_WATCHER.add(
+ this._event,
+ Stacktrace.create()
+ );
+ }
}
return this._event;
}
@@ -60,13 +124,31 @@ export class Emitter implements IDisposable {
public fire(e: T): void {
this._last = e;
for (const listener of this._listeners) {
- listener(e);
+ listener.callback(e);
}
}
public dispose(): void {
- this._listeners = [];
- this._disposed = true;
+ if (!this._disposed) {
+ this._disposed = true;
+
+ if (this._listeners.length > 0) {
+ if (Emitter.ENABLE_TRACKING) {
+ queueMicrotask(() => {
+ // don't check until stack of execution is completed to allow for out-of-order disposals within the same execution block
+ for (const listener of this._listeners) {
+ console.warn(listener.stacktrace?.print());
+ }
+ });
+ }
+
+ this._listeners = [];
+ }
+
+ if (Emitter.ENABLE_TRACKING && this._event) {
+ Emitter.MEMORY_LEAK_WATCHER.delete(this._event);
+ }
+ }
}
}
diff --git a/packages/dockview-core/src/gridview/baseComponentGridview.ts b/packages/dockview-core/src/gridview/baseComponentGridview.ts
index 7f2c281df..93c6861eb 100644
--- a/packages/dockview-core/src/gridview/baseComponentGridview.ts
+++ b/packages/dockview-core/src/gridview/baseComponentGridview.ts
@@ -143,10 +143,7 @@ export abstract class BaseGrid
this.addDisposables(
this.gridview.onDidChange(() => {
this._bufferOnDidLayoutChange.fire();
- })
- );
-
- this.addDisposables(
+ }),
Event.any(
this.onDidAddGroup,
this.onDidRemoveGroup,
@@ -297,8 +294,6 @@ export abstract class BaseGrid
}
public dispose(): void {
- super.dispose();
-
this._onDidActiveGroupChange.dispose();
this._onDidAddGroup.dispose();
this._onDidRemoveGroup.dispose();
@@ -309,5 +304,7 @@ export abstract class BaseGrid
}
this.gridview.dispose();
+
+ super.dispose();
}
}
diff --git a/packages/dockview-core/src/gridview/basePanelView.ts b/packages/dockview-core/src/gridview/basePanelView.ts
index 375b37a47..f61473864 100644
--- a/packages/dockview-core/src/gridview/basePanelView.ts
+++ b/packages/dockview-core/src/gridview/basePanelView.ts
@@ -68,16 +68,17 @@ export abstract class BasePanelView
this._element.style.width = '100%';
this._element.style.overflow = 'hidden';
- const { onDidFocus, onDidBlur } = trackFocus(this._element);
+ const focusTracker = trackFocus(this._element);
this.addDisposables(
this.api,
- onDidFocus(() => {
+ focusTracker.onDidFocus(() => {
this.api._onDidChangeFocus.fire({ isFocused: true });
}),
- onDidBlur(() => {
+ focusTracker.onDidBlur(() => {
this.api._onDidChangeFocus.fire({ isFocused: false });
- })
+ }),
+ focusTracker
);
}
@@ -124,9 +125,9 @@ export abstract class BasePanelView
}
dispose(): void {
- super.dispose();
-
this.api.dispose();
this.part?.dispose();
+
+ super.dispose();
}
}
diff --git a/packages/dockview-core/src/gridview/branchNode.ts b/packages/dockview-core/src/gridview/branchNode.ts
index c97e33243..6295b3f88 100644
--- a/packages/dockview-core/src/gridview/branchNode.ts
+++ b/packages/dockview-core/src/gridview/branchNode.ts
@@ -260,13 +260,13 @@ export class BranchNode extends CompositeDisposable implements IView {
return this.splitview.getViewCachedVisibleSize(index);
}
- public removeChild(index: number, sizing?: Sizing): void {
+ public removeChild(index: number, sizing?: Sizing): Node {
if (index < 0 || index >= this.children.length) {
throw new Error('Invalid index');
}
this.splitview.removeView(index, sizing);
- this._removeChild(index);
+ return this._removeChild(index);
}
private _addChild(node: Node, index: number): void {
@@ -296,9 +296,10 @@ export class BranchNode extends CompositeDisposable implements IView {
}
public dispose(): void {
- super.dispose();
this._childrenDisposable.dispose();
- this.children.forEach((child) => child.dispose());
this.splitview.dispose();
+ this.children.forEach((child) => child.dispose());
+
+ super.dispose();
}
}
diff --git a/packages/dockview-core/src/gridview/gridview.ts b/packages/dockview-core/src/gridview/gridview.ts
index 37242cc33..583b63c6f 100644
--- a/packages/dockview-core/src/gridview/gridview.ts
+++ b/packages/dockview-core/src/gridview/gridview.ts
@@ -462,7 +462,8 @@ export class Gridview implements IDisposable {
if (oldRoot.children.length === 1) {
// can remove one level of redundant branching if there is only a single child
const childReference = oldRoot.children[0];
- oldRoot.removeChild(0); // remove to prevent disposal when disposing of unwanted root
+ const child = oldRoot.removeChild(0); // remove to prevent disposal when disposing of unwanted root
+ child.dispose();
oldRoot.dispose();
this._root.addChild(
@@ -632,7 +633,8 @@ export class Gridview implements IDisposable {
newSiblingSize = Sizing.Invisible(newSiblingCachedVisibleSize);
}
- grandParent.removeChild(parentIndex);
+ const child = grandParent.removeChild(parentIndex);
+ child.dispose();
const newParent = new BranchNode(
parent.orientation,
@@ -682,14 +684,18 @@ export class Gridview implements IDisposable {
throw new Error('Invalid location');
}
- parent.removeChild(index, sizing);
+ const view = node.view;
+ node.dispose(); // dispose of node
+
+ const child = parent.removeChild(index, sizing);
+ child.dispose();
if (parent.children.length === 0) {
- return node.view;
+ return view;
}
if (parent.children.length > 1) {
- return node.view;
+ return view;
}
const sibling = parent.children[0];
@@ -698,25 +704,28 @@ export class Gridview implements IDisposable {
// parent is root
if (sibling instanceof LeafNode) {
- return node.view;
+ return view;
}
// we must promote sibling to be the new root
- parent.removeChild(0, sizing);
+ const child = parent.removeChild(0, sizing);
+ child.dispose();
this.root = sibling;
- return node.view;
+ return view;
}
const [grandParent, ..._] = [...pathToParent].reverse();
const [parentIndex, ...__] = [...rest].reverse();
const isSiblingVisible = parent.isChildVisible(0);
- parent.removeChild(0, sizing);
+ const childNode = parent.removeChild(0, sizing);
+ childNode.dispose();
const sizes = grandParent.children.map((_size, i) =>
grandParent.getChildSize(i)
);
- grandParent.removeChild(parentIndex, sizing);
+ const parentNode = grandParent.removeChild(parentIndex, sizing);
+ parentNode.dispose();
if (sibling instanceof BranchNode) {
sizes.splice(
@@ -745,7 +754,7 @@ export class Gridview implements IDisposable {
grandParent.resizeChild(i, sizes[i]);
}
- return node.view;
+ return view;
}
public layout(width: number, height: number): void {
diff --git a/packages/dockview-core/src/gridview/gridviewPanel.ts b/packages/dockview-core/src/gridview/gridviewPanel.ts
index 530a3cc70..9562bb92b 100644
--- a/packages/dockview-core/src/gridview/gridviewPanel.ts
+++ b/packages/dockview-core/src/gridview/gridviewPanel.ts
@@ -154,7 +154,6 @@ export abstract class GridviewPanel
this.api.initialize(this); // TODO: required to by-pass 'super before this' requirement
this.addDisposables(
- this._onDidChange,
this.api.onVisibilityChange((event) => {
const { isVisible } = event;
const { accessor } = this._params as GridviewInitParameters;
@@ -195,7 +194,8 @@ export abstract class GridviewPanel
height: event.height,
width: event.width,
});
- })
+ }),
+ this._onDidChange
);
}
diff --git a/packages/dockview-core/src/lifecycle.ts b/packages/dockview-core/src/lifecycle.ts
index e756bc803..8262b28d1 100644
--- a/packages/dockview-core/src/lifecycle.ts
+++ b/packages/dockview-core/src/lifecycle.ts
@@ -16,7 +16,7 @@ export namespace Disposable {
}
export class CompositeDisposable {
- private readonly disposables: IDisposable[];
+ private readonly _disposables: IDisposable[];
private _isDisposed = false;
protected get isDisposed(): boolean {
@@ -28,15 +28,15 @@ export class CompositeDisposable {
}
constructor(...args: IDisposable[]) {
- this.disposables = args;
+ this._disposables = args;
}
public addDisposables(...args: IDisposable[]): void {
- args.forEach((arg) => this.disposables.push(arg));
+ args.forEach((arg) => this._disposables.push(arg));
}
public dispose(): void {
- this.disposables.forEach((arg) => arg.dispose());
+ this._disposables.forEach((arg) => arg.dispose());
this._isDisposed = true;
}
diff --git a/packages/dockview-core/src/splitview/splitview.ts b/packages/dockview-core/src/splitview/splitview.ts
index 447529cfe..48295a8c7 100644
--- a/packages/dockview-core/src/splitview/splitview.ts
+++ b/packages/dockview-core/src/splitview/splitview.ts
@@ -13,6 +13,7 @@ import { Event, Emitter } from '../events';
import { pushToStart, pushToEnd, firstIndex } from '../array';
import { range, clamp } from '../math';
import { ViewItem } from './viewItem';
+import { IDisposable } from '../lifecycle';
export enum Orientation {
HORIZONTAL = 'HORIZONTAL',
@@ -42,7 +43,7 @@ export enum LayoutPriority {
Normal = 'normal',
}
-export interface IBaseView {
+export interface IBaseView extends IDisposable {
minimumSize: number;
maximumSize: number;
snap?: boolean;
@@ -97,7 +98,7 @@ export class Splitview {
private element: HTMLElement;
private viewContainer: HTMLElement;
private sashContainer: HTMLElement;
- private views: ViewItem[] = [];
+ private viewItems: ViewItem[] = [];
private sashes: ISashItem[] = [];
private _orientation: Orientation;
private _size = 0;
@@ -132,7 +133,7 @@ export class Splitview {
}
public get length(): number {
- return this.views.length;
+ return this.viewItems.length;
}
public get proportions(): number[] | undefined {
@@ -159,13 +160,13 @@ export class Splitview {
}
get minimumSize(): number {
- return this.views.reduce((r, item) => r + item.minimumSize, 0);
+ return this.viewItems.reduce((r, item) => r + item.minimumSize, 0);
}
get maximumSize(): number {
return this.length === 0
? Number.POSITIVE_INFINITY
- : this.views.reduce((r, item) => r + item.maximumSize, 0);
+ : this.viewItems.reduce((r, item) => r + item.maximumSize, 0);
}
get startSnappingEnabled(): boolean {
@@ -240,7 +241,7 @@ export class Splitview {
});
// Initialize content size and proportions for first layout
- this.contentSize = this.views.reduce((r, i) => r + i.size, 0);
+ this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
this.saveProportions();
}
}
@@ -261,22 +262,22 @@ export class Splitview {
}
isViewVisible(index: number): boolean {
- if (index < 0 || index >= this.views.length) {
+ if (index < 0 || index >= this.viewItems.length) {
throw new Error('Index out of bounds');
}
- const viewItem = this.views[index];
+ const viewItem = this.viewItems[index];
return viewItem.visible;
}
setViewVisible(index: number, visible: boolean): void {
- if (index < 0 || index >= this.views.length) {
+ if (index < 0 || index >= this.viewItems.length) {
throw new Error('Index out of bounds');
}
toggleClass(this.container, 'visible', visible);
- const viewItem = this.views[index];
+ const viewItem = this.viewItems[index];
toggleClass(this.container, 'visible', visible);
@@ -288,30 +289,30 @@ export class Splitview {
}
getViewSize(index: number): number {
- if (index < 0 || index >= this.views.length) {
+ if (index < 0 || index >= this.viewItems.length) {
return -1;
}
- return this.views[index].size;
+ return this.viewItems[index].size;
}
resizeView(index: number, size: number): void {
- if (index < 0 || index >= this.views.length) {
+ if (index < 0 || index >= this.viewItems.length) {
return;
}
- const indexes = range(this.views.length).filter((i) => i !== index);
+ const indexes = range(this.viewItems.length).filter((i) => i !== index);
const lowPriorityIndexes = [
...indexes.filter(
- (i) => this.views[i].priority === LayoutPriority.Low
+ (i) => this.viewItems[i].priority === LayoutPriority.Low
),
index,
];
const highPriorityIndexes = indexes.filter(
- (i) => this.views[i].priority === LayoutPriority.High
+ (i) => this.viewItems[i].priority === LayoutPriority.High
);
- const item = this.views[index];
+ const item = this.viewItems[index];
size = Math.round(size);
size = clamp(
size,
@@ -324,13 +325,13 @@ export class Splitview {
}
public getViews(): T[] {
- return this.views.map((x) => x.view as T);
+ return this.viewItems.map((x) => x.view as T);
}
private onDidChange(item: ViewItem, size: number | undefined): void {
- const index = this.views.indexOf(item);
+ const index = this.viewItems.indexOf(item);
- if (index < 0 || index >= this.views.length) {
+ if (index < 0 || index >= this.viewItems.length) {
return;
}
@@ -345,7 +346,7 @@ export class Splitview {
public addView(
view: IView,
size: number | Sizing = { type: 'distribute' },
- index: number = this.views.length,
+ index: number = this.viewItems.length,
skipLayout?: boolean
): void {
const container = document.createElement('div');
@@ -369,14 +370,14 @@ export class Splitview {
this.onDidChange(viewItem, newSize.size)
);
- const dispose = () => {
- disposable?.dispose();
- this.viewContainer.removeChild(container);
- };
+ const viewItem = new ViewItem(container, view, viewSize, {
+ dispose: () => {
+ disposable.dispose();
+ this.viewContainer.removeChild(container);
+ },
+ });
- const viewItem = new ViewItem(container, view, viewSize, { dispose });
-
- if (index === this.views.length) {
+ if (index === this.viewItems.length) {
this.viewContainer.appendChild(container);
} else {
this.viewContainer.insertBefore(
@@ -385,15 +386,15 @@ export class Splitview {
);
}
- this.views.splice(index, 0, viewItem);
+ this.viewItems.splice(index, 0, viewItem);
- if (this.views.length > 1) {
+ if (this.viewItems.length > 1) {
//add sash
const sash = document.createElement('div');
sash.className = 'sash';
const onStart = (event: MouseEvent) => {
- for (const item of this.views) {
+ for (const item of this.viewItems) {
item.enabled = false;
}
@@ -417,19 +418,20 @@ export class Splitview {
);
//
- const sizes = this.views.map((x) => x.size);
+ const sizes = this.viewItems.map((x) => x.size);
//
let snapBefore: ISashDragSnapState | undefined;
let snapAfter: ISashDragSnapState | undefined;
const upIndexes = range(sashIndex, -1);
- const downIndexes = range(sashIndex + 1, this.views.length);
+ const downIndexes = range(sashIndex + 1, this.viewItems.length);
const minDeltaUp = upIndexes.reduce(
- (r, i) => r + (this.views[i].minimumSize - sizes[i]),
+ (r, i) => r + (this.viewItems[i].minimumSize - sizes[i]),
0
);
const maxDeltaUp = upIndexes.reduce(
- (r, i) => r + (this.views[i].viewMaximumSize - sizes[i]),
+ (r, i) =>
+ r + (this.viewItems[i].viewMaximumSize - sizes[i]),
0
);
const maxDeltaDown =
@@ -437,7 +439,8 @@ export class Splitview {
? Number.POSITIVE_INFINITY
: downIndexes.reduce(
(r, i) =>
- r + (sizes[i] - this.views[i].minimumSize),
+ r +
+ (sizes[i] - this.viewItems[i].minimumSize),
0
);
const minDeltaDown =
@@ -446,7 +449,8 @@ export class Splitview {
: downIndexes.reduce(
(r, i) =>
r +
- (sizes[i] - this.views[i].viewMaximumSize),
+ (sizes[i] -
+ this.viewItems[i].viewMaximumSize),
0
);
const minDelta = Math.max(minDeltaUp, minDeltaDown);
@@ -454,7 +458,7 @@ export class Splitview {
const snapBeforeIndex = this.findFirstSnapIndex(upIndexes);
const snapAfterIndex = this.findFirstSnapIndex(downIndexes);
if (typeof snapBeforeIndex === 'number') {
- const snappedViewItem = this.views[snapBeforeIndex];
+ const snappedViewItem = this.viewItems[snapBeforeIndex];
const halfSize = Math.floor(
snappedViewItem.viewMinimumSize / 2
);
@@ -469,7 +473,7 @@ export class Splitview {
}
if (typeof snapAfterIndex === 'number') {
- const snappedViewItem = this.views[snapAfterIndex];
+ const snappedViewItem = this.viewItems[snapAfterIndex];
const halfSize = Math.floor(
snappedViewItem.viewMinimumSize / 2
);
@@ -507,7 +511,7 @@ export class Splitview {
};
const end = () => {
- for (const item of this.views) {
+ for (const item of this.viewItems) {
item.enabled = true;
}
@@ -562,7 +566,7 @@ export class Splitview {
const flexibleViewItems: ViewItem[] = [];
let flexibleSize = 0;
- for (const item of this.views) {
+ for (const item of this.viewItems) {
if (item.maximumSize - item.minimumSize > 0) {
flexibleViewItems.push(item);
flexibleSize += item.size;
@@ -575,12 +579,12 @@ export class Splitview {
item.size = clamp(size, item.minimumSize, item.maximumSize);
}
- const indexes = range(this.views.length);
+ const indexes = range(this.viewItems.length);
const lowPriorityIndexes = indexes.filter(
- (i) => this.views[i].priority === LayoutPriority.Low
+ (i) => this.viewItems[i].priority === LayoutPriority.Low
);
const highPriorityIndexes = indexes.filter(
- (i) => this.views[i].priority === LayoutPriority.High
+ (i) => this.viewItems[i].priority === LayoutPriority.High
);
this.relayout(lowPriorityIndexes, highPriorityIndexes);
@@ -592,11 +596,11 @@ export class Splitview {
skipLayout = false
): IView {
// Remove view
- const viewItem = this.views.splice(index, 1)[0];
+ const viewItem = this.viewItems.splice(index, 1)[0];
viewItem.dispose();
// Remove sash
- if (this.views.length >= 1) {
+ if (this.viewItems.length >= 1) {
const sashIndex = Math.max(index - 1, 0);
const sashItem = this.sashes.splice(sashIndex, 1)[0];
sashItem.disposable();
@@ -616,11 +620,11 @@ export class Splitview {
}
getViewCachedVisibleSize(index: number): number | undefined {
- if (index < 0 || index >= this.views.length) {
+ if (index < 0 || index >= this.viewItems.length) {
throw new Error('Index out of bounds');
}
- const viewItem = this.views[index];
+ const viewItem = this.viewItems[index];
return viewItem.cachedVisibleSize;
}
@@ -640,24 +644,24 @@ export class Splitview {
this.orthogonalSize = orthogonalSize;
if (!this.proportions) {
- const indexes = range(this.views.length);
+ const indexes = range(this.viewItems.length);
const lowPriorityIndexes = indexes.filter(
- (i) => this.views[i].priority === LayoutPriority.Low
+ (i) => this.viewItems[i].priority === LayoutPriority.Low
);
const highPriorityIndexes = indexes.filter(
- (i) => this.views[i].priority === LayoutPriority.High
+ (i) => this.viewItems[i].priority === LayoutPriority.High
);
this.resize(
- this.views.length - 1,
+ this.viewItems.length - 1,
size - previousSize,
undefined,
lowPriorityIndexes,
highPriorityIndexes
);
} else {
- for (let i = 0; i < this.views.length; i++) {
- const item = this.views[i];
+ for (let i = 0; i < this.viewItems.length; i++) {
+ const item = this.viewItems[i];
item.size = clamp(
Math.round(this.proportions[i] * size),
@@ -675,10 +679,10 @@ export class Splitview {
lowPriorityIndexes?: number[],
highPriorityIndexes?: number[]
): void {
- const contentSize = this.views.reduce((r, i) => r + i.size, 0);
+ const contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
this.resize(
- this.views.length - 1,
+ this.viewItems.length - 1,
this._size - contentSize,
undefined,
lowPriorityIndexes,
@@ -690,15 +694,15 @@ export class Splitview {
}
private distributeEmptySpace(lowPriorityIndex?: number): void {
- const contentSize = this.views.reduce((r, i) => r + i.size, 0);
+ const contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
let emptyDelta = this.size - contentSize;
- const indexes = range(this.views.length - 1, -1);
+ const indexes = range(this.viewItems.length - 1, -1);
const lowPriorityIndexes = indexes.filter(
- (i) => this.views[i].priority === LayoutPriority.Low
+ (i) => this.viewItems[i].priority === LayoutPriority.Low
);
const highPriorityIndexes = indexes.filter(
- (i) => this.views[i].priority === LayoutPriority.High
+ (i) => this.viewItems[i].priority === LayoutPriority.High
);
for (const index of highPriorityIndexes) {
@@ -714,7 +718,7 @@ export class Splitview {
}
for (let i = 0; emptyDelta !== 0 && i < indexes.length; i++) {
- const item = this.views[indexes[i]];
+ const item = this.viewItems[indexes[i]];
const size = clamp(
item.size + emptyDelta,
item.minimumSize,
@@ -729,21 +733,21 @@ export class Splitview {
private saveProportions(): void {
if (this.proportionalLayout && this.contentSize > 0) {
- this._proportions = this.views.map(
+ this._proportions = this.viewItems.map(
(i) => i.size / this.contentSize
);
}
}
private layoutViews(): void {
- this.contentSize = this.views.reduce((r, i) => r + i.size, 0);
+ this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
let sum = 0;
const x: number[] = [];
this.updateSashEnablement();
- for (let i = 0; i < this.views.length - 1; i++) {
- sum += this.views[i].size;
+ for (let i = 0; i < this.viewItems.length - 1; i++) {
+ sum += this.viewItems[i].size;
x.push(sum);
const offset = Math.min(Math.max(0, sum - 2), this.size - 4);
@@ -757,7 +761,7 @@ export class Splitview {
this.sashes[i].container.style.top = `${offset}px`;
}
}
- this.views.forEach((view, i) => {
+ this.viewItems.forEach((view, i) => {
if (this._orientation === Orientation.HORIZONTAL) {
view.container.style.width = `${view.size}px`;
view.container.style.left = i == 0 ? '0px' : `${x[i - 1]}px`;
@@ -778,7 +782,7 @@ export class Splitview {
private findFirstSnapIndex(indexes: number[]): number | undefined {
// visible views first
for (const index of indexes) {
- const viewItem = this.views[index];
+ const viewItem = this.viewItems[index];
if (!viewItem.visible) {
continue;
@@ -791,7 +795,7 @@ export class Splitview {
// then, hidden views
for (const index of indexes) {
- const viewItem = this.views[index];
+ const viewItem = this.viewItems[index];
if (
viewItem.visible &&
@@ -810,16 +814,16 @@ export class Splitview {
private updateSashEnablement(): void {
let previous = false;
- const collapsesDown = this.views.map(
+ const collapsesDown = this.viewItems.map(
(i) => (previous = i.size - i.minimumSize > 0 || previous)
);
previous = false;
- const expandsDown = this.views.map(
+ const expandsDown = this.viewItems.map(
(i) => (previous = i.maximumSize - i.size > 0 || previous)
);
- const reverseViews = [...this.views].reverse();
+ const reverseViews = [...this.viewItems].reverse();
previous = false;
const collapsesUp = reverseViews
.map((i) => (previous = i.size - i.minimumSize > 0 || previous))
@@ -833,7 +837,7 @@ export class Splitview {
let position = 0;
for (let index = 0; index < this.sashes.length; index++) {
const sash = this.sashes[index];
- const viewItem = this.views[index];
+ const viewItem = this.viewItems[index];
position += viewItem.size;
const min = !(collapsesDown[index] && expandsUp[index + 1]);
@@ -841,16 +845,16 @@ export class Splitview {
if (min && max) {
const upIndexes = range(index, -1);
- const downIndexes = range(index + 1, this.views.length);
+ const downIndexes = range(index + 1, this.viewItems.length);
const snapBeforeIndex = this.findFirstSnapIndex(upIndexes);
const snapAfterIndex = this.findFirstSnapIndex(downIndexes);
const snappedBefore =
typeof snapBeforeIndex === 'number' &&
- !this.views[snapBeforeIndex].visible;
+ !this.viewItems[snapBeforeIndex].visible;
const snappedAfter =
typeof snapAfterIndex === 'number' &&
- !this.views[snapAfterIndex].visible;
+ !this.viewItems[snapAfterIndex].visible;
if (
snappedBefore &&
@@ -887,7 +891,7 @@ export class Splitview {
private resize = (
index: number,
delta: number,
- sizes: number[] = this.views.map((x) => x.size),
+ sizes: number[] = this.viewItems.map((x) => x.size),
lowPriorityIndexes?: number[],
highPriorityIndexes?: number[],
overloadMinDelta: number = Number.NEGATIVE_INFINITY,
@@ -895,12 +899,12 @@ export class Splitview {
snapBefore?: ISashDragSnapState,
snapAfter?: ISashDragSnapState
): number => {
- if (index < 0 || index > this.views.length) {
+ if (index < 0 || index > this.viewItems.length) {
return 0;
}
const upIndexes = range(index, -1);
- const downIndexes = range(index + 1, this.views.length);
+ const downIndexes = range(index + 1, this.viewItems.length);
//
if (highPriorityIndexes) {
for (const i of highPriorityIndexes) {
@@ -916,18 +920,18 @@ export class Splitview {
}
}
//
- const upItems = upIndexes.map((i) => this.views[i]);
+ const upItems = upIndexes.map((i) => this.viewItems[i]);
const upSizes = upIndexes.map((i) => sizes[i]);
//
- const downItems = downIndexes.map((i) => this.views[i]);
+ const downItems = downIndexes.map((i) => this.viewItems[i]);
const downSizes = downIndexes.map((i) => sizes[i]);
//
const minDeltaUp = upIndexes.reduce(
- (_, i) => _ + this.views[i].minimumSize - sizes[i],
+ (_, i) => _ + this.viewItems[i].minimumSize - sizes[i],
0
);
const maxDeltaUp = upIndexes.reduce(
- (_, i) => _ + this.views[i].maximumSize - sizes[i],
+ (_, i) => _ + this.viewItems[i].maximumSize - sizes[i],
0
);
//
@@ -935,7 +939,7 @@ export class Splitview {
downIndexes.length === 0
? Number.POSITIVE_INFINITY
: downIndexes.reduce(
- (_, i) => _ + sizes[i] - this.views[i].minimumSize,
+ (_, i) => _ + sizes[i] - this.viewItems[i].minimumSize,
0
);
@@ -943,7 +947,7 @@ export class Splitview {
downIndexes.length === 0
? Number.NEGATIVE_INFINITY
: downIndexes.reduce(
- (_, i) => _ + sizes[i] - this.views[i].maximumSize,
+ (_, i) => _ + sizes[i] - this.viewItems[i].maximumSize,
0
);
//
@@ -952,14 +956,14 @@ export class Splitview {
//
let snapped = false;
if (snapBefore) {
- const snapView = this.views[snapBefore.index];
+ const snapView = this.viewItems[snapBefore.index];
const visible = delta >= snapBefore.limitDelta;
snapped = visible !== snapView.visible;
snapView.setVisible(visible, snapBefore.size);
}
if (!snapped && snapAfter) {
- const snapView = this.views[snapAfter.index];
+ const snapView = this.viewItems[snapAfter.index];
const visible = delta < snapAfter.limitDelta;
snapped = visible !== snapView.visible;
snapView.setVisible(visible, snapAfter.size);
@@ -1047,6 +1051,10 @@ export class Splitview {
}
}
+ for (const viewItem of this.viewItems) {
+ viewItem.dispose();
+ }
+
this.element.remove();
}
}
diff --git a/packages/dockview-core/src/splitview/splitviewComponent.ts b/packages/dockview-core/src/splitview/splitviewComponent.ts
index f4f0bee7c..37573c40e 100644
--- a/packages/dockview-core/src/splitview/splitviewComponent.ts
+++ b/packages/dockview-core/src/splitview/splitviewComponent.ts
@@ -1,7 +1,6 @@
import {
CompositeDisposable,
IDisposable,
- IValueDisposable,
MutableDisposable,
} from '../lifecycle';
import {
@@ -83,10 +82,10 @@ export class SplitviewComponent
extends Resizable
implements ISplitviewComponent
{
- private _disposable = new MutableDisposable();
+ private _splitviewChangeDisposable = new MutableDisposable();
private _splitview!: Splitview;
private _activePanel: SplitviewPanel | undefined;
- private _panels = new Map>();
+ private _panels = new Map();
private _options: SplitviewComponentOptions;
private readonly _onDidLayoutfromJSON = new Emitter();
@@ -124,7 +123,7 @@ export class SplitviewComponent
set splitview(value: Splitview) {
this._splitview = value;
- this._disposable.value = new CompositeDisposable(
+ this._splitviewChangeDisposable.value = new CompositeDisposable(
this._splitview.onDidSashEnd(() => {
this._onDidLayoutChange.fire(undefined);
}),
@@ -170,7 +169,6 @@ export class SplitviewComponent
this.splitview = new Splitview(this.element, options);
this.addDisposables(
- this._disposable,
this._onDidAddView,
this._onDidLayoutfromJSON,
this._onDidRemoveView,
@@ -226,19 +224,19 @@ export class SplitviewComponent
}
removePanel(panel: SplitviewPanel, sizing?: Sizing): void {
- const disposable = this._panels.get(panel.id);
+ const item = this._panels.get(panel.id);
- if (!disposable) {
+ if (!item) {
throw new Error(`unknown splitview panel ${panel.id}`);
}
- disposable.disposable.dispose();
- disposable.value.dispose();
+ item.dispose();
this._panels.delete(panel.id);
const index = this.panels.findIndex((_) => _ === panel);
- this.splitview.removeView(index, sizing);
+ const removedView = this.splitview.removeView(index, sizing);
+ removedView.dispose();
const panels = this.panels;
if (panels.length > 0) {
@@ -250,7 +248,7 @@ export class SplitviewComponent
return this.panels.find((view) => view.id === id);
}
- addPanel(options: AddSplitviewComponentOptions): ISplitviewPanel {
+ addPanel(options: AddSplitviewComponentOptions): SplitviewPanel {
if (this._panels.has(options.id)) {
throw new Error(`panel ${options.id} already exists`);
}
@@ -308,7 +306,7 @@ export class SplitviewComponent
this.setActive(view, true);
});
- this._panels.set(view.id, { disposable, value: view });
+ this._panels.set(view.id, disposable);
}
toJSON(): SerializedSplitview {
@@ -404,23 +402,34 @@ export class SplitviewComponent
}
clear(): void {
- for (const [_, value] of this._panels.entries()) {
- value.disposable.dispose();
- value.value.dispose();
+ for (const disposable of this._panels.values()) {
+ disposable.dispose();
}
+
this._panels.clear();
- this.splitview.dispose();
+
+ while (this.splitview.length > 0) {
+ const view = this.splitview.removeView(0, Sizing.Distribute, true);
+ view.dispose();
+ }
}
dispose(): void {
- for (const [_, value] of this._panels.entries()) {
- value.disposable.dispose();
- value.value.dispose();
+ for (const disposable of this._panels.values()) {
+ disposable.dispose();
}
+
this._panels.clear();
+ const views = this.splitview.getViews();
+
+ this._splitviewChangeDisposable.dispose();
this.splitview.dispose();
+ for (const view of views) {
+ view.dispose();
+ }
+
super.dispose();
}
}
diff --git a/packages/dockview-core/src/splitview/splitviewPanel.ts b/packages/dockview-core/src/splitview/splitviewPanel.ts
index 4782e8c30..d0ac1c41c 100644
--- a/packages/dockview-core/src/splitview/splitviewPanel.ts
+++ b/packages/dockview-core/src/splitview/splitviewPanel.ts
@@ -7,6 +7,7 @@ import { SplitviewPanelApiImpl } from '../api/splitviewPanelApi';
import { LayoutPriority, Orientation } from './splitview';
import { FunctionOrValue } from '../types';
import { Emitter, Event } from '../events';
+import { CompositeDisposable } from '../lifecycle';
export interface ISplitviewPanel
extends BasePanelViewExported {
From 78eac85c6814aef62ed997a9242c8fab9ada20f1 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Mon, 5 Jun 2023 20:24:04 +0100
Subject: [PATCH 09/23] bug: title is deleted when updateParameters() is called
with no title
---
package.json | 5 +-
.../__mocks__/mockDockviewPanelMode.ts | 11 +-
.../src/__tests__/api/api.spec.ts | 25 ++++-
.../__tests__/api/dockviewPanelApi.spec.ts | 36 ++++++-
.../__tests__/dockview/dockviewPanel.spec.ts | 70 +++++++++++-
.../src/__tests__/events.spec.ts | 4 +
.../groupview/dockviewGroupPanelModel.spec.ts | 7 +-
.../dockview-core/src/api/dockviewPanelApi.ts | 2 +-
packages/dockview-core/src/api/panelApi.ts | 4 +-
.../src/dockview/dockviewPanel.ts | 30 +++---
.../src/dockview/dockviewPanelModel.ts | 6 +-
packages/dockview-core/src/dockview/types.ts | 12 +--
packages/dockview-core/src/events.ts | 8 +-
.../src/gridview/basePanelView.ts | 13 +++
packages/dockview/jest.config.ts | 1 +
.../src/__tests__/dockview/dockview.spec.tsx | 96 ++++++++++++++++-
.../src/__tests__/gridview/gridview.spec.tsx | 100 +++++++++++++++++-
.../src/__tests__/paneview/paneview.spec.tsx | 97 ++++++++++++++++-
.../react/dockview/dockview.spec.tsx | 53 ----------
.../dockview/groupControlsRenderer.spec.ts | 58 ----------
.../react/gridview/gridview.spec.tsx | 64 -----------
.../react/paneview/paneview.spec.tsx | 52 ---------
.../src/__tests__/react/react.spec.tsx | 90 ----------------
.../react/splitview/splitview.spec.tsx | 64 -----------
.../__tests__/splitview/splitview.spec.tsx | 100 +++++++++++++++++-
packages/docs/docs/components/dockview.mdx | 34 ++++++
yarn.lock | 69 +++++++++++-
27 files changed, 664 insertions(+), 447 deletions(-)
delete mode 100644 packages/dockview/src/__tests__/react/dockview/dockview.spec.tsx
delete mode 100644 packages/dockview/src/__tests__/react/dockview/groupControlsRenderer.spec.ts
delete mode 100644 packages/dockview/src/__tests__/react/gridview/gridview.spec.tsx
delete mode 100644 packages/dockview/src/__tests__/react/paneview/paneview.spec.tsx
delete mode 100644 packages/dockview/src/__tests__/react/react.spec.tsx
delete mode 100644 packages/dockview/src/__tests__/react/splitview/splitview.spec.tsx
diff --git a/package.json b/package.json
index 3148b38c4..114afaa58 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
"homepage": "https://github.com/mathuo/dockview#readme",
"devDependencies": {
"@testing-library/dom": "^8.20.0",
+ "@testing-library/jest-dom": "^5.16.5",
"@types/jest": "^29.4.0",
"@typescript-eslint/eslint-plugin": "^5.52.0",
"@typescript-eslint/parser": "^5.52.0",
@@ -58,8 +59,8 @@
"style-loader": "^3.3.1",
"ts-jest": "^29.0.5",
"ts-loader": "^9.4.2",
- "tslib": "^2.5.0",
"ts-node": "^10.9.1",
+ "tslib": "^2.5.0",
"typedoc": "^0.24.7",
"typescript": "^4.9.5",
"webpack": "^5.75.0",
@@ -67,4 +68,4 @@
"webpack-dev-server": "^4.11.1"
},
"dependencies": {}
-}
\ No newline at end of file
+}
diff --git a/packages/dockview-core/src/__tests__/__mocks__/mockDockviewPanelMode.ts b/packages/dockview-core/src/__tests__/__mocks__/mockDockviewPanelMode.ts
index 0d788620e..a1e3397dd 100644
--- a/packages/dockview-core/src/__tests__/__mocks__/mockDockviewPanelMode.ts
+++ b/packages/dockview-core/src/__tests__/__mocks__/mockDockviewPanelMode.ts
@@ -2,10 +2,10 @@ import { IDockviewPanelModel } from '../../dockview/dockviewPanelModel';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
import {
GroupPanelPartInitParameters,
- GroupPanelUpdateEvent,
IContentRenderer,
ITabRenderer,
} from '../../dockview/types';
+import { PanelUpdateEvent } from '../../panel/types';
export class DockviewPanelModelMock implements IDockviewPanelModel {
constructor(
@@ -21,7 +21,14 @@ export class DockviewPanelModelMock implements IDockviewPanelModel {
//
}
- update(event: GroupPanelUpdateEvent): void {
+ updateParentGroup(
+ group: DockviewGroupPanel,
+ isPanelVisible: boolean
+ ): void {
+ //
+ }
+
+ update(event: PanelUpdateEvent): void {
//
}
diff --git a/packages/dockview-core/src/__tests__/api/api.spec.ts b/packages/dockview-core/src/__tests__/api/api.spec.ts
index 10f9bc657..5b40a6aa9 100644
--- a/packages/dockview-core/src/__tests__/api/api.spec.ts
+++ b/packages/dockview-core/src/__tests__/api/api.spec.ts
@@ -1,4 +1,5 @@
import { PanelApiImpl } from '../../api/panelApi';
+import { IPanel } from '../../panel/types';
describe('api', () => {
let api: PanelApiImpl;
@@ -7,7 +8,23 @@ describe('api', () => {
api = new PanelApiImpl('dummy_id');
});
- it('should update isFcoused getter', () => {
+ test('updateParameters', () => {
+ const panel = {
+ update: jest.fn(),
+ } as Partial;
+
+ api.initialize(panel as IPanel);
+
+ expect(panel.update).toHaveBeenCalledTimes(0);
+
+ api.updateParameters({ keyA: 'valueA' });
+ expect(panel.update).toHaveBeenCalledTimes(1);
+ expect(panel.update).toHaveBeenCalledWith({
+ params: { keyA: 'valueA' },
+ });
+ });
+
+ test('should update isFcoused getter', () => {
expect(api.isFocused).toBeFalsy();
api._onDidChangeFocus.fire({ isFocused: true });
@@ -17,7 +34,7 @@ describe('api', () => {
expect(api.isFocused).toBeFalsy();
});
- it('should update isActive getter', () => {
+ test('should update isActive getter', () => {
expect(api.isFocused).toBeFalsy();
api._onDidActiveChange.fire({ isActive: true });
@@ -27,7 +44,7 @@ describe('api', () => {
expect(api.isActive).toBeFalsy();
});
- it('should update isActive getter', () => {
+ test('should update isActive getter', () => {
expect(api.isVisible).toBeTruthy();
api._onDidVisibilityChange.fire({ isVisible: false });
@@ -37,7 +54,7 @@ describe('api', () => {
expect(api.isVisible).toBeTruthy();
});
- it('should update width and height getter', () => {
+ test('should update width and height getter', () => {
expect(api.height).toBe(0);
expect(api.width).toBe(0);
diff --git a/packages/dockview-core/src/__tests__/api/dockviewPanelApi.spec.ts b/packages/dockview-core/src/__tests__/api/dockviewPanelApi.spec.ts
index 243a2f4d1..1226b6cb2 100644
--- a/packages/dockview-core/src/__tests__/api/dockviewPanelApi.spec.ts
+++ b/packages/dockview-core/src/__tests__/api/dockviewPanelApi.spec.ts
@@ -1,4 +1,4 @@
-import { DockviewPanelApiImpl, TitleEvent } from '../../api/dockviewPanelApi';
+import { DockviewPanelApiImpl } from '../../api/dockviewPanelApi';
import { DockviewComponent } from '../../dockview/dockviewComponent';
import { DockviewPanel, IDockviewPanel } from '../../dockview/dockviewPanel';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
@@ -8,6 +8,7 @@ describe('groupPanelApi', () => {
const panelMock = jest.fn(() => {
return {
update: jest.fn(),
+ setTitle: jest.fn(),
} as any;
});
const groupMock = jest.fn(() => {
@@ -20,11 +21,38 @@ describe('groupPanelApi', () => {
const cut = new DockviewPanelApiImpl(panel, group);
cut.setTitle('test_title');
+ expect(panel.setTitle).toBeCalledTimes(1);
+ expect(panel.setTitle).toBeCalledWith('test_title');
+ });
- expect(panel.update).toBeCalledTimes(1);
- expect(panel.update).toBeCalledWith({
- params: { title: 'test_title' },
+ test('updateParameters', () => {
+ const groupPanel: Partial = {
+ id: 'test_id',
+ update: jest.fn(),
+ };
+
+ const accessor: Partial = {
+ onDidAddPanel: jest.fn(),
+ onDidRemovePanel: jest.fn(),
+ options: {},
+ };
+ const groupViewPanel = new DockviewGroupPanel(
+ accessor,
+ '',
+ {}
+ );
+
+ const cut = new DockviewPanelApiImpl(
+ groupPanel,
+ groupViewPanel
+ );
+
+ cut.updateParameters({ keyA: 'valueA' });
+
+ expect(groupPanel.update).toHaveBeenCalledWith({
+ params: { keyA: 'valueA' },
});
+ expect(groupPanel.update).toHaveBeenCalledTimes(1);
});
test('onDidGroupChange', () => {
diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewPanel.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewPanel.spec.ts
index d87ac438b..c67546db8 100644
--- a/packages/dockview-core/src/__tests__/dockview/dockviewPanel.spec.ts
+++ b/packages/dockview-core/src/__tests__/dockview/dockviewPanel.spec.ts
@@ -43,7 +43,7 @@ describe('dockviewPanel', () => {
expect(latestTitle).toBe('new title');
expect(cut.title).toBe('new title');
- cut.update({ params: { title: 'another title' } });
+ cut.setTitle('another title');
expect(latestTitle).toBe('another title');
expect(cut.title).toBe('another title');
@@ -81,6 +81,9 @@ describe('dockviewPanel', () => {
cut.setTitle('newTitle');
expect(cut.title).toBe('newTitle');
+
+ cut.api.setTitle('new title 2');
+ expect(cut.title).toBe('new title 2');
});
test('dispose cleanup', () => {
@@ -142,7 +145,7 @@ describe('dockviewPanel', () => {
expect(cut.params).toEqual(undefined);
- cut.update({ params: { params: { variableA: 'A', variableB: 'B' } } });
+ cut.update({ params: { variableA: 'A', variableB: 'B' } });
expect(cut.params).toEqual({ variableA: 'A', variableB: 'B' });
});
@@ -181,4 +184,67 @@ describe('dockviewPanel', () => {
expect(group.api.setSize).toBeCalledWith({ height: 123, width: 456 });
expect(group.api.setSize).toBeCalledTimes(1);
});
+
+ test('updateParameter', () => {
+ const dockviewApiMock = jest.fn(() => {
+ return {} as any;
+ });
+ const accessorMock = jest.fn(() => {
+ return {} as any;
+ });
+ const groupMock = jest.fn(() => {
+ return {} as any;
+ });
+ const panelModelMock = jest.fn, []>(() => {
+ return {
+ update: jest.fn(),
+ init: jest.fn(),
+ dispose: jest.fn(),
+ };
+ });
+
+ const api = new dockviewApiMock();
+ const accessor = new accessorMock();
+ const group = new groupMock();
+ const model = new panelModelMock();
+
+ const cut = new DockviewPanel('fake-id', accessor, api, group, model);
+
+ cut.init({ params: { a: '1', b: '2' }, title: 'A title' });
+ expect(cut.params).toEqual({ a: '1', b: '2' });
+
+ // update 'a' and add 'c'
+ cut.update({ params: { a: '-1', c: '3' } });
+ expect(cut.params).toEqual({ a: '-1', b: '2', c: '3' });
+
+ cut.update({ params: { d: '4', e: '5', f: '6' } });
+ expect(cut.params).toEqual({
+ a: '-1',
+ b: '2',
+ c: '3',
+ d: '4',
+ e: '5',
+ f: '6',
+ });
+
+ cut.update({
+ params: {
+ d: '',
+ e: null,
+ f: undefined,
+ g: '',
+ h: null,
+ i: undefined,
+ },
+ });
+ expect(cut.params).toEqual({
+ a: '-1',
+ b: '2',
+ c: '3',
+ d: '',
+ e: null,
+ g: '',
+ h: null,
+ });
+ });
});
diff --git a/packages/dockview-core/src/__tests__/events.spec.ts b/packages/dockview-core/src/__tests__/events.spec.ts
index 69790cee4..6ac17cc5c 100644
--- a/packages/dockview-core/src/__tests__/events.spec.ts
+++ b/packages/dockview-core/src/__tests__/events.spec.ts
@@ -2,6 +2,10 @@ import { Emitter, Event } from '../events';
describe('events', () => {
describe('emitter', () => {
+ it('debug mode is off', () => {
+ expect(Emitter.ENABLE_TRACKING).toBeFalsy();
+ });
+
it('should emit values', () => {
const emitter = new Emitter();
let value: number | undefined = undefined;
diff --git a/packages/dockview-core/src/__tests__/groupview/dockviewGroupPanelModel.spec.ts b/packages/dockview-core/src/__tests__/groupview/dockviewGroupPanelModel.spec.ts
index b00522d05..249167341 100644
--- a/packages/dockview-core/src/__tests__/groupview/dockviewGroupPanelModel.spec.ts
+++ b/packages/dockview-core/src/__tests__/groupview/dockviewGroupPanelModel.spec.ts
@@ -1,6 +1,5 @@
import { DockviewComponent } from '../../dockview/dockviewComponent';
import {
- GroupPanelUpdateEvent,
GroupviewPanelState,
IGroupPanelInitParameters,
GroupPanelPartInitParameters,
@@ -39,7 +38,7 @@ class TestModel implements IDockviewPanelModel {
this.tab = new TestContentPart(id);
}
- update(event: GroupPanelUpdateEvent): void {
+ update(event: PanelUpdateEvent): void {
//
}
@@ -203,6 +202,10 @@ export class TestPanel implements IDockviewPanel {
//noop
}
+ setTitle(title: string): void {
+ //
+ }
+
update(event: PanelUpdateEvent) {
//noop
}
diff --git a/packages/dockview-core/src/api/dockviewPanelApi.ts b/packages/dockview-core/src/api/dockviewPanelApi.ts
index d42ac65a4..5c6222071 100644
--- a/packages/dockview-core/src/api/dockviewPanelApi.ts
+++ b/packages/dockview-core/src/api/dockviewPanelApi.ts
@@ -89,7 +89,7 @@ export class DockviewPanelApiImpl
}
public setTitle(title: string): void {
- this.panel.update({ params: { title } });
+ this.panel.setTitle(title);
}
public close(): void {
diff --git a/packages/dockview-core/src/api/panelApi.ts b/packages/dockview-core/src/api/panelApi.ts
index 795ac1589..95d35a3b8 100644
--- a/packages/dockview-core/src/api/panelApi.ts
+++ b/packages/dockview-core/src/api/panelApi.ts
@@ -155,9 +155,7 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
this.panelUpdatesDisposable.value = this._onUpdateParameters.event(
(parameters) => {
panel.update({
- params: {
- params: parameters,
- },
+ params: parameters,
});
}
);
diff --git a/packages/dockview-core/src/dockview/dockviewPanel.ts b/packages/dockview-core/src/dockview/dockviewPanel.ts
index cc34b1545..4f67933fc 100644
--- a/packages/dockview-core/src/dockview/dockviewPanel.ts
+++ b/packages/dockview-core/src/dockview/dockviewPanel.ts
@@ -3,14 +3,10 @@ import {
DockviewPanelApi,
DockviewPanelApiImpl,
} from '../api/dockviewPanelApi';
-import {
- GroupPanelUpdateEvent,
- GroupviewPanelState,
- IGroupPanelInitParameters,
-} from './types';
+import { GroupviewPanelState, IGroupPanelInitParameters } from './types';
import { DockviewGroupPanel } from './dockviewGroupPanel';
import { CompositeDisposable, IDisposable } from '../lifecycle';
-import { IPanel, Parameters } from '../panel/types';
+import { IPanel, PanelUpdateEvent, Parameters } from '../panel/types';
import { IDockviewPanelModel } from './dockviewPanelModel';
import { IDockviewComponent } from './dockviewComponent';
@@ -23,7 +19,8 @@ export interface IDockviewPanel extends IDisposable, IPanel {
updateParentGroup(group: DockviewGroupPanel, isGroupActive: boolean): void;
init(params: IGroupPanelInitParameters): void;
toJSON(): GroupviewPanelState;
- update(event: GroupPanelUpdateEvent): void;
+ setTitle(title: string): void;
+ update(event: PanelUpdateEvent): void;
}
export class DockviewPanel
@@ -117,19 +114,24 @@ export class DockviewPanel
}
}
- public update(event: GroupPanelUpdateEvent): void {
- const params = event.params as IGroupPanelInitParameters;
-
+ public update(event: PanelUpdateEvent): void {
+ // merge the new parameters with the existing parameters
this._params = {
...(this._params || {}),
- ...event.params.params,
+ ...event.params,
};
- if (params.title !== this.title) {
- this._title = params.title;
- this.api._onDidTitleChange.fire({ title: params.title });
+ /**
+ * delete new keys that have a value of undefined,
+ * allow values of null
+ */
+ for (const key of Object.keys(event.params)) {
+ if (event.params[key] === undefined) {
+ delete this._params[key];
+ }
}
+ // update the view with the updated props
this.view.update({
params: {
params: this._params,
diff --git a/packages/dockview-core/src/dockview/dockviewPanelModel.ts b/packages/dockview-core/src/dockview/dockviewPanelModel.ts
index b29bcd12c..44461f6a2 100644
--- a/packages/dockview-core/src/dockview/dockviewPanelModel.ts
+++ b/packages/dockview-core/src/dockview/dockviewPanelModel.ts
@@ -3,19 +3,19 @@ import {
GroupPanelPartInitParameters,
IContentRenderer,
ITabRenderer,
- GroupPanelUpdateEvent,
} from './types';
import { DockviewGroupPanel } from './dockviewGroupPanel';
import { IDisposable } from '../lifecycle';
import { createComponent } from '../panel/componentFactory';
import { IDockviewComponent } from './dockviewComponent';
+import { PanelUpdateEvent } from '../panel/types';
export interface IDockviewPanelModel extends IDisposable {
readonly contentComponent: string;
readonly tabComponent?: string;
readonly content: IContentRenderer;
readonly tab?: ITabRenderer;
- update(event: GroupPanelUpdateEvent): void;
+ update(event: PanelUpdateEvent): void;
layout(width: number, height: number): void;
init(params: GroupPanelPartInitParameters): void;
updateParentGroup(group: DockviewGroupPanel, isPanelVisible: boolean): void;
@@ -80,7 +80,7 @@ export class DockviewPanelModel implements IDockviewPanelModel {
this.content.layout?.(width, height);
}
- update(event: GroupPanelUpdateEvent): void {
+ update(event: PanelUpdateEvent): void {
this.content.update?.(event);
this.tab.update?.(event);
}
diff --git a/packages/dockview-core/src/dockview/types.ts b/packages/dockview-core/src/dockview/types.ts
index 107da33ed..7d870746c 100644
--- a/packages/dockview-core/src/dockview/types.ts
+++ b/packages/dockview-core/src/dockview/types.ts
@@ -1,11 +1,6 @@
import { IDockviewComponent } from './dockviewComponent';
import { DockviewPanelApi } from '../api/dockviewPanelApi';
-import {
- PanelInitParameters,
- IPanel,
- PanelUpdateEvent,
- Parameters,
-} from '../panel/types';
+import { PanelInitParameters, IPanel } from '../panel/types';
import { DockviewApi } from '../api/component.api';
import { Event } from '../events';
import { Optional } from '../types';
@@ -91,11 +86,6 @@ export interface IGroupPanelInitParameters
//
}
-export type GroupPanelUpdateEvent = PanelUpdateEvent<{
- params?: Parameters;
- title?: string;
-}>;
-
export interface GroupviewPanelState {
id: string;
contentComponent?: string;
diff --git a/packages/dockview-core/src/events.ts b/packages/dockview-core/src/events.ts
index 13b8b3382..91f27a1b1 100644
--- a/packages/dockview-core/src/events.ts
+++ b/packages/dockview-core/src/events.ts
@@ -102,10 +102,10 @@ export class Emitter implements IDisposable {
if (index > -1) {
this._listeners.splice(index, 1);
} else if (Emitter.ENABLE_TRACKING) {
- console.warn(
- `Listener already disposed`,
- Stacktrace.create().print()
- );
+ // console.warn(
+ // `Listener already disposed`,
+ // Stacktrace.create().print()
+ // );
}
},
};
diff --git a/packages/dockview-core/src/gridview/basePanelView.ts b/packages/dockview-core/src/gridview/basePanelView.ts
index f61473864..4244fef36 100644
--- a/packages/dockview-core/src/gridview/basePanelView.ts
+++ b/packages/dockview-core/src/gridview/basePanelView.ts
@@ -104,6 +104,7 @@ export abstract class BasePanelView
}
update(event: PanelUpdateEvent): void {
+ // merge the new parameters with the existing parameters
this._params = {
...this._params,
params: {
@@ -111,6 +112,18 @@ export abstract class BasePanelView
...event.params,
},
};
+
+ /**
+ * delete new keys that have a value of undefined,
+ * allow values of null
+ */
+ for (const key of Object.keys(event.params)) {
+ if (event.params[key] === undefined) {
+ delete this._params.params[key];
+ }
+ }
+
+ // update the view with the updated props
this.part?.update({ params: this._params.params });
}
diff --git a/packages/dockview/jest.config.ts b/packages/dockview/jest.config.ts
index b909c68ef..5d952690f 100644
--- a/packages/dockview/jest.config.ts
+++ b/packages/dockview/jest.config.ts
@@ -15,6 +15,7 @@ const config: JestConfigWithTsJest = {
setupFiles: [
'/packages/dockview/src/__tests__/__mocks__/resizeObserver.js',
],
+ setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
coveragePathIgnorePatterns: ['/node_modules/'],
modulePathIgnorePatterns: [
'/packages/dockview/src/__tests__/__mocks__',
diff --git a/packages/dockview/src/__tests__/dockview/dockview.spec.tsx b/packages/dockview/src/__tests__/dockview/dockview.spec.tsx
index 6fe0872a7..72e1feec5 100644
--- a/packages/dockview/src/__tests__/dockview/dockview.spec.tsx
+++ b/packages/dockview/src/__tests__/dockview/dockview.spec.tsx
@@ -1,6 +1,6 @@
import * as React from 'react';
-import { render } from '@testing-library/react';
-import { DockviewApi } from 'dockview-core';
+import { act, render, waitFor } from '@testing-library/react';
+import { DockviewApi, IDockviewPanel } from 'dockview-core';
import {
IDockviewPanelProps,
DockviewReact,
@@ -15,7 +15,17 @@ describe('gridview react', () => {
beforeEach(() => {
components = {
default: (props: IDockviewPanelProps) => {
- return hello world
;
+ return (
+
+ {Object.keys(props.params).map((key) => {
+ return (
+
{`key=${key},value=${props.params[key]}`}
+ );
+ })}
+
+ );
},
};
});
@@ -51,4 +61,84 @@ describe('gridview react', () => {
expect(api!.width).toBe(650);
expect(api!.height).toBe(450);
});
+
+ test('that the component can update parameters', async () => {
+ let api: DockviewApi;
+
+ const onReady = (event: DockviewReadyEvent) => {
+ api = event.api;
+ };
+
+ const wrapper = render(
+
+ );
+
+ let panel: IDockviewPanel;
+
+ act(() => {
+ panel = api!.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ keyA: 'valueA',
+ keyB: 'valueB',
+ },
+ });
+ });
+
+ await waitFor(() => {
+ expect(
+ wrapper.queryByText(/key=keyA,value=valueA/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyB,value=valueB/i)
+ ).toBeInTheDocument();
+ });
+
+ act(() => {
+ panel.api.updateParameters({ keyA: 'valueAA', keyC: 'valueC' });
+ });
+
+ await waitFor(() => {
+ expect(
+ wrapper.queryByText(/key=keyA,value=valueAA/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyB,value=valueB/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyC,value=valueC/i)
+ ).toBeInTheDocument();
+ });
+
+ act(() => {
+ panel.api.updateParameters({ keyC: null });
+ });
+
+ await waitFor(() => {
+ expect(
+ wrapper.queryByText(/key=keyA,value=valueAA/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyB,value=valueB/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyC,value=null/i)
+ ).toBeInTheDocument();
+ });
+
+ act(() => {
+ panel.api.updateParameters({ keyA: undefined });
+ });
+
+ await waitFor(() => {
+ expect(wrapper.queryByText(/key=keyA/i)).not.toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyB,value=valueB/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyC,value=null/i)
+ ).toBeInTheDocument();
+ });
+ });
});
diff --git a/packages/dockview/src/__tests__/gridview/gridview.spec.tsx b/packages/dockview/src/__tests__/gridview/gridview.spec.tsx
index 0881e00b4..7fdce204c 100644
--- a/packages/dockview/src/__tests__/gridview/gridview.spec.tsx
+++ b/packages/dockview/src/__tests__/gridview/gridview.spec.tsx
@@ -1,6 +1,6 @@
import * as React from 'react';
-import { render } from '@testing-library/react';
-import { GridviewApi, Orientation } from 'dockview-core';
+import { act, render, waitFor } from '@testing-library/react';
+import { GridviewApi, IGridviewPanel, Orientation } from 'dockview-core';
import {
IGridviewPanelProps,
GridviewReact,
@@ -15,7 +15,17 @@ describe('gridview react', () => {
beforeEach(() => {
components = {
default: (props: IGridviewPanelProps) => {
- return hello world
;
+ return (
+
+ {Object.keys(props.params).map((key) => {
+ return (
+
{`key=${key},value=${props.params[key]}`}
+ );
+ })}
+
+ );
},
};
});
@@ -62,4 +72,88 @@ describe('gridview react', () => {
expect(api!.width).toBe(650);
expect(api!.height).toBe(450);
});
+
+ test('that the component can update parameters', async () => {
+ let api: GridviewApi;
+
+ const onReady = (event: GridviewReadyEvent) => {
+ api = event.api;
+ };
+
+ const wrapper = render(
+
+ );
+
+ let panel: IGridviewPanel;
+
+ act(() => {
+ panel = api!.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ keyA: 'valueA',
+ keyB: 'valueB',
+ },
+ });
+ });
+
+ await waitFor(() => {
+ expect(
+ wrapper.queryByText(/key=keyA,value=valueA/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyB,value=valueB/i)
+ ).toBeInTheDocument();
+ });
+
+ act(() => {
+ panel.api.updateParameters({ keyA: 'valueAA', keyC: 'valueC' });
+ });
+
+ await waitFor(() => {
+ expect(
+ wrapper.queryByText(/key=keyA,value=valueAA/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyB,value=valueB/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyC,value=valueC/i)
+ ).toBeInTheDocument();
+ });
+
+ act(() => {
+ panel.api.updateParameters({ keyC: null });
+ });
+
+ await waitFor(() => {
+ expect(
+ wrapper.queryByText(/key=keyA,value=valueAA/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyB,value=valueB/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyC,value=null/i)
+ ).toBeInTheDocument();
+ });
+
+ act(() => {
+ panel.api.updateParameters({ keyA: undefined });
+ });
+
+ await waitFor(() => {
+ expect(wrapper.queryByText(/key=keyA/i)).not.toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyB,value=valueB/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyC,value=null/i)
+ ).toBeInTheDocument();
+ });
+ });
});
diff --git a/packages/dockview/src/__tests__/paneview/paneview.spec.tsx b/packages/dockview/src/__tests__/paneview/paneview.spec.tsx
index 830861e89..53be8476a 100644
--- a/packages/dockview/src/__tests__/paneview/paneview.spec.tsx
+++ b/packages/dockview/src/__tests__/paneview/paneview.spec.tsx
@@ -1,6 +1,6 @@
import * as React from 'react';
-import { render } from '@testing-library/react';
-import { PaneviewApi } from 'dockview-core';
+import { act, render, waitFor } from '@testing-library/react';
+import { IPaneviewPanel, PaneviewApi } from 'dockview-core';
import {
IPaneviewPanelProps,
PaneviewReact,
@@ -15,7 +15,17 @@ describe('gridview react', () => {
beforeEach(() => {
components = {
default: (props: IPaneviewPanelProps) => {
- return hello world
;
+ return (
+
+ {Object.keys(props.params).map((key) => {
+ return (
+
{`key=${key},value=${props.params[key]}`}
+ );
+ })}
+
+ );
},
};
});
@@ -49,4 +59,85 @@ describe('gridview react', () => {
expect(api!.width).toBe(650);
expect(api!.height).toBe(450);
});
+
+ test('that the component can update parameters', async () => {
+ let api: PaneviewApi;
+
+ const onReady = (event: PaneviewReadyEvent) => {
+ api = event.api;
+ };
+
+ const wrapper = render(
+
+ );
+
+ let panel: IPaneviewPanel;
+
+ act(() => {
+ panel = api!.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ title: 'Panel 1',
+ params: {
+ keyA: 'valueA',
+ keyB: 'valueB',
+ },
+ });
+ });
+
+ await waitFor(() => {
+ expect(
+ wrapper.queryByText(/key=keyA,value=valueA/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyB,value=valueB/i)
+ ).toBeInTheDocument();
+ });
+
+ act(() => {
+ panel.api.updateParameters({ keyA: 'valueAA', keyC: 'valueC' });
+ });
+
+ await waitFor(() => {
+ expect(
+ wrapper.queryByText(/key=keyA,value=valueAA/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyB,value=valueB/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyC,value=valueC/i)
+ ).toBeInTheDocument();
+ });
+
+ act(() => {
+ panel.api.updateParameters({ keyC: null });
+ });
+
+ await waitFor(() => {
+ expect(
+ wrapper.queryByText(/key=keyA,value=valueAA/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyB,value=valueB/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyC,value=null/i)
+ ).toBeInTheDocument();
+ });
+
+ act(() => {
+ panel.api.updateParameters({ keyA: undefined });
+ });
+
+ await waitFor(() => {
+ expect(wrapper.queryByText(/key=keyA/i)).not.toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyB,value=valueB/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyC,value=null/i)
+ ).toBeInTheDocument();
+ });
+ });
});
diff --git a/packages/dockview/src/__tests__/react/dockview/dockview.spec.tsx b/packages/dockview/src/__tests__/react/dockview/dockview.spec.tsx
deleted file mode 100644
index 12048cac5..000000000
--- a/packages/dockview/src/__tests__/react/dockview/dockview.spec.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import * as React from 'react';
-import { render } from '@testing-library/react';
-import { DockviewApi } from 'dockview-core';
-import {
- IDockviewPanelProps,
- DockviewReact,
- DockviewReadyEvent,
-} from '../../../dockview/dockview';
-import { PanelCollection } from '../../../types';
-import { setMockRefElement } from '../../__test_utils__/utils';
-
-describe('dockview', () => {
- let components: PanelCollection;
-
- beforeEach(() => {
- components = {
- default: (props: IDockviewPanelProps) => {
- return hello world
;
- },
- };
- });
-
- test('default', () => {
- let api: DockviewApi | undefined;
-
- const onReady = (event: DockviewReadyEvent) => {
- api = event.api;
- };
-
- render();
-
- expect(api).toBeTruthy();
- });
-
- test('is sized to container', () => {
- const el = document.createElement('div') as any;
- jest.spyOn(el, 'clientHeight', 'get').mockReturnValue(450);
- jest.spyOn(el, 'clientWidth', 'get').mockReturnValue(650);
-
- setMockRefElement(el);
-
- let api: DockviewApi | undefined;
-
- const onReady = (event: DockviewReadyEvent) => {
- api = event.api;
- };
-
- render();
-
- expect(api!.width).toBe(650);
- expect(api!.height).toBe(450);
- });
-});
diff --git a/packages/dockview/src/__tests__/react/dockview/groupControlsRenderer.spec.ts b/packages/dockview/src/__tests__/react/dockview/groupControlsRenderer.spec.ts
deleted file mode 100644
index d3a056372..000000000
--- a/packages/dockview/src/__tests__/react/dockview/groupControlsRenderer.spec.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import {
- DockviewGroupPanel,
- DockviewGroupPanelApi,
- DockviewGroupPanelModel,
-} from 'dockview-core';
-import { ReactGroupControlsRendererPart } from '../../../dockview/groupControlsRenderer';
-
-describe('groupControlsRenderer', () => {
- test('#1', () => {
- const groupviewMock = jest.fn, []>(
- () => {
- return {
- onDidAddPanel: jest.fn(),
- onDidRemovePanel: jest.fn(),
- onDidActivePanelChange: jest.fn(),
- };
- }
- );
-
- const groupview = new groupviewMock() as DockviewGroupPanelModel;
-
- const groupPanelMock = jest.fn, []>(() => {
- return {
- api: {} as DockviewGroupPanelApi as any,
- model: groupview,
- };
- });
-
- const groupPanel = new groupPanelMock() as DockviewGroupPanel;
-
- const cut = new ReactGroupControlsRendererPart(
- jest.fn(),
- {
- addPortal: jest.fn(),
- },
- groupPanel
- );
-
- expect(cut.element.childNodes.length).toBe(0);
- expect(cut.element.className).toBe('dockview-react-part');
- expect(cut.part).toBeUndefined();
-
- cut.init({
- containerApi: jest.fn(),
- api: {
- onDidActiveChange: jest.fn(),
- },
- });
-
- const update = jest.fn();
-
- jest.spyOn(cut.part!, 'update').mockImplementation(update);
-
- cut.update({ params: { valueA: 'A' } });
-
- expect(update).toBeCalledWith({ valueA: 'A' });
- });
-});
diff --git a/packages/dockview/src/__tests__/react/gridview/gridview.spec.tsx b/packages/dockview/src/__tests__/react/gridview/gridview.spec.tsx
deleted file mode 100644
index 5e5ff70e9..000000000
--- a/packages/dockview/src/__tests__/react/gridview/gridview.spec.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import * as React from 'react';
-import { render } from '@testing-library/react';
-import { GridviewApi, Orientation } from 'dockview-core';
-import {
- IGridviewPanelProps,
- GridviewReact,
- GridviewReadyEvent,
-} from '../../../gridview/gridview';
-import { PanelCollection } from '../../../types';
-import { setMockRefElement } from '../../__test_utils__/utils';
-
-describe('gridview react', () => {
- let components: PanelCollection;
-
- beforeEach(() => {
- components = {
- default: (props: IGridviewPanelProps) => {
- return hello world
;
- },
- };
- });
-
- test('default', () => {
- let api: GridviewApi | undefined;
-
- const onReady = (event: GridviewReadyEvent) => {
- api = event.api;
- };
-
- render(
-
- );
-
- expect(api).toBeTruthy();
- });
-
- test('is sized to container', () => {
- setMockRefElement({
- clientHeight: 450,
- clientWidth: 650,
- appendChild: jest.fn(),
- });
- let api: GridviewApi | undefined;
-
- const onReady = (event: GridviewReadyEvent) => {
- api = event.api;
- };
-
- render(
-
- );
-
- expect(api!.width).toBe(650);
- expect(api!.height).toBe(450);
- });
-});
diff --git a/packages/dockview/src/__tests__/react/paneview/paneview.spec.tsx b/packages/dockview/src/__tests__/react/paneview/paneview.spec.tsx
deleted file mode 100644
index 4dc8b8198..000000000
--- a/packages/dockview/src/__tests__/react/paneview/paneview.spec.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import * as React from 'react';
-import { render } from '@testing-library/react';
-import { PaneviewApi } from 'dockview-core';
-import {
- IPaneviewPanelProps,
- PaneviewReact,
- PaneviewReadyEvent,
-} from '../../../paneview/paneview';
-import { PanelCollection } from '../../../types';
-import { setMockRefElement } from '../../__test_utils__/utils';
-
-describe('gridview react', () => {
- let components: PanelCollection;
-
- beforeEach(() => {
- components = {
- default: (props: IPaneviewPanelProps) => {
- return hello world
;
- },
- };
- });
-
- test('default', () => {
- let api: PaneviewApi | undefined;
-
- const onReady = (event: PaneviewReadyEvent) => {
- api = event.api;
- };
-
- render();
-
- expect(api).toBeTruthy();
- });
-
- test('is sized to container', () => {
- setMockRefElement({
- clientHeight: 450,
- clientWidth: 650,
- appendChild: jest.fn(),
- });
- let api: PaneviewApi | undefined;
-
- const onReady = (event: PaneviewReadyEvent) => {
- api = event.api;
- };
-
- render();
-
- expect(api!.width).toBe(650);
- expect(api!.height).toBe(450);
- });
-});
diff --git a/packages/dockview/src/__tests__/react/react.spec.tsx b/packages/dockview/src/__tests__/react/react.spec.tsx
deleted file mode 100644
index b89d09d74..000000000
--- a/packages/dockview/src/__tests__/react/react.spec.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-import { ReactPart } from '../../react';
-import * as React from 'react';
-import { render, screen, act } from '@testing-library/react';
-
-interface TestInterface {
- valueA: string;
- valueB: number;
-}
-
-describe('react', () => {
- describe('ReactPart', () => {
- test('update underlying component via ReactPart class', () => {
- let api: ReactPart;
-
- const onReady = (_api: ReactPart) => {
- api = _api;
- };
-
- render();
-
- expect(api!).toBeTruthy();
-
- expect(screen.getByTestId('valueA').textContent).toBe('stringA');
- expect(screen.getByTestId('valueB').textContent).toBe('42');
-
- act(() => {
- api.update({ valueB: '32' });
- });
-
- expect(screen.getByTestId('valueA').textContent).toBe('stringA');
- expect(screen.getByTestId('valueB').textContent).toBe('32');
-
- act(() => {
- api.update({ valueA: 'anotherStringA', valueB: '22' });
- });
-
- expect(screen.getByTestId('valueA').textContent).toBe(
- 'anotherStringA'
- );
- expect(screen.getByTestId('valueB').textContent).toBe('22');
- });
- });
-});
-
-const Component = (props: TestInterface) => {
- return (
-
-
{props.valueA}
-
{props.valueB}
-
- );
-};
-
-const TestWrapper = (props: {
- component: React.FunctionComponent;
- onReady: (api: ReactPart) => void;
-}) => {
- const [portal, setPortal] = React.useState([]);
- const ref = React.useRef(null);
-
- React.useEffect(() => {
- const cut = new ReactPart(
- ref.current!,
- {
- addPortal: (portal: React.ReactPortal) => {
- setPortal((_) => [..._, portal]);
-
- return {
- dispose: () => {
- setPortal((_) => _.filter((_) => _ !== portal));
- },
- };
- },
- },
- props.component,
- {
- valueA: 'stringA',
- valueB: 42,
- }
- );
-
- props.onReady(cut);
-
- return () => {
- cut.dispose();
- };
- }, []);
-
- return {portal}
;
-};
diff --git a/packages/dockview/src/__tests__/react/splitview/splitview.spec.tsx b/packages/dockview/src/__tests__/react/splitview/splitview.spec.tsx
deleted file mode 100644
index 9ffc01974..000000000
--- a/packages/dockview/src/__tests__/react/splitview/splitview.spec.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import * as React from 'react';
-import { render } from '@testing-library/react';
-import { SplitviewApi, Orientation } from 'dockview-core';
-import {
- ISplitviewPanelProps,
- SplitviewReact,
- SplitviewReadyEvent,
-} from '../../../splitview/splitview';
-import { PanelCollection } from '../../../types';
-import { setMockRefElement } from '../../__test_utils__/utils';
-
-describe('splitview react', () => {
- let components: PanelCollection;
-
- beforeEach(() => {
- components = {
- default: (props: ISplitviewPanelProps) => {
- return hello world
;
- },
- };
- });
-
- test('default', () => {
- let api: SplitviewApi | undefined;
-
- const onReady = (event: SplitviewReadyEvent) => {
- api = event.api;
- };
-
- render(
-
- );
-
- expect(api).toBeTruthy();
- });
-
- test('is sized to container', () => {
- setMockRefElement({
- clientHeight: 450,
- clientWidth: 650,
- appendChild: jest.fn(),
- });
- let api: SplitviewApi | undefined;
-
- const onReady = (event: SplitviewReadyEvent) => {
- api = event.api;
- };
-
- render(
-
- );
-
- expect(api!.width).toBe(650);
- expect(api!.height).toBe(450);
- });
-});
diff --git a/packages/dockview/src/__tests__/splitview/splitview.spec.tsx b/packages/dockview/src/__tests__/splitview/splitview.spec.tsx
index 34e0027db..e85959656 100644
--- a/packages/dockview/src/__tests__/splitview/splitview.spec.tsx
+++ b/packages/dockview/src/__tests__/splitview/splitview.spec.tsx
@@ -1,6 +1,6 @@
import * as React from 'react';
-import { render } from '@testing-library/react';
-import { SplitviewApi, Orientation } from 'dockview-core';
+import { act, render, waitFor } from '@testing-library/react';
+import { SplitviewApi, Orientation, ISplitviewPanel } from 'dockview-core';
import {
ISplitviewPanelProps,
SplitviewReact,
@@ -15,7 +15,17 @@ describe('splitview react', () => {
beforeEach(() => {
components = {
default: (props: ISplitviewPanelProps) => {
- return hello world
;
+ return (
+
+ {Object.keys(props.params).map((key) => {
+ return (
+
{`key=${key},value=${props.params[key]}`}
+ );
+ })}
+
+ );
},
};
});
@@ -61,4 +71,88 @@ describe('splitview react', () => {
expect(api!.width).toBe(650);
expect(api!.height).toBe(450);
});
+
+ test('that the component can update parameters', async () => {
+ let api: SplitviewApi;
+
+ const onReady = (event: SplitviewReadyEvent) => {
+ api = event.api;
+ };
+
+ const wrapper = render(
+
+ );
+
+ let panel: ISplitviewPanel;
+
+ act(() => {
+ panel = api!.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ keyA: 'valueA',
+ keyB: 'valueB',
+ },
+ });
+ });
+
+ await waitFor(() => {
+ expect(
+ wrapper.queryByText(/key=keyA,value=valueA/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyB,value=valueB/i)
+ ).toBeInTheDocument();
+ });
+
+ act(() => {
+ panel.api.updateParameters({ keyA: 'valueAA', keyC: 'valueC' });
+ });
+
+ await waitFor(() => {
+ expect(
+ wrapper.queryByText(/key=keyA,value=valueAA/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyB,value=valueB/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyC,value=valueC/i)
+ ).toBeInTheDocument();
+ });
+
+ act(() => {
+ panel.api.updateParameters({ keyC: null });
+ });
+
+ await waitFor(() => {
+ expect(
+ wrapper.queryByText(/key=keyA,value=valueAA/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyB,value=valueB/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyC,value=null/i)
+ ).toBeInTheDocument();
+ });
+
+ act(() => {
+ panel.api.updateParameters({ keyA: undefined });
+ });
+
+ await waitFor(() => {
+ expect(wrapper.queryByText(/key=keyA/i)).not.toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyB,value=valueB/i)
+ ).toBeInTheDocument();
+ expect(
+ wrapper.queryByText(/key=keyC,value=null/i)
+ ).toBeInTheDocument();
+ });
+ });
});
diff --git a/packages/docs/docs/components/dockview.mdx b/packages/docs/docs/components/dockview.mdx
index 835dee189..176f309db 100644
--- a/packages/docs/docs/components/dockview.mdx
+++ b/packages/docs/docs/components/dockview.mdx
@@ -435,6 +435,40 @@ const panel2 = api.addPanel({
});
```
+### Update Panel
+
+You can programatically update the `params` passed through to the panel through the panal api using `api.updateParameters`.
+
+```ts
+const panel = api.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ keyA: 'valueA',
+ },
+});
+
+// ...
+
+panel.api.updateParameters({
+ keyB: 'valueB',
+});
+
+// ...
+
+panel.api.updateParameters({
+ keyA: 'anotherValueA',
+});
+```
+
+To delete a parameter you should pass a value of `undefined` for the key.
+
+```ts
+panel.api.updateParameters({
+ keyA: undefined, // this will delete 'keyA'.
+});
+```
+
### Panel Rendering
By default `DockviewReact` only adds to the DOM those panels that are visible,
diff --git a/yarn.lock b/yarn.lock
index cf1e11427..f62c689a9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,6 +2,11 @@
# yarn lockfile v1
+"@adobe/css-tools@^4.0.1":
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.2.0.tgz#e1a84fca468f4b337816fcb7f0964beb620ba855"
+ integrity sha512-E09FiIft46CmH5Qnjb0wsW54/YQd69LsxeKUOWawmws1XWvyFGURnAChH0mlr7YPFR1ofwvUQfcL0J3lMxXqPA==
+
"@algolia/autocomplete-core@1.7.4":
version "1.7.4"
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.7.4.tgz#85ff36b2673654a393c8c505345eaedd6eaa4f70"
@@ -2888,6 +2893,21 @@
lz-string "^1.4.4"
pretty-format "^27.0.2"
+"@testing-library/jest-dom@^5.16.5":
+ version "5.16.5"
+ resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz#3912846af19a29b2dbf32a6ae9c31ef52580074e"
+ integrity sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA==
+ dependencies:
+ "@adobe/css-tools" "^4.0.1"
+ "@babel/runtime" "^7.9.2"
+ "@types/testing-library__jest-dom" "^5.9.1"
+ aria-query "^5.0.0"
+ chalk "^3.0.0"
+ css.escape "^1.5.1"
+ dom-accessibility-api "^0.5.6"
+ lodash "^4.17.15"
+ redent "^3.0.0"
+
"@testing-library/react@^13.4.0":
version "13.4.0"
resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-13.4.0.tgz#6a31e3bf5951615593ad984e96b9e5e2d9380966"
@@ -3107,6 +3127,14 @@
dependencies:
"@types/istanbul-lib-report" "*"
+"@types/jest@*":
+ version "29.5.2"
+ resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.2.tgz#86b4afc86e3a8f3005b297ed8a72494f89e6395b"
+ integrity sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg==
+ dependencies:
+ expect "^29.0.0"
+ pretty-format "^29.0.0"
+
"@types/jest@^29.4.0":
version "29.5.0"
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.0.tgz#337b90bbcfe42158f39c2fb5619ad044bbb518ac"
@@ -3292,6 +3320,13 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==
+"@types/testing-library__jest-dom@^5.9.1":
+ version "5.14.6"
+ resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.6.tgz#4887f6e1af11215428ab02777873bcede98a53b0"
+ integrity sha512-FkHXCb+ikSoUP4Y4rOslzTdX5sqYwMxfefKh1GmZ8ce1GOkEHntSp6b5cGadmNfp5e4BMEWOMx+WSKd5/MqlDA==
+ dependencies:
+ "@types/jest" "*"
+
"@types/tough-cookie@*":
version "4.0.2"
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.2.tgz#6286b4c7228d58ab7866d19716f3696e03a09397"
@@ -4659,6 +4694,14 @@ chalk@^2.0.0, chalk@^2.3.0:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
+chalk@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
+ integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
+ dependencies:
+ ansi-styles "^4.1.0"
+ supports-color "^7.1.0"
+
chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
@@ -5488,6 +5531,11 @@ css-what@^6.0.1, css-what@^6.1.0:
resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
+css.escape@^1.5.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb"
+ integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==
+
cssesc@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
@@ -5928,7 +5976,7 @@ docusaurus-plugin-sass@^0.2.3:
dependencies:
sass-loader "^10.1.1"
-dom-accessibility-api@^0.5.9:
+dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9:
version "0.5.16"
resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453"
integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==
@@ -9918,7 +9966,7 @@ markdown-escapes@^1.0.0:
resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535"
integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==
-marked@^4.3.0:
+marked@^4.2.12, marked@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3"
integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==
@@ -10136,6 +10184,13 @@ minimatch@^6.1.6:
dependencies:
brace-expansion "^2.0.1"
+minimatch@^7.1.3:
+ version "7.4.6"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.6.tgz#845d6f254d8f4a5e4fd6baf44d5f10c8448365fb"
+ integrity sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==
+ dependencies:
+ brace-expansion "^2.0.1"
+
minimatch@^7.4.1, minimatch@^7.4.2:
version "7.4.3"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.3.tgz#012cbf110a65134bb354ae9773b55256cdb045a2"
@@ -14256,6 +14311,16 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
+typedoc@^0.23.25:
+ version "0.23.28"
+ resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.23.28.tgz#3ce9c36ef1c273fa849d2dea18651855100d3ccd"
+ integrity sha512-9x1+hZWTHEQcGoP7qFmlo4unUoVJLB0H/8vfO/7wqTnZxg4kPuji9y3uRzEu0ZKez63OJAUmiGhUrtukC6Uj3w==
+ dependencies:
+ lunr "^2.3.9"
+ marked "^4.2.12"
+ minimatch "^7.1.3"
+ shiki "^0.14.1"
+
typedoc@^0.24.7:
version "0.24.7"
resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.24.7.tgz#7eeb272a1894b3789acc1a94b3f2ae8e7330ee39"
From d9906eb802e34ecd36ab719d032e281060bb9751 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Sat, 10 Jun 2023 11:38:41 +0100
Subject: [PATCH 10/23] chore: prepare v1.7.4
---
.../docs/blog/2023-06-14-dockview-1.7.4.md | 20 +++++++++++
.../basics.mdx | 0
.../components/_category_.json | 0
.../components/dockview.mdx | 34 +++++++++++++++++++
.../components/gridview.mdx | 0
.../components/paneview.mdx | 0
.../components/splitview.mdx | 0
.../index.mdx | 0
.../theme.mdx | 0
...ebars.json => version-1.7.4-sidebars.json} | 0
packages/docs/versions.json | 4 +--
11 files changed, 56 insertions(+), 2 deletions(-)
create mode 100644 packages/docs/blog/2023-06-14-dockview-1.7.4.md
rename packages/docs/versioned_docs/{version-1.7.3 => version-1.7.4}/basics.mdx (100%)
rename packages/docs/versioned_docs/{version-1.7.3 => version-1.7.4}/components/_category_.json (100%)
rename packages/docs/versioned_docs/{version-1.7.3 => version-1.7.4}/components/dockview.mdx (98%)
rename packages/docs/versioned_docs/{version-1.7.3 => version-1.7.4}/components/gridview.mdx (100%)
rename packages/docs/versioned_docs/{version-1.7.3 => version-1.7.4}/components/paneview.mdx (100%)
rename packages/docs/versioned_docs/{version-1.7.3 => version-1.7.4}/components/splitview.mdx (100%)
rename packages/docs/versioned_docs/{version-1.7.3 => version-1.7.4}/index.mdx (100%)
rename packages/docs/versioned_docs/{version-1.7.3 => version-1.7.4}/theme.mdx (100%)
rename packages/docs/versioned_sidebars/{version-1.7.3-sidebars.json => version-1.7.4-sidebars.json} (100%)
diff --git a/packages/docs/blog/2023-06-14-dockview-1.7.4.md b/packages/docs/blog/2023-06-14-dockview-1.7.4.md
new file mode 100644
index 000000000..6e8e2fe3f
--- /dev/null
+++ b/packages/docs/blog/2023-06-14-dockview-1.7.4.md
@@ -0,0 +1,20 @@
+---
+slug: dockview-1.7.4-release
+title: Dockview 1.7.4
+tags: [release]
+---
+
+# Release Notes
+
+Please reference to docs @ [dockview.dev](https://dockview.dev).
+
+## 🚀 Features
+
+- Improvements and tests added to the panel `api.updateParameters(...)` method [#265](https://github.com/mathuo/dockview/pull/265)
+
+## 🛠Miscs
+
+- Fix bug associated with overidding panel titles when using `api.updateParameters(...)` [#265](https://github.com/mathuo/dockview/pull/265)
+- Cleanup listeners and disposables after use [#257](https://github.com/mathuo/dockview/pull/257)
+
+## 🔥 Breaking changes
diff --git a/packages/docs/versioned_docs/version-1.7.3/basics.mdx b/packages/docs/versioned_docs/version-1.7.4/basics.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.3/basics.mdx
rename to packages/docs/versioned_docs/version-1.7.4/basics.mdx
diff --git a/packages/docs/versioned_docs/version-1.7.3/components/_category_.json b/packages/docs/versioned_docs/version-1.7.4/components/_category_.json
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.3/components/_category_.json
rename to packages/docs/versioned_docs/version-1.7.4/components/_category_.json
diff --git a/packages/docs/versioned_docs/version-1.7.3/components/dockview.mdx b/packages/docs/versioned_docs/version-1.7.4/components/dockview.mdx
similarity index 98%
rename from packages/docs/versioned_docs/version-1.7.3/components/dockview.mdx
rename to packages/docs/versioned_docs/version-1.7.4/components/dockview.mdx
index 835dee189..176f309db 100644
--- a/packages/docs/versioned_docs/version-1.7.3/components/dockview.mdx
+++ b/packages/docs/versioned_docs/version-1.7.4/components/dockview.mdx
@@ -435,6 +435,40 @@ const panel2 = api.addPanel({
});
```
+### Update Panel
+
+You can programatically update the `params` passed through to the panel through the panal api using `api.updateParameters`.
+
+```ts
+const panel = api.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ keyA: 'valueA',
+ },
+});
+
+// ...
+
+panel.api.updateParameters({
+ keyB: 'valueB',
+});
+
+// ...
+
+panel.api.updateParameters({
+ keyA: 'anotherValueA',
+});
+```
+
+To delete a parameter you should pass a value of `undefined` for the key.
+
+```ts
+panel.api.updateParameters({
+ keyA: undefined, // this will delete 'keyA'.
+});
+```
+
### Panel Rendering
By default `DockviewReact` only adds to the DOM those panels that are visible,
diff --git a/packages/docs/versioned_docs/version-1.7.3/components/gridview.mdx b/packages/docs/versioned_docs/version-1.7.4/components/gridview.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.3/components/gridview.mdx
rename to packages/docs/versioned_docs/version-1.7.4/components/gridview.mdx
diff --git a/packages/docs/versioned_docs/version-1.7.3/components/paneview.mdx b/packages/docs/versioned_docs/version-1.7.4/components/paneview.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.3/components/paneview.mdx
rename to packages/docs/versioned_docs/version-1.7.4/components/paneview.mdx
diff --git a/packages/docs/versioned_docs/version-1.7.3/components/splitview.mdx b/packages/docs/versioned_docs/version-1.7.4/components/splitview.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.3/components/splitview.mdx
rename to packages/docs/versioned_docs/version-1.7.4/components/splitview.mdx
diff --git a/packages/docs/versioned_docs/version-1.7.3/index.mdx b/packages/docs/versioned_docs/version-1.7.4/index.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.3/index.mdx
rename to packages/docs/versioned_docs/version-1.7.4/index.mdx
diff --git a/packages/docs/versioned_docs/version-1.7.3/theme.mdx b/packages/docs/versioned_docs/version-1.7.4/theme.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.3/theme.mdx
rename to packages/docs/versioned_docs/version-1.7.4/theme.mdx
diff --git a/packages/docs/versioned_sidebars/version-1.7.3-sidebars.json b/packages/docs/versioned_sidebars/version-1.7.4-sidebars.json
similarity index 100%
rename from packages/docs/versioned_sidebars/version-1.7.3-sidebars.json
rename to packages/docs/versioned_sidebars/version-1.7.4-sidebars.json
diff --git a/packages/docs/versions.json b/packages/docs/versions.json
index 900dc7f77..a53923196 100644
--- a/packages/docs/versions.json
+++ b/packages/docs/versions.json
@@ -1,3 +1,3 @@
[
- "1.7.3"
-]
\ No newline at end of file
+ "1.7.4"
+]
From 7dde18c6369bb154425ca36e2e8cec3b8fdbfe35 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Sun, 11 Jun 2023 09:45:28 +0100
Subject: [PATCH 11/23] chore(release): publish v1.7.4
---
lerna.json | 2 +-
packages/dockview-core/package.json | 2 +-
packages/dockview/package.json | 4 ++--
packages/docs/package.json | 4 ++--
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/lerna.json b/lerna.json
index 5d0c99866..bf55e0899 100644
--- a/lerna.json
+++ b/lerna.json
@@ -3,7 +3,7 @@
"packages/*"
],
"useWorkspaces": true,
- "version": "1.7.3",
+ "version": "1.7.4",
"npmClient": "yarn",
"command": {
"publish": {
diff --git a/packages/dockview-core/package.json b/packages/dockview-core/package.json
index e8bbfe657..a4d45486f 100644
--- a/packages/dockview-core/package.json
+++ b/packages/dockview-core/package.json
@@ -1,6 +1,6 @@
{
"name": "dockview-core",
- "version": "1.7.3",
+ "version": "1.7.4",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support",
"main": "./dist/cjs/index.js",
"types": "./dist/cjs/index.d.ts",
diff --git a/packages/dockview/package.json b/packages/dockview/package.json
index 975e2e48c..3d0acd2ff 100644
--- a/packages/dockview/package.json
+++ b/packages/dockview/package.json
@@ -1,6 +1,6 @@
{
"name": "dockview",
- "version": "1.7.3",
+ "version": "1.7.4",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support",
"main": "./dist/cjs/index.js",
"types": "./dist/cjs/index.d.ts",
@@ -56,7 +56,7 @@
"author": "https://github.com/mathuo",
"license": "MIT",
"dependencies": {
- "dockview-core": "^1.7.3"
+ "dockview-core": "^1.7.4"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^15.0.1",
diff --git a/packages/docs/package.json b/packages/docs/package.json
index a1a77a4bb..7cb47b249 100644
--- a/packages/docs/package.json
+++ b/packages/docs/package.json
@@ -1,6 +1,6 @@
{
"name": "dockview-docs",
- "version": "1.7.3",
+ "version": "1.7.4",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
@@ -22,7 +22,7 @@
"@minoru/react-dnd-treeview": "^3.4.3",
"axios": "^1.3.3",
"clsx": "^1.2.1",
- "dockview": "^1.7.3",
+ "dockview": "^1.7.4",
"prism-react-renderer": "^1.3.5",
"react": "^18.2.0",
"react-dnd": "^16.0.1",
From 15393213200e9eb4b15d041803073bd0313a4bf5 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Sun, 11 Jun 2023 13:21:32 +0100
Subject: [PATCH 12/23] test: add tests to existing mouse dnd functionality
---
.../src/__tests__/splitview/splitview.spec.ts | 52 ++++++++++++++++++-
.../dockview-core/src/splitview/splitview.ts | 2 -
2 files changed, 51 insertions(+), 3 deletions(-)
diff --git a/packages/dockview-core/src/__tests__/splitview/splitview.spec.ts b/packages/dockview-core/src/__tests__/splitview/splitview.spec.ts
index 23c9b1df8..7d14653d2 100644
--- a/packages/dockview-core/src/__tests__/splitview/splitview.spec.ts
+++ b/packages/dockview-core/src/__tests__/splitview/splitview.spec.ts
@@ -7,7 +7,7 @@ import {
Sizing,
Splitview,
} from '../../splitview/splitview';
-
+import { fireEvent } from '@testing-library/dom';
class Testview implements IView {
private _element: HTMLElement = document.createElement('div');
private _size = 0;
@@ -596,4 +596,54 @@ describe('splitview', () => {
expect(anyEvents).toBeFalsy();
expect(container.childNodes.length).toBe(0);
});
+
+ test('dnd: mouse events to move sash', () => {
+ const splitview = new Splitview(container, {
+ orientation: Orientation.HORIZONTAL,
+ proportionalLayout: false,
+ });
+ splitview.layout(400, 500);
+
+ const view1 = new Testview(0, 1000);
+ const view2 = new Testview(0, 1000);
+
+ splitview.addView(view1);
+ splitview.addView(view2);
+
+ const sashElement = container
+ .getElementsByClassName('sash')
+ .item(0) as HTMLElement;
+
+ // validate the expected state before drag
+ expect([view1.size, view2.size]).toEqual([200, 200]);
+ expect(sashElement).toBeTruthy();
+ expect(view1.element.parentElement!.style.pointerEvents).toBe('');
+ expect(view2.element.parentElement!.style.pointerEvents).toBe('');
+
+ // start the drag event
+ fireEvent.mouseDown(sashElement, { clientX: 50, clientY: 100 });
+
+ // during a sash drag the views should have pointer-events disabled
+ expect(view1.element.parentElement!.style.pointerEvents).toBe('none');
+ expect(view2.element.parentElement!.style.pointerEvents).toBe('none');
+
+ // expect a delta move of 70 - 50 = 20
+ fireEvent.mouseMove(document, { clientX: 70, clientY: 110 });
+ expect([view1.size, view2.size]).toEqual([220, 180]);
+
+ // expect a delta move of 75 - 70 = 5
+ fireEvent.mouseMove(document, { clientX: 75, clientY: 110 });
+ expect([view1.size, view2.size]).toEqual([225, 175]);
+
+ // end the drag event
+ fireEvent.mouseUp(document);
+
+ // expect pointer-eventes on views to be restored
+ expect(view1.element.parentElement!.style.pointerEvents).toBe('');
+ expect(view2.element.parentElement!.style.pointerEvents).toBe('');
+
+ fireEvent.mouseMove(document, { clientX: 100, clientY: 100 });
+ // expect no additional resizes
+ expect([view1.size, view2.size]).toEqual([225, 175]);
+ });
});
diff --git a/packages/dockview-core/src/splitview/splitview.ts b/packages/dockview-core/src/splitview/splitview.ts
index 48295a8c7..fd68a4a29 100644
--- a/packages/dockview-core/src/splitview/splitview.ts
+++ b/packages/dockview-core/src/splitview/splitview.ts
@@ -523,14 +523,12 @@ export class Splitview {
document.removeEventListener('mousemove', mousemove);
document.removeEventListener('mouseup', end);
- document.removeEventListener('mouseend', end);
this._onDidSashEnd.fire(undefined);
};
document.addEventListener('mousemove', mousemove);
document.addEventListener('mouseup', end);
- document.addEventListener('mouseend', end);
};
sash.addEventListener('mousedown', onStart);
From a39c2938f02ef54e6a55d893874104930c3f1d81 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Sun, 11 Jun 2023 14:31:28 +0100
Subject: [PATCH 13/23] test: listener utilities
---
.../src/__tests__/events.spec.ts | 141 +++++++++++++++++-
packages/dockview-core/src/events.ts | 4 +-
2 files changed, 142 insertions(+), 3 deletions(-)
diff --git a/packages/dockview-core/src/__tests__/events.spec.ts b/packages/dockview-core/src/__tests__/events.spec.ts
index 6ac17cc5c..532390a07 100644
--- a/packages/dockview-core/src/__tests__/events.spec.ts
+++ b/packages/dockview-core/src/__tests__/events.spec.ts
@@ -1,4 +1,9 @@
-import { Emitter, Event } from '../events';
+import {
+ Emitter,
+ Event,
+ addDisposableListener,
+ addDisposableWindowListener,
+} from '../events';
describe('events', () => {
describe('emitter', () => {
@@ -101,4 +106,138 @@ describe('events', () => {
emitter3.fire(3);
expect(value).toBe(3);
});
+
+ it('addDisposableWindowListener with capture options', () => {
+ const element = {
+ addEventListener: jest.fn(),
+ removeEventListener: jest.fn(),
+ };
+
+ const handler = jest.fn();
+
+ const disposable = addDisposableWindowListener(
+ element as any,
+ 'mousedown',
+ handler,
+ true
+ );
+
+ expect(element.addEventListener).toBeCalledTimes(1);
+ expect(element.addEventListener).toHaveBeenCalledWith(
+ 'mousedown',
+ handler,
+ true
+ );
+ expect(element.removeEventListener).toBeCalledTimes(0);
+
+ disposable.dispose();
+
+ expect(element.addEventListener).toBeCalledTimes(1);
+ expect(element.removeEventListener).toBeCalledTimes(1);
+ expect(element.removeEventListener).toBeCalledWith(
+ 'mousedown',
+ handler,
+ true
+ );
+ });
+
+ it('addDisposableWindowListener without capture options', () => {
+ const element = {
+ addEventListener: jest.fn(),
+ removeEventListener: jest.fn(),
+ };
+
+ const handler = jest.fn();
+
+ const disposable = addDisposableWindowListener(
+ element as any,
+ 'mousedown',
+ handler
+ );
+
+ expect(element.addEventListener).toBeCalledTimes(1);
+ expect(element.addEventListener).toHaveBeenCalledWith(
+ 'mousedown',
+ handler,
+ undefined
+ );
+ expect(element.removeEventListener).toBeCalledTimes(0);
+
+ disposable.dispose();
+
+ expect(element.addEventListener).toBeCalledTimes(1);
+ expect(element.removeEventListener).toBeCalledTimes(1);
+ expect(element.removeEventListener).toBeCalledWith(
+ 'mousedown',
+ handler,
+ undefined
+ );
+ });
+
+ it('addDisposableListener with capture options', () => {
+ const element = {
+ addEventListener: jest.fn(),
+ removeEventListener: jest.fn(),
+ };
+
+ const handler = jest.fn();
+
+ const disposable = addDisposableListener(
+ element as any,
+ 'mousedown',
+ handler,
+ true
+ );
+
+ expect(element.addEventListener).toBeCalledTimes(1);
+ expect(element.addEventListener).toHaveBeenCalledWith(
+ 'mousedown',
+ handler,
+ true
+ );
+ expect(element.removeEventListener).toBeCalledTimes(0);
+
+ disposable.dispose();
+
+ expect(element.addEventListener).toBeCalledTimes(1);
+ expect(element.removeEventListener).toBeCalledTimes(1);
+ expect(element.removeEventListener).toBeCalledWith(
+ 'mousedown',
+ handler,
+ true
+ );
+ });
+
+ it('addDisposableListener without capture options', () => {
+ const element = {
+ addEventListener: jest.fn(),
+ removeEventListener: jest.fn(),
+ };
+
+ const handler = jest.fn();
+
+ const disposable = addDisposableListener(
+ element as any,
+ 'mousedown',
+ handler
+ );
+
+ expect(element.addEventListener).toBeCalledTimes(1);
+ expect(element.addEventListener).toHaveBeenCalledWith(
+ 'mousedown',
+ handler,
+ undefined
+ );
+ expect(element.removeEventListener).toBeCalledTimes(0);
+
+ disposable.dispose();
+
+ expect(element.addEventListener).toBeCalledTimes(1);
+ expect(element.removeEventListener).toBeCalledTimes(1);
+ expect(element.removeEventListener).toBeCalledWith(
+ 'mousedown',
+ handler,
+ undefined
+ );
+ });
});
diff --git a/packages/dockview-core/src/events.ts b/packages/dockview-core/src/events.ts
index 91f27a1b1..cb8d95930 100644
--- a/packages/dockview-core/src/events.ts
+++ b/packages/dockview-core/src/events.ts
@@ -162,7 +162,7 @@ export function addDisposableWindowListener(
return {
dispose: () => {
- element.removeEventListener(type, listener);
+ element.removeEventListener(type, listener, options);
},
};
}
@@ -177,7 +177,7 @@ export function addDisposableListener(
return {
dispose: () => {
- element.removeEventListener(type, listener);
+ element.removeEventListener(type, listener, options);
},
};
}
From ba3fe82c02f066415f786da50c26292b8b954bf4 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Sun, 11 Jun 2023 15:48:37 +0100
Subject: [PATCH 14/23] chore: iFrame example
---
.codesandbox/ci.json | 3 +-
.../__tests__/dnd/abstractDragHandler.spec.ts | 50 +++++--
.../src/dnd/abstractDragHandler.ts | 33 +++--
packages/docs/docs/components/dockview.mdx | 24 ++++
.../sandboxes/iframe-dockview/package.json | 32 +++++
.../iframe-dockview/public/index.html | 44 ++++++
.../sandboxes/iframe-dockview/src/app.tsx | 61 +++++++++
.../src/hoistedDockviewPanel.tsx | 128 ++++++++++++++++++
.../sandboxes/iframe-dockview/src/index.tsx | 20 +++
.../sandboxes/iframe-dockview/src/styles.css | 15 ++
.../sandboxes/iframe-dockview/tsconfig.json | 18 +++
.../version-1.7.4/components/dockview.mdx | 24 ++++
12 files changed, 430 insertions(+), 22 deletions(-)
create mode 100644 packages/docs/sandboxes/iframe-dockview/package.json
create mode 100644 packages/docs/sandboxes/iframe-dockview/public/index.html
create mode 100644 packages/docs/sandboxes/iframe-dockview/src/app.tsx
create mode 100644 packages/docs/sandboxes/iframe-dockview/src/hoistedDockviewPanel.tsx
create mode 100644 packages/docs/sandboxes/iframe-dockview/src/index.tsx
create mode 100644 packages/docs/sandboxes/iframe-dockview/src/styles.css
create mode 100644 packages/docs/sandboxes/iframe-dockview/tsconfig.json
diff --git a/.codesandbox/ci.json b/.codesandbox/ci.json
index 856df6dc8..f04bc5e88 100644
--- a/.codesandbox/ci.json
+++ b/.codesandbox/ci.json
@@ -13,6 +13,7 @@
"/packages/docs/sandboxes/externaldnd-dockview",
"/packages/docs/sandboxes/fullwidthtab-dockview",
"/packages/docs/sandboxes/groupcontol-dockview",
+ "/packages/docs/sandboxes/iframe-dockview",
"/packages/docs/sandboxes/layout-dockview",
"/packages/docs/sandboxes/nativeapp-dockview",
"/packages/docs/sandboxes/nested-dockview",
@@ -29,4 +30,4 @@
"/packages/docs/sandboxes/javascript/vanilla-dockview"
],
"node": "16"
-}
+}
\ No newline at end of file
diff --git a/packages/dockview-core/src/__tests__/dnd/abstractDragHandler.spec.ts b/packages/dockview-core/src/__tests__/dnd/abstractDragHandler.spec.ts
index ebb55aae7..312916ae5 100644
--- a/packages/dockview-core/src/__tests__/dnd/abstractDragHandler.spec.ts
+++ b/packages/dockview-core/src/__tests__/dnd/abstractDragHandler.spec.ts
@@ -20,10 +20,6 @@ describe('abstractDragHandler', () => {
},
};
}
-
- dispose(): void {
- super.dispose();
- }
})(element);
expect(element.classList.contains('dv-dragged')).toBeFalsy();
@@ -62,10 +58,6 @@ describe('abstractDragHandler', () => {
},
};
}
-
- dispose(): void {
- //
- }
})(element);
expect(iframe.style.pointerEvents).toBeFalsy();
@@ -84,4 +76,46 @@ describe('abstractDragHandler', () => {
handler.dispose();
});
+
+ test('that the disabling of pointerEvents is restored on a premature disposal of the handler', () => {
+ jest.useFakeTimers();
+
+ const element = document.createElement('div');
+ const iframe = document.createElement('iframe');
+ const webview = document.createElement('webview');
+ const span = document.createElement('span');
+
+ document.body.appendChild(element);
+ document.body.appendChild(iframe);
+ document.body.appendChild(webview);
+ document.body.appendChild(span);
+
+ const handler = new (class TestClass extends DragHandler {
+ constructor(el: HTMLElement) {
+ super(el);
+ }
+
+ getData(): IDisposable {
+ return {
+ dispose: () => {
+ // /
+ },
+ };
+ }
+ })(element);
+
+ expect(iframe.style.pointerEvents).toBeFalsy();
+ expect(webview.style.pointerEvents).toBeFalsy();
+ expect(span.style.pointerEvents).toBeFalsy();
+
+ fireEvent.dragStart(element);
+ expect(iframe.style.pointerEvents).toBe('none');
+ expect(webview.style.pointerEvents).toBe('none');
+ expect(span.style.pointerEvents).toBeFalsy();
+
+ handler.dispose();
+ expect(iframe.style.pointerEvents).toBe('auto');
+ expect(webview.style.pointerEvents).toBe('auto');
+ expect(span.style.pointerEvents).toBeFalsy();
+ });
});
diff --git a/packages/dockview-core/src/dnd/abstractDragHandler.ts b/packages/dockview-core/src/dnd/abstractDragHandler.ts
index df3f49177..55e03fa42 100644
--- a/packages/dockview-core/src/dnd/abstractDragHandler.ts
+++ b/packages/dockview-core/src/dnd/abstractDragHandler.ts
@@ -7,17 +7,20 @@ import {
} from '../lifecycle';
export abstract class DragHandler extends CompositeDisposable {
- private readonly disposable = new MutableDisposable();
+ private readonly dataDisposable = new MutableDisposable();
+ private readonly pointerEventsDisposable = new MutableDisposable();
private readonly _onDragStart = new Emitter();
readonly onDragStart = this._onDragStart.event;
- private iframes: HTMLElement[] = [];
-
constructor(protected readonly el: HTMLElement) {
super();
- this.addDisposables(this._onDragStart);
+ this.addDisposables(
+ this._onDragStart,
+ this.dataDisposable,
+ this.pointerEventsDisposable
+ );
this.configure();
}
@@ -28,19 +31,27 @@ export abstract class DragHandler extends CompositeDisposable {
this.addDisposables(
this._onDragStart,
addDisposableListener(this.el, 'dragstart', (event) => {
- this.iframes = [
+ const iframes = [
...getElementsByTagName('iframe'),
...getElementsByTagName('webview'),
];
- for (const iframe of this.iframes) {
+ this.pointerEventsDisposable.value = {
+ dispose: () => {
+ for (const iframe of iframes) {
+ iframe.style.pointerEvents = 'auto';
+ }
+ },
+ };
+
+ for (const iframe of iframes) {
iframe.style.pointerEvents = 'none';
}
this.el.classList.add('dv-dragged');
setTimeout(() => this.el.classList.remove('dv-dragged'), 0);
- this.disposable.value = this.getData(event.dataTransfer);
+ this.dataDisposable.value = this.getData(event.dataTransfer);
if (event.dataTransfer) {
event.dataTransfer.effectAllowed = 'move';
@@ -61,12 +72,8 @@ export abstract class DragHandler extends CompositeDisposable {
}
}),
addDisposableListener(this.el, 'dragend', () => {
- for (const iframe of this.iframes) {
- iframe.style.pointerEvents = 'auto';
- }
- this.iframes = [];
-
- this.disposable.dispose();
+ this.pointerEventsDisposable.dispose();
+ this.dataDisposable.dispose();
})
);
}
diff --git a/packages/docs/docs/components/dockview.mdx b/packages/docs/docs/components/dockview.mdx
index 176f309db..576c574a3 100644
--- a/packages/docs/docs/components/dockview.mdx
+++ b/packages/docs/docs/components/dockview.mdx
@@ -27,6 +27,7 @@ import RenderingDockview from '@site/sandboxes/rendering-dockview/src/app';
import DockviewExternalDnd from '@site/sandboxes/externaldnd-dockview/src/app';
import DockviewResizeContainer from '@site/sandboxes/resizecontainer-dockview/src/app';
import DockviewTabheight from '@site/sandboxes/tabheight-dockview/src/app';
+import DockviewWithIFrames from '@site/sandboxes/iframe-dockview/src/app';
import { attach as attachDockviewVanilla } from '@site/sandboxes/javascript/vanilla-dockview/src/app';
import { attach as attachSimpleDockview } from '@site/sandboxes/javascript/simple-dockview/src/app';
@@ -739,6 +740,29 @@ api.group.api.setConstraints(...)
+## iFrames
+
+iFrames required special attention because of a particular behaviour in how iFrames render:
+
+> Re-parenting an iFrame will reload the contents of the iFrame or the rephrase this, moving an iFrame within the DOM will cause a reload of its contents.
+
+You can find many examples of discussions on this. Two reputable forums for example are linked [here](https://bugzilla.mozilla.org/show_bug.cgi?id=254144) and [here](https://github.com/whatwg/html/issues/5484).
+
+The problem with iFrames and `dockview` is that when you hide or move a panel that panels DOM element may be moved within the DOM or removed from the DOM completely.
+If your panel contains an iFrame then that iFrame will reload after being re-positioned within the DOM tree and all state in that iFrame will most likely be lost.
+
+`dockview` does not provide a built-in solution to this because it's too specific of a problem to include in the library.
+However the below example does show an implementation of a higher-order component `HoistedDockviewPanel`that you could use to work around this problems and make iFrames behave in `dockview`.
+
+What the higher-order component is doing is to hoist the panels contents into a DOM element that is always present and then `position: absolute` that element to match the dimensions of it's linked panel.
+The visibility of these hoisted elements is then controlled through some exposed api methods to hide elements that shouldn't be currently shown.
+
+You should open this example in CodeSandbox using the provided link to understand the code and make use of this implemention if required.
+
+
+
+
+
## Events
A simple example showing events fired by `dockviewz that can be interacted with.
diff --git a/packages/docs/sandboxes/iframe-dockview/package.json b/packages/docs/sandboxes/iframe-dockview/package.json
new file mode 100644
index 000000000..0a750cb5e
--- /dev/null
+++ b/packages/docs/sandboxes/iframe-dockview/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "iframe-dockview",
+ "description": "",
+ "keywords": [
+ "dockview"
+ ],
+ "version": "1.0.0",
+ "main": "src/index.tsx",
+ "dependencies": {
+ "dockview": "*",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@types/react": "^18.0.28",
+ "@types/react-dom": "^18.0.11",
+ "typescript": "^4.9.5",
+ "react-scripts": "*"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test --env=jsdom",
+ "eject": "react-scripts eject"
+ },
+ "browserslist": [
+ ">0.2%",
+ "not dead",
+ "not ie <= 11",
+ "not op_mini all"
+ ]
+}
\ No newline at end of file
diff --git a/packages/docs/sandboxes/iframe-dockview/public/index.html b/packages/docs/sandboxes/iframe-dockview/public/index.html
new file mode 100644
index 000000000..1f8a52426
--- /dev/null
+++ b/packages/docs/sandboxes/iframe-dockview/public/index.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ React App
+
+
+
+
+
+
+
+
+
diff --git a/packages/docs/sandboxes/iframe-dockview/src/app.tsx b/packages/docs/sandboxes/iframe-dockview/src/app.tsx
new file mode 100644
index 000000000..f52656551
--- /dev/null
+++ b/packages/docs/sandboxes/iframe-dockview/src/app.tsx
@@ -0,0 +1,61 @@
+import {
+ DockviewReact,
+ DockviewReadyEvent,
+ IDockviewPanelProps,
+} from 'dockview';
+import * as React from 'react';
+import { HoistedDockviewPanel } from './hoistedDockviewPanel';
+
+const components = {
+ iframeComponent: HoistedDockviewPanel(
+ (props: IDockviewPanelProps<{ color: string }>) => {
+ return (
+
+ );
+ }
+ ),
+ basicComponent: () => {
+ return (
+
+ {'This panel is just a usual component '}
+
+ );
+ },
+};
+
+export const App: React.FC = () => {
+ const onReady = (event: DockviewReadyEvent) => {
+ event.api.addPanel({
+ id: 'panel_1',
+ component: 'iframeComponent',
+ });
+
+ event.api.addPanel({
+ id: 'panel_2',
+ component: 'iframeComponent',
+ });
+
+ event.api.addPanel({
+ id: 'panel_3',
+ component: 'basicComponent',
+ });
+ };
+
+ return (
+
+ );
+};
+
+export default App;
diff --git a/packages/docs/sandboxes/iframe-dockview/src/hoistedDockviewPanel.tsx b/packages/docs/sandboxes/iframe-dockview/src/hoistedDockviewPanel.tsx
new file mode 100644
index 000000000..038cddd89
--- /dev/null
+++ b/packages/docs/sandboxes/iframe-dockview/src/hoistedDockviewPanel.tsx
@@ -0,0 +1,128 @@
+import { IDockviewPanelProps } from 'dockview';
+import * as React from 'react';
+import * as ReactDOM from 'react-dom';
+
+// watch an element for resize
+function watchElementResize(
+ element: HTMLElement,
+ cb: (entry: ResizeObserverEntry) => void
+): { dispose: () => void } {
+ const observer = new ResizeObserver((entires) => {
+ requestAnimationFrame(() => {
+ const firstEntry = entires[0];
+ cb(firstEntry);
+ });
+ });
+
+ observer.observe(element);
+
+ return {
+ dispose: () => {
+ observer.unobserve(element);
+ observer.disconnect();
+ },
+ };
+}
+
+// get absolute position of element allowing for scroll position
+function getDomNodePagePosition(domNode: HTMLElement): {
+ left: number;
+ top: number;
+ width: number;
+ height: number;
+} {
+ const { left, top, width, height } = domNode.getBoundingClientRect();
+ return {
+ left: left + window.scrollX,
+ top: top + window.scrollY,
+ width: width,
+ height: height,
+ };
+}
+
+function toggleVisibility(element: HTMLElement, isVisible: boolean) {
+ element.style.visibility = isVisible ? 'visible' : 'hidden';
+}
+
+export const HoistedDockviewPanel = (
+ DockviewPanelComponent: React.FC>
+) => {
+ return (props: IDockviewPanelProps) => {
+ const ref = React.useRef(null);
+ const innerRef = React.useRef(null);
+
+ React.useEffect(() => {
+ if (!ref.current || !innerRef.current) {
+ return;
+ }
+
+ const positionHoistedPanel = () => {
+ if (!ref.current || !innerRef.current) {
+ return;
+ }
+
+ const { left, top, height, width } = getDomNodePagePosition(
+ ref.current.parentElement! // use the parent element to determine our size
+ );
+
+ innerRef.current.style.left = `${left}px`;
+ innerRef.current.style.top = `${top}px`;
+ innerRef.current.style.height = `${height}px`;
+ innerRef.current.style.width = `${width}px`;
+ };
+
+ const observer = watchElementResize(ref.current, (callback) => {
+ if (!ref.current || !innerRef.current) {
+ return;
+ }
+
+ positionHoistedPanel(); // since the dockview-panel has changed we must re-position the hoisted element
+ });
+
+ positionHoistedPanel(); // initial-paint because a resize may not yet have occured
+
+ return () => {
+ observer.dispose(); // cleanup
+ };
+ }, []);
+
+ React.useEffect(() => {
+ if (!innerRef.current) {
+ return;
+ }
+
+ const disposable = props.api.onDidVisibilityChange((event) => {
+ if (!innerRef.current) {
+ return;
+ }
+
+ toggleVisibility(innerRef.current, event.isVisible); // subsequent checks of visibility
+ });
+
+ toggleVisibility(innerRef.current, props.api.isVisible); // initial check of visibility
+
+ return () => {
+ disposable.dispose(); // cleanup
+ };
+ }, [props.api]);
+
+ return (
+
+ {ReactDOM.createPortal(
+
+
+
,
+ document.body // <-- you may choose to mount these 'global' elements to anywhere you see suitable
+ )}
+
+ );
+ };
+};
diff --git a/packages/docs/sandboxes/iframe-dockview/src/index.tsx b/packages/docs/sandboxes/iframe-dockview/src/index.tsx
new file mode 100644
index 000000000..2fe1be232
--- /dev/null
+++ b/packages/docs/sandboxes/iframe-dockview/src/index.tsx
@@ -0,0 +1,20 @@
+import { StrictMode } from 'react';
+import * as ReactDOMClient from 'react-dom/client';
+import './styles.css';
+import 'dockview/dist/styles/dockview.css';
+
+import App from './app';
+
+const rootElement = document.getElementById('root');
+
+if (rootElement) {
+ const root = ReactDOMClient.createRoot(rootElement);
+
+ root.render(
+
+
+
+ );
+}
diff --git a/packages/docs/sandboxes/iframe-dockview/src/styles.css b/packages/docs/sandboxes/iframe-dockview/src/styles.css
new file mode 100644
index 000000000..b80f6dd76
--- /dev/null
+++ b/packages/docs/sandboxes/iframe-dockview/src/styles.css
@@ -0,0 +1,15 @@
+body {
+ margin: 0px;
+ color: white;
+ font-family: sans-serif;
+ text-align: center;
+}
+
+#root {
+ height: 100vh;
+ width: 100vw;
+}
+
+.app {
+ height: 100%;
+}
diff --git a/packages/docs/sandboxes/iframe-dockview/tsconfig.json b/packages/docs/sandboxes/iframe-dockview/tsconfig.json
new file mode 100644
index 000000000..cdc4fb5f5
--- /dev/null
+++ b/packages/docs/sandboxes/iframe-dockview/tsconfig.json
@@ -0,0 +1,18 @@
+{
+ "compilerOptions": {
+ "outDir": "build/dist",
+ "module": "esnext",
+ "target": "es5",
+ "lib": ["es6", "dom"],
+ "sourceMap": true,
+ "allowJs": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "rootDir": "src",
+ "forceConsistentCasingInFileNames": true,
+ "noImplicitReturns": true,
+ "noImplicitThis": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true
+ }
+}
diff --git a/packages/docs/versioned_docs/version-1.7.4/components/dockview.mdx b/packages/docs/versioned_docs/version-1.7.4/components/dockview.mdx
index 176f309db..576c574a3 100644
--- a/packages/docs/versioned_docs/version-1.7.4/components/dockview.mdx
+++ b/packages/docs/versioned_docs/version-1.7.4/components/dockview.mdx
@@ -27,6 +27,7 @@ import RenderingDockview from '@site/sandboxes/rendering-dockview/src/app';
import DockviewExternalDnd from '@site/sandboxes/externaldnd-dockview/src/app';
import DockviewResizeContainer from '@site/sandboxes/resizecontainer-dockview/src/app';
import DockviewTabheight from '@site/sandboxes/tabheight-dockview/src/app';
+import DockviewWithIFrames from '@site/sandboxes/iframe-dockview/src/app';
import { attach as attachDockviewVanilla } from '@site/sandboxes/javascript/vanilla-dockview/src/app';
import { attach as attachSimpleDockview } from '@site/sandboxes/javascript/simple-dockview/src/app';
@@ -739,6 +740,29 @@ api.group.api.setConstraints(...)
+## iFrames
+
+iFrames required special attention because of a particular behaviour in how iFrames render:
+
+> Re-parenting an iFrame will reload the contents of the iFrame or the rephrase this, moving an iFrame within the DOM will cause a reload of its contents.
+
+You can find many examples of discussions on this. Two reputable forums for example are linked [here](https://bugzilla.mozilla.org/show_bug.cgi?id=254144) and [here](https://github.com/whatwg/html/issues/5484).
+
+The problem with iFrames and `dockview` is that when you hide or move a panel that panels DOM element may be moved within the DOM or removed from the DOM completely.
+If your panel contains an iFrame then that iFrame will reload after being re-positioned within the DOM tree and all state in that iFrame will most likely be lost.
+
+`dockview` does not provide a built-in solution to this because it's too specific of a problem to include in the library.
+However the below example does show an implementation of a higher-order component `HoistedDockviewPanel`that you could use to work around this problems and make iFrames behave in `dockview`.
+
+What the higher-order component is doing is to hoist the panels contents into a DOM element that is always present and then `position: absolute` that element to match the dimensions of it's linked panel.
+The visibility of these hoisted elements is then controlled through some exposed api methods to hide elements that shouldn't be currently shown.
+
+You should open this example in CodeSandbox using the provided link to understand the code and make use of this implemention if required.
+
+
+
+
+
## Events
A simple example showing events fired by `dockviewz that can be interacted with.
From 4f5b6adb5fc7972a0e0e56da3dff6062b229a22c Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Sun, 11 Jun 2023 20:00:05 +0100
Subject: [PATCH 15/23] fix: revert gridview disposal changes
---
.../dockview/dockviewComponent.spec.ts | 162 ++++++++++++------
.../dockview-core/src/gridview/gridview.ts | 25 +--
2 files changed, 121 insertions(+), 66 deletions(-)
diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts
index 2142045d5..67f317886 100644
--- a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts
+++ b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts
@@ -100,67 +100,67 @@ describe('dockviewComponent', () => {
});
});
- test('event leakage', () => {
- Emitter.setLeakageMonitorEnabled(true);
+ // test('event leakage', () => {
+ // Emitter.setLeakageMonitorEnabled(true);
- dockview = new DockviewComponent({
- parentElement: container,
- components: {
- default: PanelContentPartTest,
- },
- });
+ // dockview = new DockviewComponent({
+ // parentElement: container,
+ // components: {
+ // default: PanelContentPartTest,
+ // },
+ // });
- dockview.layout(500, 1000);
+ // dockview.layout(500, 1000);
- dockview.addPanel({
- id: 'panel1',
- component: 'default',
- });
+ // dockview.addPanel({
+ // id: 'panel1',
+ // component: 'default',
+ // });
- const panel2 = dockview.addPanel({
- id: 'panel2',
- component: 'default',
- });
+ // const panel2 = dockview.addPanel({
+ // id: 'panel2',
+ // component: 'default',
+ // });
- dockview.removePanel(panel2);
+ // dockview.removePanel(panel2);
- const panel3 = dockview.addPanel({
- id: 'panel3',
- component: 'default',
- position: {
- direction: 'right',
- referencePanel: 'panel1',
- },
- });
+ // const panel3 = dockview.addPanel({
+ // id: 'panel3',
+ // component: 'default',
+ // position: {
+ // direction: 'right',
+ // referencePanel: 'panel1',
+ // },
+ // });
- const panel4 = dockview.addPanel({
- id: 'panel4',
- component: 'default',
- position: {
- direction: 'above',
- },
- });
+ // const panel4 = dockview.addPanel({
+ // id: 'panel4',
+ // component: 'default',
+ // position: {
+ // direction: 'above',
+ // },
+ // });
- dockview.moveGroupOrPanel(
- panel4.group,
- panel3.group.id,
- panel3.id,
- 'center'
- );
+ // dockview.moveGroupOrPanel(
+ // panel4.group,
+ // panel3.group.id,
+ // panel3.id,
+ // 'center'
+ // );
- dockview.dispose();
+ // dockview.dispose();
- if (Emitter.MEMORY_LEAK_WATCHER.size > 0) {
- for (const entry of Array.from(
- Emitter.MEMORY_LEAK_WATCHER.events
- )) {
- console.log('disposal', entry[1]);
- }
- throw new Error('not all listeners disposed');
- }
+ // if (Emitter.MEMORY_LEAK_WATCHER.size > 0) {
+ // for (const entry of Array.from(
+ // Emitter.MEMORY_LEAK_WATCHER.events
+ // )) {
+ // console.log('disposal', entry[1]);
+ // }
+ // throw new Error('not all listeners disposed');
+ // }
- Emitter.setLeakageMonitorEnabled(false);
- });
+ // Emitter.setLeakageMonitorEnabled(false);
+ // });
test('duplicate panel', () => {
dockview.layout(500, 1000);
@@ -2448,4 +2448,66 @@ describe('dockviewComponent', () => {
activeGroup: '1',
});
});
+
+ test('check', () => {
+ const container = document.createElement('div');
+
+ const dockview = new DockviewComponent({
+ parentElement: container,
+ components: {
+ default: PanelContentPartTest,
+ },
+ tabComponents: {
+ test_tab_id: PanelTabPartTest,
+ },
+ orientation: Orientation.HORIZONTAL,
+ });
+
+ dockview.layout(100, 100);
+
+ const panel1 = dockview.addPanel({
+ id: 'panel1',
+ component: 'default',
+ });
+
+ const panel2 = dockview.addPanel({
+ id: 'panel2',
+ component: 'default',
+ });
+
+ const panel3 = dockview.addPanel({
+ id: 'panel3',
+ component: 'default',
+ });
+
+ dockview.moveGroupOrPanel(
+ panel3.group,
+ panel3.group.id,
+ panel3.id,
+ 'right'
+ );
+
+ expect(dockview.groups.length).toBe(2);
+
+ dockview.moveGroupOrPanel(
+ panel3.group,
+ panel2.group.id,
+ panel2.id,
+ 'bottom'
+ );
+
+ expect(dockview.groups.length).toBe(3);
+
+ dockview.moveGroupOrPanel(
+ panel2.group,
+ panel1.group.id,
+ panel1.id,
+ 'center'
+ );
+
+ expect(dockview.groups.length).toBe(2);
+
+ const viewQuery = container.querySelectorAll('.split-view-container');
+ expect(viewQuery).toBeTruthy();
+ });
});
diff --git a/packages/dockview-core/src/gridview/gridview.ts b/packages/dockview-core/src/gridview/gridview.ts
index 583b63c6f..ee9d8f923 100644
--- a/packages/dockview-core/src/gridview/gridview.ts
+++ b/packages/dockview-core/src/gridview/gridview.ts
@@ -684,18 +684,14 @@ export class Gridview implements IDisposable {
throw new Error('Invalid location');
}
- const view = node.view;
- node.dispose(); // dispose of node
-
- const child = parent.removeChild(index, sizing);
- child.dispose();
+ parent.removeChild(index, sizing);
if (parent.children.length === 0) {
- return view;
+ return node.view;
}
if (parent.children.length > 1) {
- return view;
+ return node.view;
}
const sibling = parent.children[0];
@@ -704,28 +700,25 @@ export class Gridview implements IDisposable {
// parent is root
if (sibling instanceof LeafNode) {
- return view;
+ return node.view;
}
// we must promote sibling to be the new root
- const child = parent.removeChild(0, sizing);
- child.dispose();
+ parent.removeChild(0, sizing);
this.root = sibling;
- return view;
+ return node.view;
}
const [grandParent, ..._] = [...pathToParent].reverse();
const [parentIndex, ...__] = [...rest].reverse();
const isSiblingVisible = parent.isChildVisible(0);
- const childNode = parent.removeChild(0, sizing);
- childNode.dispose();
+ parent.removeChild(0, sizing);
const sizes = grandParent.children.map((_size, i) =>
grandParent.getChildSize(i)
);
- const parentNode = grandParent.removeChild(parentIndex, sizing);
- parentNode.dispose();
+ grandParent.removeChild(parentIndex, sizing);
if (sibling instanceof BranchNode) {
sizes.splice(
@@ -754,7 +747,7 @@ export class Gridview implements IDisposable {
grandParent.resizeChild(i, sizes[i]);
}
- return view;
+ return node.view;
}
public layout(width: number, height: number): void {
From d8e8103f8069b23360011ce10f3b3336578412b7 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Sun, 11 Jun 2023 20:21:11 +0100
Subject: [PATCH 16/23] chore: prepare v1.7.5
---
.../{version-1.7.4 => version-1.7.5}/basics.mdx | 0
.../components/_category_.json | 0
.../{version-1.7.4 => version-1.7.5}/components/dockview.mdx | 0
.../{version-1.7.4 => version-1.7.5}/components/gridview.mdx | 0
.../{version-1.7.4 => version-1.7.5}/components/paneview.mdx | 0
.../{version-1.7.4 => version-1.7.5}/components/splitview.mdx | 0
.../versioned_docs/{version-1.7.4 => version-1.7.5}/index.mdx | 0
.../versioned_docs/{version-1.7.4 => version-1.7.5}/theme.mdx | 0
...ersion-1.7.4-sidebars.json => version-1.7.5-sidebars.json} | 0
packages/docs/versions.json | 4 ++--
10 files changed, 2 insertions(+), 2 deletions(-)
rename packages/docs/versioned_docs/{version-1.7.4 => version-1.7.5}/basics.mdx (100%)
rename packages/docs/versioned_docs/{version-1.7.4 => version-1.7.5}/components/_category_.json (100%)
rename packages/docs/versioned_docs/{version-1.7.4 => version-1.7.5}/components/dockview.mdx (100%)
rename packages/docs/versioned_docs/{version-1.7.4 => version-1.7.5}/components/gridview.mdx (100%)
rename packages/docs/versioned_docs/{version-1.7.4 => version-1.7.5}/components/paneview.mdx (100%)
rename packages/docs/versioned_docs/{version-1.7.4 => version-1.7.5}/components/splitview.mdx (100%)
rename packages/docs/versioned_docs/{version-1.7.4 => version-1.7.5}/index.mdx (100%)
rename packages/docs/versioned_docs/{version-1.7.4 => version-1.7.5}/theme.mdx (100%)
rename packages/docs/versioned_sidebars/{version-1.7.4-sidebars.json => version-1.7.5-sidebars.json} (100%)
diff --git a/packages/docs/versioned_docs/version-1.7.4/basics.mdx b/packages/docs/versioned_docs/version-1.7.5/basics.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.4/basics.mdx
rename to packages/docs/versioned_docs/version-1.7.5/basics.mdx
diff --git a/packages/docs/versioned_docs/version-1.7.4/components/_category_.json b/packages/docs/versioned_docs/version-1.7.5/components/_category_.json
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.4/components/_category_.json
rename to packages/docs/versioned_docs/version-1.7.5/components/_category_.json
diff --git a/packages/docs/versioned_docs/version-1.7.4/components/dockview.mdx b/packages/docs/versioned_docs/version-1.7.5/components/dockview.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.4/components/dockview.mdx
rename to packages/docs/versioned_docs/version-1.7.5/components/dockview.mdx
diff --git a/packages/docs/versioned_docs/version-1.7.4/components/gridview.mdx b/packages/docs/versioned_docs/version-1.7.5/components/gridview.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.4/components/gridview.mdx
rename to packages/docs/versioned_docs/version-1.7.5/components/gridview.mdx
diff --git a/packages/docs/versioned_docs/version-1.7.4/components/paneview.mdx b/packages/docs/versioned_docs/version-1.7.5/components/paneview.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.4/components/paneview.mdx
rename to packages/docs/versioned_docs/version-1.7.5/components/paneview.mdx
diff --git a/packages/docs/versioned_docs/version-1.7.4/components/splitview.mdx b/packages/docs/versioned_docs/version-1.7.5/components/splitview.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.4/components/splitview.mdx
rename to packages/docs/versioned_docs/version-1.7.5/components/splitview.mdx
diff --git a/packages/docs/versioned_docs/version-1.7.4/index.mdx b/packages/docs/versioned_docs/version-1.7.5/index.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.4/index.mdx
rename to packages/docs/versioned_docs/version-1.7.5/index.mdx
diff --git a/packages/docs/versioned_docs/version-1.7.4/theme.mdx b/packages/docs/versioned_docs/version-1.7.5/theme.mdx
similarity index 100%
rename from packages/docs/versioned_docs/version-1.7.4/theme.mdx
rename to packages/docs/versioned_docs/version-1.7.5/theme.mdx
diff --git a/packages/docs/versioned_sidebars/version-1.7.4-sidebars.json b/packages/docs/versioned_sidebars/version-1.7.5-sidebars.json
similarity index 100%
rename from packages/docs/versioned_sidebars/version-1.7.4-sidebars.json
rename to packages/docs/versioned_sidebars/version-1.7.5-sidebars.json
diff --git a/packages/docs/versions.json b/packages/docs/versions.json
index a53923196..e6f7e7291 100644
--- a/packages/docs/versions.json
+++ b/packages/docs/versions.json
@@ -1,3 +1,3 @@
[
- "1.7.4"
-]
+ "1.7.5"
+]
\ No newline at end of file
From c42d8648ea904c4096af1dbbe0b1cc37ab460dad Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Sun, 11 Jun 2023 20:25:23 +0100
Subject: [PATCH 17/23] chore: prepare v1.7.5
---
...ew-1.7.4.md => 2023-06-10-dockview-1.7.4.md} | 0
packages/docs/blog/2023-06-11-dockview-1.7.5.md | 17 +++++++++++++++++
2 files changed, 17 insertions(+)
rename packages/docs/blog/{2023-06-14-dockview-1.7.4.md => 2023-06-10-dockview-1.7.4.md} (100%)
create mode 100644 packages/docs/blog/2023-06-11-dockview-1.7.5.md
diff --git a/packages/docs/blog/2023-06-14-dockview-1.7.4.md b/packages/docs/blog/2023-06-10-dockview-1.7.4.md
similarity index 100%
rename from packages/docs/blog/2023-06-14-dockview-1.7.4.md
rename to packages/docs/blog/2023-06-10-dockview-1.7.4.md
diff --git a/packages/docs/blog/2023-06-11-dockview-1.7.5.md b/packages/docs/blog/2023-06-11-dockview-1.7.5.md
new file mode 100644
index 000000000..69e4b008f
--- /dev/null
+++ b/packages/docs/blog/2023-06-11-dockview-1.7.5.md
@@ -0,0 +1,17 @@
+---
+slug: dockview-1.7.5-release
+title: Dockview 1.7.5
+tags: [release]
+---
+
+# Release Notes
+
+Please reference to docs @ [dockview.dev](https://dockview.dev).
+
+## 🚀 Features
+
+## 🛠Miscs
+
+- Fix [#255](https://github.com/mathuo/dockview/issues/255)
+
+## 🔥 Breaking changes
From 54bc30c1aa7bd523a5fea025cf438ef221cc3a9b Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Sun, 11 Jun 2023 20:25:44 +0100
Subject: [PATCH 18/23] chore(release): publish v1.7.5
---
lerna.json | 2 +-
packages/dockview-core/package.json | 2 +-
packages/dockview/package.json | 4 ++--
packages/docs/package.json | 4 ++--
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/lerna.json b/lerna.json
index bf55e0899..77cdbbf1c 100644
--- a/lerna.json
+++ b/lerna.json
@@ -3,7 +3,7 @@
"packages/*"
],
"useWorkspaces": true,
- "version": "1.7.4",
+ "version": "1.7.5",
"npmClient": "yarn",
"command": {
"publish": {
diff --git a/packages/dockview-core/package.json b/packages/dockview-core/package.json
index a4d45486f..1590381fd 100644
--- a/packages/dockview-core/package.json
+++ b/packages/dockview-core/package.json
@@ -1,6 +1,6 @@
{
"name": "dockview-core",
- "version": "1.7.4",
+ "version": "1.7.5",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support",
"main": "./dist/cjs/index.js",
"types": "./dist/cjs/index.d.ts",
diff --git a/packages/dockview/package.json b/packages/dockview/package.json
index 3d0acd2ff..8232edcc7 100644
--- a/packages/dockview/package.json
+++ b/packages/dockview/package.json
@@ -1,6 +1,6 @@
{
"name": "dockview",
- "version": "1.7.4",
+ "version": "1.7.5",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support",
"main": "./dist/cjs/index.js",
"types": "./dist/cjs/index.d.ts",
@@ -56,7 +56,7 @@
"author": "https://github.com/mathuo",
"license": "MIT",
"dependencies": {
- "dockview-core": "^1.7.4"
+ "dockview-core": "^1.7.5"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^15.0.1",
diff --git a/packages/docs/package.json b/packages/docs/package.json
index 7cb47b249..577f43f60 100644
--- a/packages/docs/package.json
+++ b/packages/docs/package.json
@@ -1,6 +1,6 @@
{
"name": "dockview-docs",
- "version": "1.7.4",
+ "version": "1.7.5",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
@@ -22,7 +22,7 @@
"@minoru/react-dnd-treeview": "^3.4.3",
"axios": "^1.3.3",
"clsx": "^1.2.1",
- "dockview": "^1.7.4",
+ "dockview": "^1.7.5",
"prism-react-renderer": "^1.3.5",
"react": "^18.2.0",
"react-dnd": "^16.0.1",
From 477394cd1e1a8e481cfb47f68a1286c26ea907c7 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Sun, 11 Jun 2023 20:43:13 +0100
Subject: [PATCH 19/23] chore: docs
---
.../sandboxes/iframe-dockview/src/app.tsx | 2 +-
.../src/hoistedDockviewPanel.tsx | 71 +++++--------------
2 files changed, 18 insertions(+), 55 deletions(-)
diff --git a/packages/docs/sandboxes/iframe-dockview/src/app.tsx b/packages/docs/sandboxes/iframe-dockview/src/app.tsx
index f52656551..8aefb6524 100644
--- a/packages/docs/sandboxes/iframe-dockview/src/app.tsx
+++ b/packages/docs/sandboxes/iframe-dockview/src/app.tsx
@@ -12,10 +12,10 @@ const components = {
return (
diff --git a/packages/docs/sandboxes/iframe-dockview/src/hoistedDockviewPanel.tsx b/packages/docs/sandboxes/iframe-dockview/src/hoistedDockviewPanel.tsx
index 038cddd89..d00698f83 100644
--- a/packages/docs/sandboxes/iframe-dockview/src/hoistedDockviewPanel.tsx
+++ b/packages/docs/sandboxes/iframe-dockview/src/hoistedDockviewPanel.tsx
@@ -2,28 +2,6 @@ import { IDockviewPanelProps } from 'dockview';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
-// watch an element for resize
-function watchElementResize(
- element: HTMLElement,
- cb: (entry: ResizeObserverEntry) => void
-): { dispose: () => void } {
- const observer = new ResizeObserver((entires) => {
- requestAnimationFrame(() => {
- const firstEntry = entires[0];
- cb(firstEntry);
- });
- });
-
- observer.observe(element);
-
- return {
- dispose: () => {
- observer.unobserve(element);
- observer.disconnect();
- },
- };
-}
-
// get absolute position of element allowing for scroll position
function getDomNodePagePosition(domNode: HTMLElement): {
left: number;
@@ -51,47 +29,27 @@ export const HoistedDockviewPanel = (
const ref = React.useRef(null);
const innerRef = React.useRef(null);
- React.useEffect(() => {
+ const positionHoistedPanel = () => {
if (!ref.current || !innerRef.current) {
return;
}
- const positionHoistedPanel = () => {
- if (!ref.current || !innerRef.current) {
- return;
- }
+ const { left, top, height, width } = getDomNodePagePosition(
+ ref.current.parentElement! // use the parent element to determine our size
+ );
- const { left, top, height, width } = getDomNodePagePosition(
- ref.current.parentElement! // use the parent element to determine our size
- );
-
- innerRef.current.style.left = `${left}px`;
- innerRef.current.style.top = `${top}px`;
- innerRef.current.style.height = `${height}px`;
- innerRef.current.style.width = `${width}px`;
- };
-
- const observer = watchElementResize(ref.current, (callback) => {
- if (!ref.current || !innerRef.current) {
- return;
- }
-
- positionHoistedPanel(); // since the dockview-panel has changed we must re-position the hoisted element
- });
-
- positionHoistedPanel(); // initial-paint because a resize may not yet have occured
-
- return () => {
- observer.dispose(); // cleanup
- };
- }, []);
+ innerRef.current.style.left = `${left}px`;
+ innerRef.current.style.top = `${top}px`;
+ innerRef.current.style.height = `${height}px`;
+ innerRef.current.style.width = `${width}px`;
+ };
React.useEffect(() => {
if (!innerRef.current) {
return;
}
- const disposable = props.api.onDidVisibilityChange((event) => {
+ const disposable1 = props.api.onDidVisibilityChange((event) => {
if (!innerRef.current) {
return;
}
@@ -99,10 +57,15 @@ export const HoistedDockviewPanel = (
toggleVisibility(innerRef.current, event.isVisible); // subsequent checks of visibility
});
- toggleVisibility(innerRef.current, props.api.isVisible); // initial check of visibility
+ const disposable2 = props.api.onDidDimensionsChange(() => {
+ positionHoistedPanel();
+ });
+
+ positionHoistedPanel();
return () => {
- disposable.dispose(); // cleanup
+ disposable1.dispose(); // cleanup
+ disposable2.dispose();
};
}, [props.api]);
From 35a97b742605de028da1693d758afba03fcb9f47 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Sun, 11 Jun 2023 21:17:04 +0100
Subject: [PATCH 20/23] test: gridview tests
---
.../src/__tests__/gridview/gridview.spec.ts | 574 ++++++++++++++++++
1 file changed, 574 insertions(+)
diff --git a/packages/dockview-core/src/__tests__/gridview/gridview.spec.ts b/packages/dockview-core/src/__tests__/gridview/gridview.spec.ts
index 79cdd3de5..bb67ad2ea 100644
--- a/packages/dockview-core/src/__tests__/gridview/gridview.spec.ts
+++ b/packages/dockview-core/src/__tests__/gridview/gridview.spec.ts
@@ -18,6 +18,10 @@ class MockGridview implements IGridView {
>().event;
element: HTMLElement = document.createElement('div');
+ constructor() {
+ this.element.className = 'mock-grid-view';
+ }
+
layout(width: number, height: number): void {
//
}
@@ -116,4 +120,574 @@ describe('gridview', () => {
checkOrientationFlipsAtEachLevel((gridview as any).root as BranchNode);
});
+
+ test('removeView: remove leaf from branch where branch becomes leaf and parent is root', () => {
+ const gridview = new Gridview(
+ false,
+ { separatorBorder: '' },
+ Orientation.HORIZONTAL
+ );
+ gridview.layout(1000, 1000);
+
+ gridview.addView(new MockGridview(), Sizing.Distribute, [0]);
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1]);
+
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1, 0]);
+
+ expect(gridview.serialize()).toEqual({
+ height: 1000,
+ orientation: 'HORIZONTAL',
+ root: {
+ data: [
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ {
+ data: [
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ ],
+ size: 500,
+ type: 'branch',
+ },
+ ],
+ size: 1000,
+ type: 'branch',
+ },
+ width: 1000,
+ });
+ expect(
+ gridview.element.querySelectorAll('.mock-grid-view').length
+ ).toBe(3);
+
+ gridview.removeView([1, 0], Sizing.Distribute);
+
+ expect(gridview.serialize()).toEqual({
+ height: 1000,
+ orientation: 'HORIZONTAL',
+ root: {
+ data: [
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ ],
+ size: 1000,
+ type: 'branch',
+ },
+ width: 1000,
+ });
+ expect(
+ gridview.element.querySelectorAll('.mock-grid-view').length
+ ).toBe(2);
+ });
+
+ test('removeView: remove leaf from branch where branch remains branch and parent is root', () => {
+ const gridview = new Gridview(
+ false,
+ { separatorBorder: '' },
+ Orientation.HORIZONTAL
+ );
+ gridview.layout(1000, 1000);
+
+ gridview.addView(new MockGridview(), Sizing.Distribute, [0]);
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1]);
+
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1, 0]);
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1, 1]);
+
+ expect(gridview.serialize()).toEqual({
+ height: 1000,
+ orientation: 'HORIZONTAL',
+ root: {
+ data: [
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ {
+ data: [
+ {
+ data: {},
+ size: 333,
+ type: 'leaf',
+ },
+ {
+ data: {},
+ size: 333,
+ type: 'leaf',
+ },
+ {
+ data: {},
+ size: 334,
+ type: 'leaf',
+ },
+ ],
+ size: 500,
+ type: 'branch',
+ },
+ ],
+ size: 1000,
+ type: 'branch',
+ },
+ width: 1000,
+ });
+ expect(
+ gridview.element.querySelectorAll('.mock-grid-view').length
+ ).toBe(4);
+
+ gridview.removeView([1, 0], Sizing.Distribute);
+
+ expect(gridview.serialize()).toEqual({
+ height: 1000,
+ orientation: 'HORIZONTAL',
+ root: {
+ data: [
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ {
+ data: [
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ ],
+ size: 500,
+ type: 'branch',
+ },
+ ],
+ size: 1000,
+ type: 'branch',
+ },
+ width: 1000,
+ });
+ expect(
+ gridview.element.querySelectorAll('.mock-grid-view').length
+ ).toBe(3);
+ });
+
+ test('removeView: remove leaf where parent is root', () => {
+ const gridview = new Gridview(
+ false,
+ { separatorBorder: '' },
+ Orientation.HORIZONTAL
+ );
+ gridview.layout(1000, 1000);
+
+ gridview.addView(new MockGridview(), Sizing.Distribute, [0]);
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1]);
+
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1, 0]);
+
+ expect(gridview.serialize()).toEqual({
+ height: 1000,
+ orientation: 'HORIZONTAL',
+ root: {
+ data: [
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ {
+ data: [
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ ],
+ size: 500,
+ type: 'branch',
+ },
+ ],
+ size: 1000,
+ type: 'branch',
+ },
+ width: 1000,
+ });
+ expect(
+ gridview.element.querySelectorAll('.mock-grid-view').length
+ ).toBe(3);
+
+ gridview.removeView([0], Sizing.Distribute);
+
+ expect(gridview.serialize()).toEqual({
+ height: 1000,
+ orientation: 'VERTICAL',
+ root: {
+ data: [
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ ],
+ size: 1000,
+ type: 'branch',
+ },
+ width: 1000,
+ });
+ expect(
+ gridview.element.querySelectorAll('.mock-grid-view').length
+ ).toBe(2);
+ });
+
+ test('removeView: remove leaf from branch where branch becomes leaf and parent is not root', () => {
+ const gridview = new Gridview(
+ false,
+ { separatorBorder: '' },
+ Orientation.HORIZONTAL
+ );
+ gridview.layout(1000, 1000);
+
+ gridview.addView(new MockGridview(), Sizing.Distribute, [0]);
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1]);
+
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1, 0]);
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1, 0, 0]);
+
+ expect(gridview.serialize()).toEqual({
+ height: 1000,
+ orientation: 'HORIZONTAL',
+ root: {
+ data: [
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ {
+ data: [
+ {
+ data: [
+ {
+ data: {},
+ size: 250,
+ type: 'leaf',
+ },
+ {
+ data: {},
+ size: 250,
+ type: 'leaf',
+ },
+ ],
+ size: 500,
+ type: 'branch',
+ },
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ ],
+ size: 500,
+ type: 'branch',
+ },
+ ],
+ size: 1000,
+ type: 'branch',
+ },
+ width: 1000,
+ });
+ expect(
+ gridview.element.querySelectorAll('.mock-grid-view').length
+ ).toBe(4);
+
+ gridview.removeView([1, 0, 0], Sizing.Distribute);
+
+ expect(gridview.serialize()).toEqual({
+ height: 1000,
+ orientation: 'HORIZONTAL',
+ root: {
+ data: [
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ {
+ data: [
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ ],
+ size: 500,
+ type: 'branch',
+ },
+ ],
+ size: 1000,
+ type: 'branch',
+ },
+ width: 1000,
+ });
+ expect(
+ gridview.element.querySelectorAll('.mock-grid-view').length
+ ).toBe(3);
+ });
+
+ test('removeView: remove leaf from branch where branch remains branch and parent is not root', () => {
+ const gridview = new Gridview(
+ false,
+ { separatorBorder: '' },
+ Orientation.HORIZONTAL
+ );
+ gridview.layout(1000, 1000);
+
+ gridview.addView(new MockGridview(), Sizing.Distribute, [0]);
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1]);
+
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1, 0]);
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1, 0, 0]);
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1, 0, 1]);
+
+ expect(gridview.serialize()).toEqual({
+ height: 1000,
+ orientation: 'HORIZONTAL',
+ root: {
+ data: [
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ {
+ data: [
+ {
+ data: [
+ {
+ data: {},
+ size: 166,
+ type: 'leaf',
+ },
+ {
+ data: {},
+ size: 166,
+ type: 'leaf',
+ },
+ {
+ data: {},
+ size: 168,
+ type: 'leaf',
+ },
+ ],
+ size: 500,
+ type: 'branch',
+ },
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ ],
+ size: 500,
+ type: 'branch',
+ },
+ ],
+ size: 1000,
+ type: 'branch',
+ },
+ width: 1000,
+ });
+ expect(
+ gridview.element.querySelectorAll('.mock-grid-view').length
+ ).toBe(5);
+
+ gridview.removeView([1, 0, 1], Sizing.Distribute);
+
+ expect(gridview.serialize()).toEqual({
+ height: 1000,
+ orientation: 'HORIZONTAL',
+ root: {
+ data: [
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ {
+ data: [
+ {
+ data: [
+ {
+ data: {},
+ size: 250,
+ type: 'leaf',
+ },
+ {
+ data: {},
+ size: 250,
+ type: 'leaf',
+ },
+ ],
+ size: 500,
+ type: 'branch',
+ },
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ ],
+ size: 500,
+ type: 'branch',
+ },
+ ],
+ size: 1000,
+ type: 'branch',
+ },
+ width: 1000,
+ });
+ expect(
+ gridview.element.querySelectorAll('.mock-grid-view').length
+ ).toBe(4);
+ });
+
+ test('removeView: remove leaf where parent is root', () => {
+ const gridview = new Gridview(
+ false,
+ { separatorBorder: '' },
+ Orientation.HORIZONTAL
+ );
+ gridview.layout(1000, 1000);
+
+ gridview.addView(new MockGridview(), Sizing.Distribute, [0]);
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1]);
+
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1, 0]);
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1, 0, 0]);
+ gridview.addView(new MockGridview(), Sizing.Distribute, [1, 0, 1]);
+
+ expect(gridview.serialize()).toEqual({
+ height: 1000,
+ orientation: 'HORIZONTAL',
+ root: {
+ data: [
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ {
+ data: [
+ {
+ data: [
+ {
+ data: {},
+ size: 166,
+ type: 'leaf',
+ },
+ {
+ data: {},
+ size: 166,
+ type: 'leaf',
+ },
+ {
+ data: {},
+ size: 168,
+ type: 'leaf',
+ },
+ ],
+ size: 500,
+ type: 'branch',
+ },
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ ],
+ size: 500,
+ type: 'branch',
+ },
+ ],
+ size: 1000,
+ type: 'branch',
+ },
+ width: 1000,
+ });
+ expect(
+ gridview.element.querySelectorAll('.mock-grid-view').length
+ ).toBe(5);
+
+ gridview.removeView([1, 1], Sizing.Distribute);
+
+ expect(gridview.serialize()).toEqual({
+ height: 1000,
+ orientation: 'HORIZONTAL',
+ root: {
+ data: [
+ {
+ data: {},
+ size: 500,
+ type: 'leaf',
+ },
+ {
+ data: {},
+ size: 166,
+ type: 'leaf',
+ },
+ {
+ data: {},
+ size: 166,
+ type: 'leaf',
+ },
+ {
+ data: {},
+ size: 168,
+ type: 'leaf',
+ },
+ ],
+ size: 1000,
+ type: 'branch',
+ },
+ width: 1000,
+ });
+ expect(
+ gridview.element.querySelectorAll('.mock-grid-view').length
+ ).toBe(4);
+ });
});
From e3dd45a185da3200cb1aad6db657730c931a8cb5 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Sun, 11 Jun 2023 21:34:34 +0100
Subject: [PATCH 21/23] test: add tests
---
.../dockview/dockviewComponent.spec.ts | 113 ++++++++++--------
.../dockview-core/src/gridview/gridview.ts | 53 ++++++--
2 files changed, 100 insertions(+), 66 deletions(-)
diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts
index 67f317886..ae3659753 100644
--- a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts
+++ b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts
@@ -100,67 +100,67 @@ describe('dockviewComponent', () => {
});
});
- // test('event leakage', () => {
- // Emitter.setLeakageMonitorEnabled(true);
+ test('event leakage', () => {
+ Emitter.setLeakageMonitorEnabled(true);
- // dockview = new DockviewComponent({
- // parentElement: container,
- // components: {
- // default: PanelContentPartTest,
- // },
- // });
+ dockview = new DockviewComponent({
+ parentElement: container,
+ components: {
+ default: PanelContentPartTest,
+ },
+ });
- // dockview.layout(500, 1000);
+ dockview.layout(500, 1000);
- // dockview.addPanel({
- // id: 'panel1',
- // component: 'default',
- // });
+ dockview.addPanel({
+ id: 'panel1',
+ component: 'default',
+ });
- // const panel2 = dockview.addPanel({
- // id: 'panel2',
- // component: 'default',
- // });
+ const panel2 = dockview.addPanel({
+ id: 'panel2',
+ component: 'default',
+ });
- // dockview.removePanel(panel2);
+ dockview.removePanel(panel2);
- // const panel3 = dockview.addPanel({
- // id: 'panel3',
- // component: 'default',
- // position: {
- // direction: 'right',
- // referencePanel: 'panel1',
- // },
- // });
+ const panel3 = dockview.addPanel({
+ id: 'panel3',
+ component: 'default',
+ position: {
+ direction: 'right',
+ referencePanel: 'panel1',
+ },
+ });
- // const panel4 = dockview.addPanel({
- // id: 'panel4',
- // component: 'default',
- // position: {
- // direction: 'above',
- // },
- // });
+ const panel4 = dockview.addPanel({
+ id: 'panel4',
+ component: 'default',
+ position: {
+ direction: 'above',
+ },
+ });
- // dockview.moveGroupOrPanel(
- // panel4.group,
- // panel3.group.id,
- // panel3.id,
- // 'center'
- // );
+ dockview.moveGroupOrPanel(
+ panel4.group,
+ panel3.group.id,
+ panel3.id,
+ 'center'
+ );
- // dockview.dispose();
+ dockview.dispose();
- // if (Emitter.MEMORY_LEAK_WATCHER.size > 0) {
- // for (const entry of Array.from(
- // Emitter.MEMORY_LEAK_WATCHER.events
- // )) {
- // console.log('disposal', entry[1]);
- // }
- // throw new Error('not all listeners disposed');
- // }
+ if (Emitter.MEMORY_LEAK_WATCHER.size > 0) {
+ for (const entry of Array.from(
+ Emitter.MEMORY_LEAK_WATCHER.events
+ )) {
+ console.log('disposal', entry[1]);
+ }
+ throw new Error('not all listeners disposed');
+ }
- // Emitter.setLeakageMonitorEnabled(false);
- // });
+ Emitter.setLeakageMonitorEnabled(false);
+ });
test('duplicate panel', () => {
dockview.layout(500, 1000);
@@ -2449,7 +2449,7 @@ describe('dockviewComponent', () => {
});
});
- test('check', () => {
+ test('check dockview component is rendering to the DOM as expected', () => {
const container = document.createElement('div');
const dockview = new DockviewComponent({
@@ -2470,16 +2470,22 @@ describe('dockviewComponent', () => {
component: 'default',
});
+ expect(dockview.element.querySelectorAll('.view').length).toBe(1);
+
const panel2 = dockview.addPanel({
id: 'panel2',
component: 'default',
});
+ expect(dockview.element.querySelectorAll('.view').length).toBe(1);
+
const panel3 = dockview.addPanel({
id: 'panel3',
component: 'default',
});
+ expect(dockview.element.querySelectorAll('.view').length).toBe(1);
+
dockview.moveGroupOrPanel(
panel3.group,
panel3.group.id,
@@ -2488,6 +2494,7 @@ describe('dockviewComponent', () => {
);
expect(dockview.groups.length).toBe(2);
+ expect(dockview.element.querySelectorAll('.view').length).toBe(2);
dockview.moveGroupOrPanel(
panel3.group,
@@ -2497,6 +2504,7 @@ describe('dockviewComponent', () => {
);
expect(dockview.groups.length).toBe(3);
+ expect(dockview.element.querySelectorAll('.view').length).toBe(4);
dockview.moveGroupOrPanel(
panel2.group,
@@ -2507,7 +2515,6 @@ describe('dockviewComponent', () => {
expect(dockview.groups.length).toBe(2);
- const viewQuery = container.querySelectorAll('.split-view-container');
- expect(viewQuery).toBeTruthy();
+ expect(dockview.element.querySelectorAll('.view').length).toBe(2);
});
});
diff --git a/packages/dockview-core/src/gridview/gridview.ts b/packages/dockview-core/src/gridview/gridview.ts
index ee9d8f923..62c2ca9fb 100644
--- a/packages/dockview-core/src/gridview/gridview.ts
+++ b/packages/dockview-core/src/gridview/gridview.ts
@@ -678,60 +678,82 @@ export class Gridview implements IDisposable {
throw new Error('Invalid location');
}
- const node = parent.children[index];
+ const nodeToRemove = parent.children[index];
- if (!(node instanceof LeafNode)) {
+ if (!(nodeToRemove instanceof LeafNode)) {
throw new Error('Invalid location');
}
parent.removeChild(index, sizing);
+ nodeToRemove.dispose();
- if (parent.children.length === 0) {
- return node.view;
+ if (parent.children.length !== 1) {
+ return nodeToRemove.view;
}
- if (parent.children.length > 1) {
- return node.view;
- }
+ // if the parent has only one child and we know the parent is a BranchNode we can make the tree
+ // more efficiently spaced by replacing the parent BranchNode with the child.
+ // if that child is a LeafNode then we simply replace the BranchNode with the child otherwise if the child
+ // is a BranchNode too we should spread it's children into the grandparent.
+ // refer to the remaining child as the sibling
const sibling = parent.children[0];
if (pathToParent.length === 0) {
- // parent is root
+ // if the parent is root
if (sibling instanceof LeafNode) {
- return node.view;
+ // if the sibling is a leaf node no action is required
+ return nodeToRemove.view;
}
- // we must promote sibling to be the new root
+ // otherwise the sibling is a branch node. since the parent is the root and the root has only one child
+ // which is a branch node we can just set this branch node to be the new root node
+
+ // for good housekeeping we'll removing the sibling from it's existing tree
parent.removeChild(0, sizing);
+
+ // and set that sibling node to be root
this.root = sibling;
- return node.view;
+
+ return nodeToRemove.view;
}
+ // otherwise the parent is apart of a large sub-tree
+
const [grandParent, ..._] = [...pathToParent].reverse();
const [parentIndex, ...__] = [...rest].reverse();
const isSiblingVisible = parent.isChildVisible(0);
+
+ // either way we need to remove the sibling from it's existing tree
parent.removeChild(0, sizing);
+ // note the sizes of all of the grandparents children
const sizes = grandParent.children.map((_size, i) =>
grandParent.getChildSize(i)
);
- grandParent.removeChild(parentIndex, sizing);
+
+ // remove the parent from the grandparent since we are moving the sibling to take the parents place
+ // this parent is no longer used and can be disposed of
+ grandParent.removeChild(parentIndex, sizing).dispose();
if (sibling instanceof BranchNode) {
+ // replace the parent with the siblings children
sizes.splice(
parentIndex,
1,
...sibling.children.map((c) => c.size)
);
+ // and add those siblings to the grandparent
for (let i = 0; i < sibling.children.length; i++) {
const child = sibling.children[i];
grandParent.addChild(child, child.size, parentIndex + i);
}
} else {
+ // otherwise create a new leaf node and add that to the grandparent
+
const newSibling = new LeafNode(
sibling.view,
orthogonal(sibling.orientation),
@@ -740,14 +762,19 @@ export class Gridview implements IDisposable {
const siblingSizing = isSiblingVisible
? sibling.orthogonalSize
: Sizing.Invisible(sibling.orthogonalSize);
+
grandParent.addChild(newSibling, siblingSizing, parentIndex);
}
+ // the containing node of the sibling is no longer required and can be disposed of
+ sibling.dispose();
+
+ // resize everything
for (let i = 0; i < sizes.length; i++) {
grandParent.resizeChild(i, sizes[i]);
}
- return node.view;
+ return nodeToRemove.view;
}
public layout(width: number, height: number): void {
From 9e10814840067d97581402be8ae1b0f267548597 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Mon, 12 Jun 2023 21:36:24 +0100
Subject: [PATCH 22/23] Patch 1 (#278)
* Touch support for split view
* Attempting to make TS happy
* Making typescript happy round two
https://stackoverflow.com/questions/54688147/react-typescript-event-type-for-both-interfaces-mouseevent-and-touchevent
* make TS Happy
* Update splitview.ts
---------
Co-authored-by: Ray Foss
---
.../dockview-core/src/splitview/splitview.ts | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/packages/dockview-core/src/splitview/splitview.ts b/packages/dockview-core/src/splitview/splitview.ts
index fd68a4a29..a39c989e3 100644
--- a/packages/dockview-core/src/splitview/splitview.ts
+++ b/packages/dockview-core/src/splitview/splitview.ts
@@ -393,7 +393,8 @@ export class Splitview {
const sash = document.createElement('div');
sash.className = 'sash';
- const onStart = (event: MouseEvent) => {
+ const onStart = (nativeEvent: MouseEvent | TouchEvent) => {
+ const event = nativeEvent instanceof TouchEvent ? nativeEvent.touches[0] : nativeEvent;
for (const item of this.viewItems) {
item.enabled = false;
}
@@ -488,11 +489,12 @@ export class Splitview {
}
//
- const mousemove = (mousemoveEvent: MouseEvent) => {
+ const mousemove = (nativeMoveEvent: MouseEvent | TouchEvent) => {
+ const moveEvent = nativeMoveEvent instanceof TouchEvent ? nativeMoveEvent.touches[0] : nativeMoveEvent;
const current =
this._orientation === Orientation.HORIZONTAL
- ? mousemoveEvent.clientX
- : mousemoveEvent.clientY;
+ ? moveEvent.clientX
+ : moveEvent.clientY;
const delta = current - start;
this.resize(
@@ -523,15 +525,24 @@ export class Splitview {
document.removeEventListener('mousemove', mousemove);
document.removeEventListener('mouseup', end);
+ document.removeEventListener("touchmove", mousemove);
+ document.removeEventListener("touchend", end);
+ document.removeEventListener("touchcancel", end);
this._onDidSashEnd.fire(undefined);
+ return true // Consume, otherwise Monaco complains
};
document.addEventListener('mousemove', mousemove);
document.addEventListener('mouseup', end);
+ document.addEventListener("touchmove", mousemove);
+ document.addEventListener("touchend", end);
+ document.addEventListener("touchcancel", end);
+ return true // consume pull to refresh gesture
};
sash.addEventListener('mousedown', onStart);
+ sash.addEventListener("touchstart", onStart);
const sashItem: ISashItem = {
container: sash,
From 01544a995338037aca4858d968a3a9890260f1b5 Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Mon, 12 Jun 2023 21:41:46 +0100
Subject: [PATCH 23/23] feat: touch support refactor and test - add tests -
refactor methods to have a clear seperation between mouse and touch logic
---
.../src/__tests__/splitview/splitview.spec.ts | 86 +++++++++++++++++++
.../dockview-core/src/splitview/splitview.ts | 57 ++++++++----
2 files changed, 124 insertions(+), 19 deletions(-)
diff --git a/packages/dockview-core/src/__tests__/splitview/splitview.spec.ts b/packages/dockview-core/src/__tests__/splitview/splitview.spec.ts
index 7d14653d2..a93d7daf4 100644
--- a/packages/dockview-core/src/__tests__/splitview/splitview.spec.ts
+++ b/packages/dockview-core/src/__tests__/splitview/splitview.spec.ts
@@ -84,6 +84,8 @@ describe('splitview', () => {
beforeEach(() => {
container = document.createElement('div');
container.className = 'container';
+
+ jest.clearAllMocks();
});
test('vertical splitview', () => {
@@ -610,6 +612,12 @@ describe('splitview', () => {
splitview.addView(view1);
splitview.addView(view2);
+ const addEventListenerSpy = jest.spyOn(document, 'addEventListener');
+ const removeEventListenerSpy = jest.spyOn(
+ document,
+ 'removeEventListener'
+ );
+
const sashElement = container
.getElementsByClassName('sash')
.item(0) as HTMLElement;
@@ -623,6 +631,8 @@ describe('splitview', () => {
// start the drag event
fireEvent.mouseDown(sashElement, { clientX: 50, clientY: 100 });
+ expect(addEventListenerSpy).toBeCalledTimes(5);
+
// during a sash drag the views should have pointer-events disabled
expect(view1.element.parentElement!.style.pointerEvents).toBe('none');
expect(view2.element.parentElement!.style.pointerEvents).toBe('none');
@@ -638,6 +648,8 @@ describe('splitview', () => {
// end the drag event
fireEvent.mouseUp(document);
+ expect(removeEventListenerSpy).toBeCalledTimes(5);
+
// expect pointer-eventes on views to be restored
expect(view1.element.parentElement!.style.pointerEvents).toBe('');
expect(view2.element.parentElement!.style.pointerEvents).toBe('');
@@ -645,5 +657,79 @@ describe('splitview', () => {
fireEvent.mouseMove(document, { clientX: 100, clientY: 100 });
// expect no additional resizes
expect([view1.size, view2.size]).toEqual([225, 175]);
+ // expect no additional document listeners
+ expect(addEventListenerSpy).toBeCalledTimes(5);
+ expect(removeEventListenerSpy).toBeCalledTimes(5);
+ });
+
+ test('dnd: touch events to move sash', () => {
+ const splitview = new Splitview(container, {
+ orientation: Orientation.HORIZONTAL,
+ proportionalLayout: false,
+ });
+ splitview.layout(400, 500);
+
+ const view1 = new Testview(0, 1000);
+ const view2 = new Testview(0, 1000);
+
+ splitview.addView(view1);
+ splitview.addView(view2);
+
+ const addEventListenerSpy = jest.spyOn(document, 'addEventListener');
+ const removeEventListenerSpy = jest.spyOn(
+ document,
+ 'removeEventListener'
+ );
+
+ const sashElement = container
+ .getElementsByClassName('sash')
+ .item(0) as HTMLElement;
+
+ // validate the expected state before drag
+ expect([view1.size, view2.size]).toEqual([200, 200]);
+ expect(sashElement).toBeTruthy();
+ expect(view1.element.parentElement!.style.pointerEvents).toBe('');
+ expect(view2.element.parentElement!.style.pointerEvents).toBe('');
+
+ // start the drag event
+ fireEvent.touchStart(sashElement, {
+ touches: [{ clientX: 50, clientY: 100 }],
+ });
+
+ expect(addEventListenerSpy).toBeCalledTimes(5);
+
+ // during a sash drag the views should have pointer-events disabled
+ expect(view1.element.parentElement!.style.pointerEvents).toBe('none');
+ expect(view2.element.parentElement!.style.pointerEvents).toBe('none');
+
+ // expect a delta move of 70 - 50 = 20
+ fireEvent.touchMove(document, {
+ touches: [{ clientX: 70, clientY: 110 }],
+ });
+ expect([view1.size, view2.size]).toEqual([220, 180]);
+
+ // expect a delta move of 75 - 70 = 5
+ fireEvent.touchMove(document, {
+ touches: [{ clientX: 75, clientY: 110 }],
+ });
+ expect([view1.size, view2.size]).toEqual([225, 175]);
+
+ // end the drag event
+ fireEvent.touchEnd(document);
+
+ expect(removeEventListenerSpy).toBeCalledTimes(5);
+
+ // expect pointer-eventes on views to be restored
+ expect(view1.element.parentElement!.style.pointerEvents).toBe('');
+ expect(view2.element.parentElement!.style.pointerEvents).toBe('');
+
+ fireEvent.touchMove(document, {
+ touches: [{ clientX: 100, clientY: 100 }],
+ });
+ // expect no additional resizes
+ expect([view1.size, view2.size]).toEqual([225, 175]);
+ // expect no additional document listeners
+ expect(addEventListenerSpy).toBeCalledTimes(5);
+ expect(removeEventListenerSpy).toBeCalledTimes(5);
});
});
diff --git a/packages/dockview-core/src/splitview/splitview.ts b/packages/dockview-core/src/splitview/splitview.ts
index a39c989e3..98dcce6a8 100644
--- a/packages/dockview-core/src/splitview/splitview.ts
+++ b/packages/dockview-core/src/splitview/splitview.ts
@@ -393,8 +393,17 @@ export class Splitview {
const sash = document.createElement('div');
sash.className = 'sash';
- const onStart = (nativeEvent: MouseEvent | TouchEvent) => {
- const event = nativeEvent instanceof TouchEvent ? nativeEvent.touches[0] : nativeEvent;
+ const onTouchStart = (event: TouchEvent) => {
+ event.preventDefault();
+ const touch = event.touches[0];
+ onStart(touch);
+ };
+
+ const onMouseDown = (event: MouseEvent) => {
+ onStart(event);
+ };
+
+ const onStart = (event: { clientX: number; clientY: number }) => {
for (const item of this.viewItems) {
item.enabled = false;
}
@@ -487,14 +496,25 @@ export class Splitview {
size: snappedViewItem.size,
};
}
- //
- const mousemove = (nativeMoveEvent: MouseEvent | TouchEvent) => {
- const moveEvent = nativeMoveEvent instanceof TouchEvent ? nativeMoveEvent.touches[0] : nativeMoveEvent;
+ const onMouseMove = (event: MouseEvent) => {
+ reposition(event);
+ };
+
+ const onTouchMove = (event: TouchEvent) => {
+ event.preventDefault();
+ const touch = event.touches[0];
+ reposition(touch);
+ };
+
+ const reposition = (event: {
+ clientX: number;
+ clientY: number;
+ }) => {
const current =
this._orientation === Orientation.HORIZONTAL
- ? moveEvent.clientX
- : moveEvent.clientY;
+ ? event.clientX
+ : event.clientY;
const delta = current - start;
this.resize(
@@ -523,31 +543,30 @@ export class Splitview {
this.saveProportions();
- document.removeEventListener('mousemove', mousemove);
+ document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', end);
- document.removeEventListener("touchmove", mousemove);
- document.removeEventListener("touchend", end);
- document.removeEventListener("touchcancel", end);
+ document.removeEventListener('touchmove', onTouchMove);
+ document.removeEventListener('touchend', end);
+ document.removeEventListener('touchcancel', end);
this._onDidSashEnd.fire(undefined);
- return true // Consume, otherwise Monaco complains
};
- document.addEventListener('mousemove', mousemove);
+ document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', end);
- document.addEventListener("touchmove", mousemove);
- document.addEventListener("touchend", end);
- document.addEventListener("touchcancel", end);
- return true // consume pull to refresh gesture
+ document.addEventListener('touchmove', onTouchMove);
+ document.addEventListener('touchend', end);
+ document.addEventListener('touchcancel', end);
};
- sash.addEventListener('mousedown', onStart);
- sash.addEventListener("touchstart", onStart);
+ sash.addEventListener('mousedown', onMouseDown);
+ sash.addEventListener('touchstart', onTouchStart);
const sashItem: ISashItem = {
container: sash,
disposable: () => {
sash.removeEventListener('mousedown', onStart);
+ sash.removeEventListener('touchstart', onTouchStart);
this.sashContainer.removeChild(sash);
},
};