From 07f6616ae9d6d6f41f7f4b1cf6b3298eae4bb32a Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Thu, 26 May 2022 20:31:34 +0000
Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20=20@=2055e21?=
=?UTF-8?q?eacb3140bac6879375fb13e905599af1757=20=F0=9F=9A=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
build/.editorconfig | 10 +
build/.eslintignore | 2 +
build/.eslintrc.js | 19 +
build/.gitignore | 15 +
build/.prettierignore | 3 +
build/.prettierrc | 6 +
build/.vscode/extensions.json | 14 +
build/.vscode/settings.json | 1 +
build/LICENSE | 21 +
build/README.md | 52 +
build/docs/.gitignore | 20 +
build/docs/README.md | 41 +
build/docs/babel.config.js | 3 +
build/docs/blog/2022-05-11-dockview-1.4.1.mdx | 24 +
build/docs/blog/2022-05-16-dockview-1.4.2.mdx | 15 +
build/docs/blog/2022-05-26-dockview-1.4.3.mdx | 23 +
build/docs/blog/authors.yml | 17 +
build/docs/docs/api/_category_.json | 7 +
build/docs/docs/api/dockview.mdx | 285 +
build/docs/docs/api/gridview.mdx | 116 +
build/docs/docs/api/paneview.mdx | 185 +
build/docs/docs/api/splitview.mdx | 243 +
build/docs/docs/basics.mdx | 117 +
build/docs/docs/index.mdx | 150 +
build/docs/docs/theme.mdx | 80 +
build/docs/docusaurus.config.js | 170 +
build/docs/jsexamples/dockview.html | 27 +
build/docs/package.json | 54 +
build/docs/scripts/package-docs.js | 8 +
build/docs/sidebars.js | 31 +
.../src/components/HomepageFeatures/index.tsx | 70 +
.../HomepageFeatures/styles.module.css | 11 +
.../docs/src/components/console/console.scss | 27 +
build/docs/src/components/console/console.tsx | 52 +
.../src/components/dockview/contextMenu.tsx | 115 +
.../src/components/dockview/customCss.tsx | 58 +
build/docs/src/components/dockview/dnd.tsx | 105 +
build/docs/src/components/dockview/events.tsx | 342 +
.../src/components/dockview/rendering.tsx | 158 +
build/docs/src/components/gridview/events.tsx | 339 +
build/docs/src/components/release.tsx | 2 +
build/docs/src/components/simpleDockview.tsx | 116 +
build/docs/src/components/simpleGridview.tsx | 99 +
build/docs/src/components/simplePaneview.tsx | 102 +
build/docs/src/components/simpleSplitview.tsx | 54 +
.../docs/src/components/simpleSplitview2.tsx | 60 +
.../docs/src/components/splitview/active.tsx | 161 +
build/docs/src/components/splitview/math.scss | 63 +
build/docs/src/components/splitview/math.tsx | 342 +
build/docs/src/css/custom.css | 32 +
build/docs/src/misc/math/constraints.jpg | Bin 0 -> 137417 bytes
build/docs/src/misc/math/math.mdx | 378 +
build/docs/src/misc/math/visual_1.jpg | Bin 0 -> 35574 bytes
build/docs/src/pages/index.module.css | 23 +
build/docs/src/pages/index.tsx | 46 +
build/docs/src/pages/markdown-page.md | 7 +
build/docs/src/theme/Root.tsx | 7 +
build/docs/static/img/docusaurus.png | Bin 0 -> 5142 bytes
build/docs/static/img/favicon.ico | Bin 0 -> 3626 bytes
build/docs/static/img/logo.svg | 1 +
.../static/img/undraw_docusaurus_mountain.svg | 171 +
.../static/img/undraw_docusaurus_react.svg | 170 +
.../static/img/undraw_docusaurus_tree.svg | 40 +
build/docs/tsconfig.json | 7 +
build/docs/yarn.lock | 7764 ++++++++
build/jest.config.base.js | 20 +
build/jest.config.js | 17 +
build/lerna.json | 13 +
build/module-build/tsconfig.esm.json | 24 +
build/module-build/tsconfig.json | 24 +
build/package.json | 63 +
build/packages/dockview-demo/.eslintrc | 8 +
.../packages/dockview-demo/.storybook/main.js | 23 +
.../dockview-demo/.storybook/preview.js | 5 +
build/packages/dockview-demo/package.json | 51 +
.../packages/dockview-demo/public/index.html | 14 +
build/packages/dockview-demo/src/dom.ts | 13 +
build/packages/dockview-demo/src/events.ts | 122 +
build/packages/dockview-demo/src/index.scss | 66 +
build/packages/dockview-demo/src/index.tsx | 15 +
.../src/layout-grid/activitybar.scss | 34 +
.../src/layout-grid/activitybar.tsx | 71 +
.../src/layout-grid/application.tsx | 108 +
.../src/layout-grid/controlCenter.scss | 30 +
.../src/layout-grid/controlCenter.tsx | 150 +
.../src/layout-grid/customTab.tsx | 6 +
.../dockview-demo/src/layout-grid/footer.tsx | 27 +
.../src/layout-grid/layoutGrid.layout.json | 101 +
.../src/layout-grid/layoutGrid.scss | 22 +
.../src/layout-grid/layoutGrid.tsx | 334 +
.../dockview-demo/src/layout-grid/panel.tsx | 67 +
.../layout-grid/panels/exampleFunctions.scss | 14 +
.../layout-grid/panels/exampleFunctions.tsx | 102 +
.../dockview-demo/src/layout-grid/registry.ts | 25 +
.../src/layout-grid/settingsPanel.tsx | 38 +
.../src/layout-grid/sidebar.layout.json | 57 +
.../src/layout-grid/sidebar.scss | 18 +
.../dockview-demo/src/layout-grid/sidebar.tsx | 97 +
.../src/layout-grid/splitPanel.scss | 0
.../src/layout-grid/splitPanel.tsx | 145 +
.../src/layout-grid/splitpanel.layout.json | 29 +
build/packages/dockview-demo/src/lifecycle.ts | 54 +
.../src/panels/gridview/gridview.tsx | 328 +
.../src/panels/splitview/splitview.scss | 76 +
.../src/panels/splitview/splitview.tsx | 308 +
.../src/panels/welcome/welcome.scss | 33 +
.../src/panels/welcome/welcome.tsx | 53 +
.../src/resources/dockview-logo.svg | 16 +
.../src/resources/gridview-logo.svg | 8 +
.../dockview-demo/src/resources/logo.svg | 25 +
.../src/resources/paneview-logo.svg | 8 +
.../src/resources/splitview-logo.svg | 5 +
.../src/services/sidebarItem.tsx | 144 +
.../dockview-demo/src/services/view.ts | 64 +
.../src/services/viewContainer.ts | 126 +
.../src/services/viewRegistry.tsx | 94 +
.../dockview-demo/src/services/viewService.ts | 213 +
.../dockview-demo/src/services/widgets.scss | 32 +
.../dockview-demo/src/services/widgets.tsx | 474 +
.../src/stories/Introduction.stories.mdx | 64 +
.../src/stories/assets/code-brackets.svg | 1 +
.../src/stories/assets/colors.svg | 1 +
.../src/stories/assets/comments.svg | 1 +
.../src/stories/assets/direction.svg | 1 +
.../dockview-demo/src/stories/assets/flow.svg | 1 +
.../src/stories/assets/plugin.svg | 1 +
.../dockview-demo/src/stories/assets/repo.svg | 1 +
.../src/stories/assets/stackalt.svg | 1 +
.../dockview.documentation.stories.mdx | 7 +
.../dockview/dockview.iframe.stories.tsx | 108 +
.../dockview/dockview.params.stories.tsx | 126 +
.../dockview/dockview.simple.stories.tsx | 93 +
.../stories/dockview/dockview.tab.stories.tsx | 85 +
.../dockview/dockview.watermark.stories.tsx | 145 +
.../gridview.documentation.stories.mdx | 7 +
.../gridview/gridview.params.stories.tsx | 107 +
.../gridview/gridview.simple.stories.tsx | 137 +
.../src/stories/introduction.css | 100 +
.../paneview.deserialization.stories.tsx | 161 +
.../paneview.documentation.stories.mdx | 7 +
.../paneview/paneview.persistance.stories.tsx | 174 +
.../paneview/paneview.simple.stories.tsx | 145 +
.../src/stories/splitview/constraints.jpg | Bin 0 -> 137417 bytes
.../src/stories/splitview/splitview.css | 74 +
.../splitview.deserialization.stories.tsx | 122 +
.../splitview.documentation.stories.mdx | 349 +
.../splitview/splitview.params.stories.tsx | 107 +
.../splitview.persistance.stories.tsx | 138 +
.../splitview/splitview.simple.stories.tsx | 110 +
.../splitview/splitview.snap.stories.tsx | 104 +
.../src/stories/splitview/splitview.tsx | 341 +
.../src/stories/splitview/visual_1.jpg | Bin 0 -> 35574 bytes
build/packages/dockview-demo/tsconfig.json | 16 +
.../packages/dockview-demo/webpack.config.js | 52 +
build/packages/dockview/README.md | 52 +
build/packages/dockview/gulpfile.js | 6 +
build/packages/dockview/jest.config.js | 27 +
build/packages/dockview/package.json | 77 +
build/packages/dockview/rollup.config.js | 102 +
.../dockview/scripts/publishExperimental.js | 63 +
.../dockview/scripts/rollupEntryTarget.ts | 2 +
.../src/__tests__/__mocks__/resizeObserver.js | 13 +
.../src/__tests__/__test_utils__/utils.ts | 14 +
.../dockview/src/__tests__/api/api.spec.ts | 52 +
.../src/__tests__/api/component.api.spec.ts | 155 +
.../src/__tests__/api/groupPanelApi.spec.ts | 79 +
.../dockview/src/__tests__/array.spec.ts | 57 +
.../__tests__/dnd/abstractDragHandler.spec.ts | 87 +
.../src/__tests__/dnd/dataTransfer.spec.ts | 101 +
.../src/__tests__/dnd/droptarget.spec.ts | 162 +
.../dockview/defaultGroupPanelView.spec.ts | 46 +
.../dockview/dockviewComponent.spec.ts | 1692 ++
.../dockview/dockviewGroupPanel.spec.ts | 114 +
.../dockview/src/__tests__/events.spec.ts | 100 +
.../gridview/baseComponentGridview.spec.ts | 170 +
.../src/__tests__/gridview/gridview.spec.ts | 28 +
.../gridview/gridviewComponent.spec.ts | 1886 ++
.../src/__tests__/groupview/groupview.spec.ts | 571 +
.../__tests__/groupview/panel/content.spec.ts | 140 +
.../src/__tests__/groupview/tab.spec.ts | 25 +
.../dockview/src/__tests__/lifecycle.spec.ts | 51 +
.../dockview/src/__tests__/math.spec.ts | 17 +
.../__tests__/panel/componentFactory.spec.ts | 102 +
.../src/__tests__/paneview/paneview.spec.ts | 139 +
.../paneview/paneviewComponent.spec.ts | 404 +
.../react/dockview/dockview.spec.tsx | 52 +
.../react/gridview/gridview.spec.tsx | 65 +
.../react/paneview/paneview.spec.tsx | 52 +
.../src/__tests__/react/react.spec.tsx | 90 +
.../react/splitview/splitview.spec.tsx | 65 +
.../splitview/core/splitview.spec.ts | 589 +
.../splitview/splitviewComponent.spec.ts | 485 +
.../src/actionbar/actionsContainer.scss | 30 +
.../src/actionbar/actionsContainer.ts | 24 +
.../dockview/src/api/component.api.ts | 473 +
.../dockview/src/api/gridviewPanelApi.ts | 68 +
.../dockview/src/api/groupPanelApi.ts | 109 +
build/packages/dockview/src/api/panelApi.ts | 155 +
.../dockview/src/api/paneviewPanelApi.ts | 55 +
.../dockview/src/api/splitviewPanelApi.ts | 65 +
build/packages/dockview/src/array.ts | 84 +
.../dockview/src/dnd/abstractDragHandler.ts | 56 +
.../packages/dockview/src/dnd/dataTransfer.ts | 90 +
build/packages/dockview/src/dnd/dnd.ts | 86 +
.../packages/dockview/src/dnd/droptarget.scss | 55 +
build/packages/dockview/src/dnd/droptarget.ts | 235 +
.../dockview/components/tab/defaultTab.scss | 81 +
.../src/dockview/components/tab/defaultTab.ts | 111 +
.../components/watermark/watermark.scss | 21 +
.../components/watermark/watermark.ts | 107 +
.../src/dockview/defaultGroupPanelView.ts | 90 +
.../dockview/src/dockview/deserializer.ts | 6 +
.../src/dockview/dockviewComponent.scss | 83 +
.../src/dockview/dockviewComponent.ts | 817 +
.../src/dockview/dockviewGroupPanel.ts | 186 +
.../packages/dockview/src/dockview/options.ts | 99 +
build/packages/dockview/src/dom.ts | 166 +
build/packages/dockview/src/events.ts | 122 +
.../src/gridview/baseComponentGridview.ts | 318 +
.../dockview/src/gridview/basePanelView.ts | 134 +
.../dockview/src/gridview/branchNode.ts | 300 +
.../dockview/src/gridview/gridview.scss | 5 +
.../dockview/src/gridview/gridview.ts | 714 +
.../src/gridview/gridviewComponent.ts | 423 +
.../dockview/src/gridview/gridviewPanel.ts | 245 +
.../dockview/src/gridview/leafNode.ts | 134 +
.../packages/dockview/src/gridview/options.ts | 19 +
build/packages/dockview/src/gridview/types.ts | 4 +
build/packages/dockview/src/groupview/dnd.ts | 5 +
.../dockview/src/groupview/groupPanel.ts | 44 +
.../dockview/src/groupview/groupview.scss | 23 +
.../dockview/src/groupview/groupview.ts | 731 +
.../dockview/src/groupview/groupviewPanel.ts | 103 +
.../dockview/src/groupview/panel/content.ts | 120 +
build/packages/dockview/src/groupview/tab.ts | 157 +
.../src/groupview/titlebar/tabsContainer.scss | 60 +
.../src/groupview/titlebar/tabsContainer.ts | 306 +
.../packages/dockview/src/groupview/types.ts | 75 +
.../packages/dockview/src/hostedContainer.ts | 92 +
build/packages/dockview/src/index.ts | 59 +
build/packages/dockview/src/lifecycle.ts | 54 +
build/packages/dockview/src/math.ts | 11 +
.../dockview/src/panel/componentFactory.ts | 52 +
build/packages/dockview/src/panel/types.ts | 39 +
.../src/paneview/defaultPaneviewHeader.ts | 61 +
.../src/paneview/draggablePaneviewPanel.ts | 141 +
.../packages/dockview/src/paneview/options.ts | 26 +
.../dockview/src/paneview/paneview.scss | 116 +
.../dockview/src/paneview/paneview.ts | 214 +
.../src/paneview/paneviewComponent.ts | 472 +
.../dockview/src/paneview/paneviewPanel.ts | 331 +
.../dockview/src/react/deserializer.ts | 59 +
.../dockview/src/react/dockview/dockview.scss | 4 +
.../dockview/src/react/dockview/dockview.tsx | 236 +
.../src/react/dockview/reactContentPart.ts | 113 +
.../src/react/dockview/reactHeaderPart.ts | 69 +
.../src/react/dockview/reactWatermarkPart.ts | 88 +
.../react/dockview/v2/reactContentRenderer.ts | 105 +
.../react/dockview/v2/reactGroupPanelView.ts | 30 +
.../dockview/v2/webviewContentRenderer.ts | 59 +
.../dockview/src/react/gridview/gridview.tsx | 123 +
.../dockview/src/react/gridview/view.ts | 34 +
build/packages/dockview/src/react/index.ts | 9 +
.../dockview/src/react/paneview/paneview.tsx | 158 +
.../dockview/src/react/paneview/view.tsx | 55 +
build/packages/dockview/src/react/react.ts | 185 +
.../src/react/splitview/splitview.tsx | 117 +
.../dockview/src/react/splitview/view.ts | 31 +
build/packages/dockview/src/react/types.ts | 9 +
.../dockview/src/splitview/core/options.ts | 29 +
.../src/splitview/core/splitview.scss | 143 +
.../dockview/src/splitview/core/splitview.ts | 1050 +
.../dockview/src/splitview/core/viewItem.ts | 101 +
.../src/splitview/splitviewComponent.ts | 428 +
.../dockview/src/splitview/splitviewPanel.ts | 169 +
build/packages/dockview/src/theme.scss | 84 +
build/packages/dockview/src/types.ts | 9 +
build/packages/dockview/tsconfig.esm.json | 11 +
build/packages/dockview/tsconfig.json | 11 +
build/packages/dockview/typedoc.json | 7 +
build/scripts/build.js | 15 +
build/scripts/package-docs.js | 8 +
build/scripts/package.js | 15 +
build/sonar-project.properties | 20 +
build/tsconfig.eslint.json | 9 +
build/tsconfig.test.json | 22 +
build/yarn.lock | 16352 ++++++++++++++++
287 files changed, 56543 insertions(+)
create mode 100644 build/.editorconfig
create mode 100644 build/.eslintignore
create mode 100644 build/.eslintrc.js
create mode 100644 build/.gitignore
create mode 100644 build/.prettierignore
create mode 100644 build/.prettierrc
create mode 100644 build/.vscode/extensions.json
create mode 100644 build/.vscode/settings.json
create mode 100644 build/LICENSE
create mode 100644 build/README.md
create mode 100644 build/docs/.gitignore
create mode 100644 build/docs/README.md
create mode 100644 build/docs/babel.config.js
create mode 100644 build/docs/blog/2022-05-11-dockview-1.4.1.mdx
create mode 100644 build/docs/blog/2022-05-16-dockview-1.4.2.mdx
create mode 100644 build/docs/blog/2022-05-26-dockview-1.4.3.mdx
create mode 100644 build/docs/blog/authors.yml
create mode 100644 build/docs/docs/api/_category_.json
create mode 100644 build/docs/docs/api/dockview.mdx
create mode 100644 build/docs/docs/api/gridview.mdx
create mode 100644 build/docs/docs/api/paneview.mdx
create mode 100644 build/docs/docs/api/splitview.mdx
create mode 100644 build/docs/docs/basics.mdx
create mode 100644 build/docs/docs/index.mdx
create mode 100644 build/docs/docs/theme.mdx
create mode 100644 build/docs/docusaurus.config.js
create mode 100644 build/docs/jsexamples/dockview.html
create mode 100644 build/docs/package.json
create mode 100644 build/docs/scripts/package-docs.js
create mode 100644 build/docs/sidebars.js
create mode 100644 build/docs/src/components/HomepageFeatures/index.tsx
create mode 100644 build/docs/src/components/HomepageFeatures/styles.module.css
create mode 100644 build/docs/src/components/console/console.scss
create mode 100644 build/docs/src/components/console/console.tsx
create mode 100644 build/docs/src/components/dockview/contextMenu.tsx
create mode 100644 build/docs/src/components/dockview/customCss.tsx
create mode 100644 build/docs/src/components/dockview/dnd.tsx
create mode 100644 build/docs/src/components/dockview/events.tsx
create mode 100644 build/docs/src/components/dockview/rendering.tsx
create mode 100644 build/docs/src/components/gridview/events.tsx
create mode 100644 build/docs/src/components/release.tsx
create mode 100644 build/docs/src/components/simpleDockview.tsx
create mode 100644 build/docs/src/components/simpleGridview.tsx
create mode 100644 build/docs/src/components/simplePaneview.tsx
create mode 100644 build/docs/src/components/simpleSplitview.tsx
create mode 100644 build/docs/src/components/simpleSplitview2.tsx
create mode 100644 build/docs/src/components/splitview/active.tsx
create mode 100644 build/docs/src/components/splitview/math.scss
create mode 100644 build/docs/src/components/splitview/math.tsx
create mode 100644 build/docs/src/css/custom.css
create mode 100644 build/docs/src/misc/math/constraints.jpg
create mode 100644 build/docs/src/misc/math/math.mdx
create mode 100644 build/docs/src/misc/math/visual_1.jpg
create mode 100644 build/docs/src/pages/index.module.css
create mode 100644 build/docs/src/pages/index.tsx
create mode 100644 build/docs/src/pages/markdown-page.md
create mode 100644 build/docs/src/theme/Root.tsx
create mode 100644 build/docs/static/img/docusaurus.png
create mode 100644 build/docs/static/img/favicon.ico
create mode 100644 build/docs/static/img/logo.svg
create mode 100644 build/docs/static/img/undraw_docusaurus_mountain.svg
create mode 100644 build/docs/static/img/undraw_docusaurus_react.svg
create mode 100644 build/docs/static/img/undraw_docusaurus_tree.svg
create mode 100644 build/docs/tsconfig.json
create mode 100644 build/docs/yarn.lock
create mode 100644 build/jest.config.base.js
create mode 100644 build/jest.config.js
create mode 100644 build/lerna.json
create mode 100644 build/module-build/tsconfig.esm.json
create mode 100644 build/module-build/tsconfig.json
create mode 100644 build/package.json
create mode 100644 build/packages/dockview-demo/.eslintrc
create mode 100644 build/packages/dockview-demo/.storybook/main.js
create mode 100644 build/packages/dockview-demo/.storybook/preview.js
create mode 100644 build/packages/dockview-demo/package.json
create mode 100644 build/packages/dockview-demo/public/index.html
create mode 100644 build/packages/dockview-demo/src/dom.ts
create mode 100644 build/packages/dockview-demo/src/events.ts
create mode 100644 build/packages/dockview-demo/src/index.scss
create mode 100644 build/packages/dockview-demo/src/index.tsx
create mode 100644 build/packages/dockview-demo/src/layout-grid/activitybar.scss
create mode 100644 build/packages/dockview-demo/src/layout-grid/activitybar.tsx
create mode 100644 build/packages/dockview-demo/src/layout-grid/application.tsx
create mode 100644 build/packages/dockview-demo/src/layout-grid/controlCenter.scss
create mode 100644 build/packages/dockview-demo/src/layout-grid/controlCenter.tsx
create mode 100644 build/packages/dockview-demo/src/layout-grid/customTab.tsx
create mode 100644 build/packages/dockview-demo/src/layout-grid/footer.tsx
create mode 100644 build/packages/dockview-demo/src/layout-grid/layoutGrid.layout.json
create mode 100644 build/packages/dockview-demo/src/layout-grid/layoutGrid.scss
create mode 100644 build/packages/dockview-demo/src/layout-grid/layoutGrid.tsx
create mode 100644 build/packages/dockview-demo/src/layout-grid/panel.tsx
create mode 100644 build/packages/dockview-demo/src/layout-grid/panels/exampleFunctions.scss
create mode 100644 build/packages/dockview-demo/src/layout-grid/panels/exampleFunctions.tsx
create mode 100644 build/packages/dockview-demo/src/layout-grid/registry.ts
create mode 100644 build/packages/dockview-demo/src/layout-grid/settingsPanel.tsx
create mode 100644 build/packages/dockview-demo/src/layout-grid/sidebar.layout.json
create mode 100644 build/packages/dockview-demo/src/layout-grid/sidebar.scss
create mode 100644 build/packages/dockview-demo/src/layout-grid/sidebar.tsx
create mode 100644 build/packages/dockview-demo/src/layout-grid/splitPanel.scss
create mode 100644 build/packages/dockview-demo/src/layout-grid/splitPanel.tsx
create mode 100644 build/packages/dockview-demo/src/layout-grid/splitpanel.layout.json
create mode 100644 build/packages/dockview-demo/src/lifecycle.ts
create mode 100644 build/packages/dockview-demo/src/panels/gridview/gridview.tsx
create mode 100644 build/packages/dockview-demo/src/panels/splitview/splitview.scss
create mode 100644 build/packages/dockview-demo/src/panels/splitview/splitview.tsx
create mode 100644 build/packages/dockview-demo/src/panels/welcome/welcome.scss
create mode 100644 build/packages/dockview-demo/src/panels/welcome/welcome.tsx
create mode 100644 build/packages/dockview-demo/src/resources/dockview-logo.svg
create mode 100644 build/packages/dockview-demo/src/resources/gridview-logo.svg
create mode 100644 build/packages/dockview-demo/src/resources/logo.svg
create mode 100644 build/packages/dockview-demo/src/resources/paneview-logo.svg
create mode 100644 build/packages/dockview-demo/src/resources/splitview-logo.svg
create mode 100644 build/packages/dockview-demo/src/services/sidebarItem.tsx
create mode 100644 build/packages/dockview-demo/src/services/view.ts
create mode 100644 build/packages/dockview-demo/src/services/viewContainer.ts
create mode 100644 build/packages/dockview-demo/src/services/viewRegistry.tsx
create mode 100644 build/packages/dockview-demo/src/services/viewService.ts
create mode 100644 build/packages/dockview-demo/src/services/widgets.scss
create mode 100644 build/packages/dockview-demo/src/services/widgets.tsx
create mode 100644 build/packages/dockview-demo/src/stories/Introduction.stories.mdx
create mode 100644 build/packages/dockview-demo/src/stories/assets/code-brackets.svg
create mode 100644 build/packages/dockview-demo/src/stories/assets/colors.svg
create mode 100644 build/packages/dockview-demo/src/stories/assets/comments.svg
create mode 100644 build/packages/dockview-demo/src/stories/assets/direction.svg
create mode 100644 build/packages/dockview-demo/src/stories/assets/flow.svg
create mode 100644 build/packages/dockview-demo/src/stories/assets/plugin.svg
create mode 100644 build/packages/dockview-demo/src/stories/assets/repo.svg
create mode 100644 build/packages/dockview-demo/src/stories/assets/stackalt.svg
create mode 100644 build/packages/dockview-demo/src/stories/dockview/dockview.documentation.stories.mdx
create mode 100644 build/packages/dockview-demo/src/stories/dockview/dockview.iframe.stories.tsx
create mode 100644 build/packages/dockview-demo/src/stories/dockview/dockview.params.stories.tsx
create mode 100644 build/packages/dockview-demo/src/stories/dockview/dockview.simple.stories.tsx
create mode 100644 build/packages/dockview-demo/src/stories/dockview/dockview.tab.stories.tsx
create mode 100644 build/packages/dockview-demo/src/stories/dockview/dockview.watermark.stories.tsx
create mode 100644 build/packages/dockview-demo/src/stories/gridview/gridview.documentation.stories.mdx
create mode 100644 build/packages/dockview-demo/src/stories/gridview/gridview.params.stories.tsx
create mode 100644 build/packages/dockview-demo/src/stories/gridview/gridview.simple.stories.tsx
create mode 100644 build/packages/dockview-demo/src/stories/introduction.css
create mode 100644 build/packages/dockview-demo/src/stories/paneview/paneview.deserialization.stories.tsx
create mode 100644 build/packages/dockview-demo/src/stories/paneview/paneview.documentation.stories.mdx
create mode 100644 build/packages/dockview-demo/src/stories/paneview/paneview.persistance.stories.tsx
create mode 100644 build/packages/dockview-demo/src/stories/paneview/paneview.simple.stories.tsx
create mode 100644 build/packages/dockview-demo/src/stories/splitview/constraints.jpg
create mode 100644 build/packages/dockview-demo/src/stories/splitview/splitview.css
create mode 100644 build/packages/dockview-demo/src/stories/splitview/splitview.deserialization.stories.tsx
create mode 100644 build/packages/dockview-demo/src/stories/splitview/splitview.documentation.stories.mdx
create mode 100644 build/packages/dockview-demo/src/stories/splitview/splitview.params.stories.tsx
create mode 100644 build/packages/dockview-demo/src/stories/splitview/splitview.persistance.stories.tsx
create mode 100644 build/packages/dockview-demo/src/stories/splitview/splitview.simple.stories.tsx
create mode 100644 build/packages/dockview-demo/src/stories/splitview/splitview.snap.stories.tsx
create mode 100644 build/packages/dockview-demo/src/stories/splitview/splitview.tsx
create mode 100644 build/packages/dockview-demo/src/stories/splitview/visual_1.jpg
create mode 100644 build/packages/dockview-demo/tsconfig.json
create mode 100644 build/packages/dockview-demo/webpack.config.js
create mode 100644 build/packages/dockview/README.md
create mode 100644 build/packages/dockview/gulpfile.js
create mode 100644 build/packages/dockview/jest.config.js
create mode 100644 build/packages/dockview/package.json
create mode 100644 build/packages/dockview/rollup.config.js
create mode 100644 build/packages/dockview/scripts/publishExperimental.js
create mode 100644 build/packages/dockview/scripts/rollupEntryTarget.ts
create mode 100644 build/packages/dockview/src/__tests__/__mocks__/resizeObserver.js
create mode 100644 build/packages/dockview/src/__tests__/__test_utils__/utils.ts
create mode 100644 build/packages/dockview/src/__tests__/api/api.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/api/component.api.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/api/groupPanelApi.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/array.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/dnd/abstractDragHandler.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/dnd/dataTransfer.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/dnd/droptarget.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/dockview/defaultGroupPanelView.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/dockview/dockviewComponent.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/dockview/dockviewGroupPanel.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/events.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/gridview/baseComponentGridview.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/gridview/gridview.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/gridview/gridviewComponent.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/groupview/groupview.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/groupview/panel/content.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/groupview/tab.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/lifecycle.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/math.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/panel/componentFactory.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/paneview/paneview.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/paneview/paneviewComponent.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/react/dockview/dockview.spec.tsx
create mode 100644 build/packages/dockview/src/__tests__/react/gridview/gridview.spec.tsx
create mode 100644 build/packages/dockview/src/__tests__/react/paneview/paneview.spec.tsx
create mode 100644 build/packages/dockview/src/__tests__/react/react.spec.tsx
create mode 100644 build/packages/dockview/src/__tests__/react/splitview/splitview.spec.tsx
create mode 100644 build/packages/dockview/src/__tests__/splitview/core/splitview.spec.ts
create mode 100644 build/packages/dockview/src/__tests__/splitview/splitviewComponent.spec.ts
create mode 100644 build/packages/dockview/src/actionbar/actionsContainer.scss
create mode 100644 build/packages/dockview/src/actionbar/actionsContainer.ts
create mode 100644 build/packages/dockview/src/api/component.api.ts
create mode 100644 build/packages/dockview/src/api/gridviewPanelApi.ts
create mode 100644 build/packages/dockview/src/api/groupPanelApi.ts
create mode 100644 build/packages/dockview/src/api/panelApi.ts
create mode 100644 build/packages/dockview/src/api/paneviewPanelApi.ts
create mode 100644 build/packages/dockview/src/api/splitviewPanelApi.ts
create mode 100644 build/packages/dockview/src/array.ts
create mode 100644 build/packages/dockview/src/dnd/abstractDragHandler.ts
create mode 100644 build/packages/dockview/src/dnd/dataTransfer.ts
create mode 100644 build/packages/dockview/src/dnd/dnd.ts
create mode 100644 build/packages/dockview/src/dnd/droptarget.scss
create mode 100644 build/packages/dockview/src/dnd/droptarget.ts
create mode 100644 build/packages/dockview/src/dockview/components/tab/defaultTab.scss
create mode 100644 build/packages/dockview/src/dockview/components/tab/defaultTab.ts
create mode 100644 build/packages/dockview/src/dockview/components/watermark/watermark.scss
create mode 100644 build/packages/dockview/src/dockview/components/watermark/watermark.ts
create mode 100644 build/packages/dockview/src/dockview/defaultGroupPanelView.ts
create mode 100644 build/packages/dockview/src/dockview/deserializer.ts
create mode 100644 build/packages/dockview/src/dockview/dockviewComponent.scss
create mode 100644 build/packages/dockview/src/dockview/dockviewComponent.ts
create mode 100644 build/packages/dockview/src/dockview/dockviewGroupPanel.ts
create mode 100644 build/packages/dockview/src/dockview/options.ts
create mode 100644 build/packages/dockview/src/dom.ts
create mode 100644 build/packages/dockview/src/events.ts
create mode 100644 build/packages/dockview/src/gridview/baseComponentGridview.ts
create mode 100644 build/packages/dockview/src/gridview/basePanelView.ts
create mode 100644 build/packages/dockview/src/gridview/branchNode.ts
create mode 100644 build/packages/dockview/src/gridview/gridview.scss
create mode 100644 build/packages/dockview/src/gridview/gridview.ts
create mode 100644 build/packages/dockview/src/gridview/gridviewComponent.ts
create mode 100644 build/packages/dockview/src/gridview/gridviewPanel.ts
create mode 100644 build/packages/dockview/src/gridview/leafNode.ts
create mode 100644 build/packages/dockview/src/gridview/options.ts
create mode 100644 build/packages/dockview/src/gridview/types.ts
create mode 100644 build/packages/dockview/src/groupview/dnd.ts
create mode 100644 build/packages/dockview/src/groupview/groupPanel.ts
create mode 100644 build/packages/dockview/src/groupview/groupview.scss
create mode 100644 build/packages/dockview/src/groupview/groupview.ts
create mode 100644 build/packages/dockview/src/groupview/groupviewPanel.ts
create mode 100644 build/packages/dockview/src/groupview/panel/content.ts
create mode 100644 build/packages/dockview/src/groupview/tab.ts
create mode 100644 build/packages/dockview/src/groupview/titlebar/tabsContainer.scss
create mode 100644 build/packages/dockview/src/groupview/titlebar/tabsContainer.ts
create mode 100644 build/packages/dockview/src/groupview/types.ts
create mode 100644 build/packages/dockview/src/hostedContainer.ts
create mode 100644 build/packages/dockview/src/index.ts
create mode 100644 build/packages/dockview/src/lifecycle.ts
create mode 100644 build/packages/dockview/src/math.ts
create mode 100644 build/packages/dockview/src/panel/componentFactory.ts
create mode 100644 build/packages/dockview/src/panel/types.ts
create mode 100644 build/packages/dockview/src/paneview/defaultPaneviewHeader.ts
create mode 100644 build/packages/dockview/src/paneview/draggablePaneviewPanel.ts
create mode 100644 build/packages/dockview/src/paneview/options.ts
create mode 100644 build/packages/dockview/src/paneview/paneview.scss
create mode 100644 build/packages/dockview/src/paneview/paneview.ts
create mode 100644 build/packages/dockview/src/paneview/paneviewComponent.ts
create mode 100644 build/packages/dockview/src/paneview/paneviewPanel.ts
create mode 100644 build/packages/dockview/src/react/deserializer.ts
create mode 100644 build/packages/dockview/src/react/dockview/dockview.scss
create mode 100644 build/packages/dockview/src/react/dockview/dockview.tsx
create mode 100644 build/packages/dockview/src/react/dockview/reactContentPart.ts
create mode 100644 build/packages/dockview/src/react/dockview/reactHeaderPart.ts
create mode 100644 build/packages/dockview/src/react/dockview/reactWatermarkPart.ts
create mode 100644 build/packages/dockview/src/react/dockview/v2/reactContentRenderer.ts
create mode 100644 build/packages/dockview/src/react/dockview/v2/reactGroupPanelView.ts
create mode 100644 build/packages/dockview/src/react/dockview/v2/webviewContentRenderer.ts
create mode 100644 build/packages/dockview/src/react/gridview/gridview.tsx
create mode 100644 build/packages/dockview/src/react/gridview/view.ts
create mode 100644 build/packages/dockview/src/react/index.ts
create mode 100644 build/packages/dockview/src/react/paneview/paneview.tsx
create mode 100644 build/packages/dockview/src/react/paneview/view.tsx
create mode 100644 build/packages/dockview/src/react/react.ts
create mode 100644 build/packages/dockview/src/react/splitview/splitview.tsx
create mode 100644 build/packages/dockview/src/react/splitview/view.ts
create mode 100644 build/packages/dockview/src/react/types.ts
create mode 100644 build/packages/dockview/src/splitview/core/options.ts
create mode 100644 build/packages/dockview/src/splitview/core/splitview.scss
create mode 100644 build/packages/dockview/src/splitview/core/splitview.ts
create mode 100644 build/packages/dockview/src/splitview/core/viewItem.ts
create mode 100644 build/packages/dockview/src/splitview/splitviewComponent.ts
create mode 100644 build/packages/dockview/src/splitview/splitviewPanel.ts
create mode 100644 build/packages/dockview/src/theme.scss
create mode 100644 build/packages/dockview/src/types.ts
create mode 100644 build/packages/dockview/tsconfig.esm.json
create mode 100644 build/packages/dockview/tsconfig.json
create mode 100644 build/packages/dockview/typedoc.json
create mode 100644 build/scripts/build.js
create mode 100644 build/scripts/package-docs.js
create mode 100644 build/scripts/package.js
create mode 100644 build/sonar-project.properties
create mode 100644 build/tsconfig.eslint.json
create mode 100644 build/tsconfig.test.json
create mode 100644 build/yarn.lock
diff --git a/build/.editorconfig b/build/.editorconfig
new file mode 100644
index 000000000..c5337b8b6
--- /dev/null
+++ b/build/.editorconfig
@@ -0,0 +1,10 @@
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+quote_type = single
\ No newline at end of file
diff --git a/build/.eslintignore b/build/.eslintignore
new file mode 100644
index 000000000..15755e534
--- /dev/null
+++ b/build/.eslintignore
@@ -0,0 +1,2 @@
+dist/
+*.scss
\ No newline at end of file
diff --git a/build/.eslintrc.js b/build/.eslintrc.js
new file mode 100644
index 000000000..f9ad98125
--- /dev/null
+++ b/build/.eslintrc.js
@@ -0,0 +1,19 @@
+module.exports = {
+ root: true,
+ parserOptions: {
+ sourceType: 'module',
+ project: ['./tsconfig.eslint.json', './packages/*/tsconfig.json'],
+ tsconfigRootDir: __dirname,
+ },
+ plugins: ['@typescript-eslint'],
+ extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
+ rules: {
+ 'no-case-declarations': 'off',
+ '@typescript-eslint/no-namespace': 'off',
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
+ '@typescript-eslint/no-explicit-any': 'off',
+ '@typescript-eslint/no-unused-vars': 'off',
+ '@typescript-eslint/ban-types': 'off',
+ '@typescript-eslint/no-non-null-assertion': 'off',
+ },
+};
diff --git a/build/.gitignore b/build/.gitignore
new file mode 100644
index 000000000..5f1ae726d
--- /dev/null
+++ b/build/.gitignore
@@ -0,0 +1,15 @@
+node_modules/
+coverage/
+dist/
+output/
+.idea/
+typedocs/
+.DS_Store
+*-debug.log
+.build
+storybook-static/
+.rollup.cache/
+test-report.xml
+*.code-workspace
+yarn-error.log
+/build
diff --git a/build/.prettierignore b/build/.prettierignore
new file mode 100644
index 000000000..22f8a40ab
--- /dev/null
+++ b/build/.prettierignore
@@ -0,0 +1,3 @@
+typedocs/
+dist/
+build/
\ No newline at end of file
diff --git a/build/.prettierrc b/build/.prettierrc
new file mode 100644
index 000000000..f91488470
--- /dev/null
+++ b/build/.prettierrc
@@ -0,0 +1,6 @@
+{
+ "trailingComma": "es5",
+ "tabWidth": 4,
+ "semi": true,
+ "singleQuote": true
+}
diff --git a/build/.vscode/extensions.json b/build/.vscode/extensions.json
new file mode 100644
index 000000000..9e9271d02
--- /dev/null
+++ b/build/.vscode/extensions.json
@@ -0,0 +1,14 @@
+{
+ // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
+ // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
+
+ // List of extensions which should be recommended for users of this workspace.
+ "recommendations": [
+ "esbenp.prettier-vscode",
+ "redhat.vscode-yaml",
+ "dbaeumer.vscode-eslint",
+ "editorconfig.editorconfig"
+ ],
+ // List of extensions recommended by VS Code that should not be recommended for users of this workspace.
+ "unwantedRecommendations": []
+}
diff --git a/build/.vscode/settings.json b/build/.vscode/settings.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/build/.vscode/settings.json
@@ -0,0 +1 @@
+{}
diff --git a/build/LICENSE b/build/LICENSE
new file mode 100644
index 000000000..7ec9c3431
--- /dev/null
+++ b/build/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 mathuo
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/build/README.md b/build/README.md
new file mode 100644
index 000000000..1983f0c99
--- /dev/null
+++ b/build/README.md
@@ -0,0 +1,52 @@
+
+
dockview
+
+
Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support written in TypeScript
+
+
+
+---
+
+[![npm version](https://badge.fury.io/js/dockview.svg)](https://www.npmjs.com/package/dockview)
+[![CI Build](https://github.com/mathuo/dockview/workflows/CI/badge.svg)](https://github.com/mathuo/dockview/actions?query=workflow%3ACI)
+[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=mathuo_dockview&metric=coverage)](https://sonarcloud.io/summary/overall?id=mathuo_dockview)
+[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=mathuo_dockview&metric=alert_status)](https://sonarcloud.io/summary/overall?id=mathuo_dockview)
+[![Bundle Phobia](https://badgen.net/bundlephobia/minzip/dockview)](https://bundlephobia.com/result?p=dockview)
+
+##
+
+Please see the website: https://mathuo.github.io/dockview/docs
+
+Want to inspect the latest deployment? Go to https://unpkg.com/browse/dockview@latest/
+
+## Features
+
+- Simple splitviews, nested splitviews (i.e. gridviews) supporting full layout managment with
+ dockable and tabular views
+- Extensive API support at the component level and view level
+- Themable and customizable
+- Serialization / deserialization support
+- Tabular docking and Drag and Drop support
+- Documentation and examples
+
+This project was inspired by many popular IDE editors. Some parts of the core resizable panelling are inspired by code found in the VSCode codebase, [splitview](https://github.com/microsoft/vscode/tree/main/src/vs/base/browser/ui/splitview) and [gridview](https://github.com/microsoft/vscode/tree/main/src/vs/base/browser/ui/grid).
+
+## Quick start
+
+Dockview has a peer dependency on `react >= 16.8.0` and `react-dom >= 16.8.0`. You can install dockview from [npm](https://www.npmjs.com/package/dockview). Please see the [Getting Started Guide](https://mathuo.github.io/dockview/docs/).
+
+```
+npm install --save dockview
+```
+
+Within your project you must import or reference the stylesheet at `dockview/dist/styles/dockview.css` and attach a theme.
+
+```css
+@import '~dockview/dist/styles/dockview.css';
+```
+
+You should also attach a dockview theme to an element containing your components. For example:
+
+```html
+
+```
diff --git a/build/docs/.gitignore b/build/docs/.gitignore
new file mode 100644
index 000000000..b2d6de306
--- /dev/null
+++ b/build/docs/.gitignore
@@ -0,0 +1,20 @@
+# Dependencies
+/node_modules
+
+# Production
+/build
+
+# Generated files
+.docusaurus
+.cache-loader
+
+# Misc
+.DS_Store
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
diff --git a/build/docs/README.md b/build/docs/README.md
new file mode 100644
index 000000000..aaba2fa1e
--- /dev/null
+++ b/build/docs/README.md
@@ -0,0 +1,41 @@
+# Website
+
+This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
+
+### Installation
+
+```
+$ yarn
+```
+
+### Local Development
+
+```
+$ yarn start
+```
+
+This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
+
+### Build
+
+```
+$ yarn build
+```
+
+This command generates static content into the `build` directory and can be served using any static contents hosting service.
+
+### Deployment
+
+Using SSH:
+
+```
+$ USE_SSH=true yarn deploy
+```
+
+Not using SSH:
+
+```
+$ GIT_USER= yarn deploy
+```
+
+If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
diff --git a/build/docs/babel.config.js b/build/docs/babel.config.js
new file mode 100644
index 000000000..e00595dae
--- /dev/null
+++ b/build/docs/babel.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
+};
diff --git a/build/docs/blog/2022-05-11-dockview-1.4.1.mdx b/build/docs/blog/2022-05-11-dockview-1.4.1.mdx
new file mode 100644
index 000000000..13ebcad79
--- /dev/null
+++ b/build/docs/blog/2022-05-11-dockview-1.4.1.mdx
@@ -0,0 +1,24 @@
+---
+slug: dockview-1.4.1-release
+title: Dockview 1.4.1
+tags: [release]
+---
+
+# Release Notes
+
+## π Features
+
+- Fix Drag and Drop issues in Dockview on Firefox [#103](https://github.com/mathuo/dockview/pull/103)
+
+## π Miscs
+
+- Documentation enhancements https://mathuo.github.io/dockview/docs/
+
+## π₯ Breaking changes
+
+All breaking changes here are designed to simplify the library with only one way to do something.
+
+- Remove `setVisible` and `setActive` from the Splitview API. You can still achieve the same behaviors through calling `setVisible` and `setActive` on the Splitview Panel API. [#105](https://github.com/mathuo/dockview/pull/105)
+- Remove `setVisible`, `setActive` and `toggleVisiblity` from Gridview API. You can still achieve the same behaviors through calling `setVisible` and `setActive` on the Gridview Panel API [#105](https://github.com/mathuo/dockview/pull/105)
+- Remove `onFocusEvent` from Panel API as this was not intended to be a public method. You can use `onDidFocusChange` instead [#105](https://github.com/mathuo/dockview/pull/105)
+- Remove HOC ``, ``, `` and `` [#105](https://github.com/mathuo/dockview/pull/105)
diff --git a/build/docs/blog/2022-05-16-dockview-1.4.2.mdx b/build/docs/blog/2022-05-16-dockview-1.4.2.mdx
new file mode 100644
index 000000000..9b1323c21
--- /dev/null
+++ b/build/docs/blog/2022-05-16-dockview-1.4.2.mdx
@@ -0,0 +1,15 @@
+---
+slug: dockview-1.4.2-release
+title: Dockview 1.4.2
+tags: [release]
+---
+
+# Release Notes
+
+## π Features
+
+- Fix deserialization issue where previously active panel wasn't display correctly after deserialization [#108](https://github.com/mathuo/dockview/pull/108)
+
+## π₯ Breaking changes
+
+- Rename `onDidAddGroup` to `onDidAddPanel`, `onDidRemoveGroup` to `onDidRemovePanel` and `onDidActiveGroupChange` to `onDidActivePanelChange` on the Gridview API [#106](https://github.com/mathuo/dockview/pull/106)
diff --git a/build/docs/blog/2022-05-26-dockview-1.4.3.mdx b/build/docs/blog/2022-05-26-dockview-1.4.3.mdx
new file mode 100644
index 000000000..9f3b8f359
--- /dev/null
+++ b/build/docs/blog/2022-05-26-dockview-1.4.3.mdx
@@ -0,0 +1,23 @@
+---
+slug: dockview-1.4.3-release
+title: Dockview 1.4.3
+tags: [release]
+---
+
+# Release Notes
+
+## π Features
+
+- Small adjusted to behaviours of default paneview header componnet [#116](https://github.com/mathuo/dockview/pull/116) [#120](https://github.com/mathuo/dockview/pull/120)
+- Improved support for external dnd events in the dockview component. `showDndOverlay` prop on `DockviewReact` exposes more parameters to interact with [#110](https://github.com/mathuo/dockview/pull/110)
+- Improved to underlying events exposes through all components [#114](https://github.com/mathuo/dockview/pull/114)
+- Add .clear() to the component APIs providing an easy way to clear a layout [#119](https://github.com/mathuo/dockview/pull/119)
+- Udate orientation via componnet APIs is now working correctly [#119](https://github.com/mathuo/dockview/pull/119)
+
+## π Miscs
+
+- Documentation enhancements https://mathuo.github.io/dockview/docs/ [#101](https://github.com/mathuo/dockview/pull/101)
+
+## π₯ Breaking changes
+
+- Fix typo by renaming `onDidLayoutfromJSON` to `onDidLayoutFromJSON` in dockview component api [#112](https://github.com/mathuo/dockview/pull/112/files)
diff --git a/build/docs/blog/authors.yml b/build/docs/blog/authors.yml
new file mode 100644
index 000000000..bcb299156
--- /dev/null
+++ b/build/docs/blog/authors.yml
@@ -0,0 +1,17 @@
+endi:
+ name: Endilie Yacop Sucipto
+ title: Maintainer of Docusaurus
+ url: https://github.com/endiliey
+ image_url: https://github.com/endiliey.png
+
+yangshun:
+ name: Yangshun Tay
+ title: Front End Engineer @ Facebook
+ url: https://github.com/yangshun
+ image_url: https://github.com/yangshun.png
+
+slorber:
+ name: SΓ©bastien Lorber
+ title: Docusaurus maintainer
+ url: https://sebastienlorber.com
+ image_url: https://github.com/slorber.png
diff --git a/build/docs/docs/api/_category_.json b/build/docs/docs/api/_category_.json
new file mode 100644
index 000000000..234c2c6d5
--- /dev/null
+++ b/build/docs/docs/api/_category_.json
@@ -0,0 +1,7 @@
+{
+ "label": "API",
+ "position": 2,
+ "link": {
+ "type": "generated-index"
+ }
+}
diff --git a/build/docs/docs/api/dockview.mdx b/build/docs/docs/api/dockview.mdx
new file mode 100644
index 000000000..dc00eb9df
--- /dev/null
+++ b/build/docs/docs/api/dockview.mdx
@@ -0,0 +1,285 @@
+import { SimpleDockview } from '../../src/components/simpleDockview';
+import {
+ RenderingDockview,
+ Checkbox,
+} from '../../src/components/dockview/rendering';
+import { DndDockview } from '../../src/components/dockview/dnd';
+import { EventsDockview } from '../../src/components/dockview/events';
+import Link from '@docusaurus/Link';
+
+# Dockview
+
+## Introduction
+
+Dockview is an abstraction built on top of [Gridviews](/docs/api/gridview) where each view is a tabbed container.
+
+
+
+
+
+```tsx
+const panel = event.api.addPanel(...);
+const anotherPanel = event.api.getPanel('somePanelid');
+```
+
+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
+
+```tsx
+import { ReactDockview } from 'dockview';
+```
+
+| Property | Type | Optional | Default | Description |
+| ------------------- | ------------------------------------ | -------- | ------- | --------------------------------------------------------------- |
+| onReady | (event: SplitviewReadyEvent) => void | No | | |
+| components | object | No | | |
+| tabComponents | object | Yes | | |
+| watermarkComponent | object | Yes | | |
+| hideBorders | boolean | Yes | false | |
+| className | string | Yes | '' | |
+| disableAutoResizing | boolean | Yes | false | See Auto Resizing |
+| onTabContextMenu | Event | Yes | false | |
+| onDidDrop | Event | Yes | false | |
+| showDndOverlay | Event | Yes | false | |
+
+## Dockview API
+
+```tsx
+const MyComponent = (props: IDockviewPanelProps<{ title: string }>) => {
+ // props.containerApi...
+
+ return {`My first panel has the title: ${props.params.title}`}
;
+};
+```
+
+```tsx
+const onReady = (event: DockviewReadyEvent) => {
+ // event.api...
+};
+```
+
+| Property | Type | Description |
+| ---------------------- | ---------------------------------------------------- | ----------------------------------------------------------- |
+| height | `number` | Component pixel height |
+| width | `number` | Component pixel width |
+| minimumHeight | `number` | |
+| maximumHeight | `number` | |
+| maximumWidth | `number` | |
+| maximumWidth | `number` | |
+| length | `number` | Number of panels |
+| size | `number` | Number of Groups |
+| panels | `IDockviewPanel[]` | |
+| groups | `GroupPanel[]` | |
+| activePanel | `IDockviewPanel \| undefined` | |
+| activeGroup | `IDockviewPanel \| undefined` | |
+| | | |
+| onDidLayoutChange | `Event` | |
+| onDidLayoutFromJSON | `Event` | |
+| onDidAddGroup | `Event` | |
+| onDidRemoveGroup | `Event` | |
+| onDidActiveGroupChange | `Event` | |
+| onDidAddPanel | `Event` | |
+| onDidRemovePanel | `Event` | |
+| onDidActivePanelChange | `Event` | |
+| onDidDrop | `EventAuto Resizing |
+| fromJSON | `(data: SerializedDockview): void` | Serialization |
+| toJSON | `(): SerializedDockview` | Serialization |
+| clear | `(): void` | Clears the current layout |
+
+## Dockview Panel API
+
+```tsx
+const MyComponent = (props: IDockviewPanelProps<{ title: string }>) => {
+ // props.api...
+
+ return {`My first panel has the title: ${props.params.title}`}
;
+};
+```
+
+| Property | Type | Description |
+| ---------------------- | ----------------------------------------------------------- | --------------- |
+| id | `string` | Panel id |
+| isFocused | `boolean` | Is panel focsed |
+| isActive | `boolean` | Is panel active |
+| width | `number` | Panel width |
+| height | `number` | Panel height |
+| onDidDimensionsChange | `Event` | |
+| onDidFocusChange | `Event` | |
+| onDidVisibilityChange | `Event` | |
+| onDidActiveChange | `Event` | |
+| setActive | `(): void` | |
+| | | |
+| onDidConstraintsChange | `onDidConstraintsChange: Event` | |
+| setConstraints | `(value: PanelConstraintChangeEvent2): void;` | |
+| setSize | `(event: SizeEvent): void` | |
+| | | |
+| group | `GroupPanel | undefined` |
+| isGroupActive | `boolean` | |
+| title | `string` | |
+| suppressClosable | `boolean` | |
+| close | `(): void` | |
+| setTitle | `(title: string): void` | |
+
+## Advanced Features
+
+### Locked group
+
+Locking a group will disable all drop events for this group ensuring a user can not add additional panels to the group.
+You can still add groups to a locked panel programatically using the api.
+
+```tsx
+panel.group.locked = true;
+```
+
+### Group header
+
+You may wish to hide the header section of a group. This can achieved through setting the `hidden` variable on `panel.group.header`.
+
+```tsx
+panel.group.header.hidden = true;
+```
+
+### Context Menu
+
+import { ContextMenuDockview } from '../../src/components/dockview/contextMenu';
+
+
+
+
+
+### Rendering
+
+Although `DockviewReact` will only add those tabs that are visible to the DOM all associated React Components for each tab including those that
+are not initially visible will be created.
+This will mean that any hooks in those components will run and if you running expensive operations in the tabs you may end up doing a lot of initial
+work for what are hidden tabs.
+
+This is the default behaviour to ensure the greatest flexibility for the user but you can create a Higher-Order component wrapping your components that
+will ensure the component is only created if the tab is visible as below:
+
+```tsx
+import { PanelApi } from 'dockview';
+import * as React from 'react';
+
+function RenderWhenVisible<
+ T extends { api: Pick }
+>(component: React.FunctionComponent) {
+ const HigherOrderComponent = (props: T) => {
+ const [visible, setVisible] = React.useState(
+ props.api.isVisible
+ );
+
+ React.useEffect(() => {
+ const disposable = props.api.onDidVisibilityChange((event) =>
+ setVisible(event.isVisible)
+ );
+
+ return () => {
+ disposable.dispose();
+ };
+ }, [props.api]);
+
+ if (!visible) {
+ return null;
+ }
+
+ return React.createElement(component, props);
+ };
+ return HigherOrderComponent;
+}
+```
+
+```tsx
+const component = RenderWhenVisible(MyComponent);
+```
+
+Through toggling the checkbox you can see that when you only render those panels which are visible the underling React component is destroyed when it becomes hidden and re-created when it becomes visible.
+
+
+
+
+
+
+### Drag And Drop
+
+The component exposes some method to help determine whether external drag events should be interacted with or not.
+
+```tsx
+/**
+ * called when an ondrop event which does not originate from the dockview libray and
+ * passes the showDndOverlay condition occurs
+ **/
+const onDidDrop = (event: DockviewDropEvent) => {
+ const { group } = event;
+
+ event.api.addPanel({
+ id: 'test',
+ component: 'default',
+ position: {
+ referencePanel: group.activePanel.id,
+ direction: 'within',
+ },
+ });
+};
+
+/**
+ * called for drag over events which do not originate from the dockview library
+ * allowing the developer to decide where the overlay should be shown for a
+ * particular drag event
+ **/
+const showDndOverlay = (event: DockviewDndOverlayEvent) => {
+ return true;
+};
+
+return (
+
+);
+```
+
+
+
+### Events
+
+
diff --git a/build/docs/docs/api/gridview.mdx b/build/docs/docs/api/gridview.mdx
new file mode 100644
index 000000000..05b72565c
--- /dev/null
+++ b/build/docs/docs/api/gridview.mdx
@@ -0,0 +1,116 @@
+import { SimpleGridview } from '../../src/components/simpleGridview';
+import { EventsGridview } from '../../src/components/gridview/events';
+import Link from '@docusaurus/Link';
+
+# Gridview
+
+## Introduction
+
+
+
+
+
+## GridviewReact Component
+
+```tsx
+import { ReactGridview } from 'dockview';
+```
+
+| Property | Type | Optional | Default | Description |
+| ------------------- | ------------------------------------ | -------- | ---------------------- | --------------------------------------------------------------------------- |
+| onReady | (event: SplitviewReadyEvent) => void | No | | |
+| components | object | No | | |
+| orientation | Orientation | Yes | Orientation.HORIZONTAL | |
+| proportionalLayout | boolean | Yes | true | See Proportional layout |
+| hideBorders | boolean | Yes | false | |
+| className | string | Yes | '' | |
+| disableAutoResizing | boolean | Yes | false | See Auto Resizing |
+
+## Gridview API
+
+```tsx
+const MyComponent = (props: IGridviewPanelProps<{ title: string }>) => {
+ // props.containerApi...
+
+ return {`My first panel has the title: ${props.params.title}`}
;
+};
+```
+
+```tsx
+const onReady = (event: GridviewReadyEvent) => {
+ // event.api...
+};
+```
+
+| Property | Type | Description |
+| ---------------------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
+| height | `number` | Component pixel height |
+| width | `number` | Component pixel width |
+| minimumHeight | `number` | |
+| maximumHeight | `number` | |
+| maximumWidth | `number` | |
+| maximumWidth | `number` | |
+| length | `number` | Number of panels |
+| panels | `ISplitviewPanel[]` | all panels |
+| orientation | `Orientation` | |
+| | | |
+| onDidLayoutChange | `Event` | Fires on layout change |
+| onDidLayoutFromJSON | `Event` | Fires of layout change caused by a fromJSON deserialization call |
+| onDidAddPanel | `Event` | Fires when a view is added |
+| onDidRemovePanel | `Event` | Fires when a view is removed |
+| onDidActivePanelChange | `Event` | Fires when the active group changes |
+| | | |
+| addPanel | `addPanel(options: AddComponentOptions): IGridviewPanel` | |
+| removePanel | `(panel: IGridviewPanel, sizing?: Sizing): void` | |
+| movePanel | `(panel: IGridviewPanel, options: {direction: Direction, refernece:string, size?: number}): void` | |
+| getPanel | `(id: string) \| IGridviewPanel \| undefined` | |
+| | | |
+| updateOptions | `(options:SplitviewComponentUpdateOptions): void` | |
+| focus | `(): void` | Focus the active panel, if exists |
+| layout | `(width: number, height:number): void` | Auto Resizing |
+| fromJSON | `(data: SerializedGridview): void` | Serialization |
+| toJSON | `(): SerializedGridview` | Serialization |
+| clear | `(): void` | Clears the current layout |
+
+## Gridview Panel API
+
+```tsx
+const MyComponent = (props: IGridviewPanelProps<{ title: string }>) => {
+ // props.api...
+
+ return {`My first panel has the title: ${props.params.title}`}
;
+};
+```
+
+| Property | Type | Description |
+| ---------------------- | ----------------------------------------------------------- | ---------------- |
+| id | `string` | Panel id |
+| isFocused | `boolean` | Is panel focsed |
+| isActive | `boolean` | Is panel active |
+| isVisible | `boolean` | Is panel visible |
+| width | `number` | Panel width |
+| height | `number` | Panel height |
+| | | |
+| onDidDimensionsChange | `Event` | |
+| onDidFocusChange | `Event` | |
+| onDidVisibilityChange | `Event` | |
+| onDidActiveChange | `Event` | |
+| onDidConstraintsChange | `onDidConstraintsChange: Event` | |
+| | | |
+| setVisible | `(isVisible: boolean): void` | |
+| setActive | `(): void` | |
+| setConstraints | `(value: PanelConstraintChangeEvent2): void;` | |
+| setSize | `(event: SizeEvent): void` | |
+
+## Events
+
+`GridviewReact` exposes a number of events that the developer can listen to and below is a simple example with a log panel showing those events that occur.
+
+
diff --git a/build/docs/docs/api/paneview.mdx b/build/docs/docs/api/paneview.mdx
new file mode 100644
index 000000000..5030c11dd
--- /dev/null
+++ b/build/docs/docs/api/paneview.mdx
@@ -0,0 +1,185 @@
+import { SimplePaneview } from '../../src/components/simplePaneview';
+import Link from '@docusaurus/Link';
+
+# Paneview
+
+# Introduction
+
+
+
+
+
+## PaneviewReact Component
+
+```tsx
+import { ReactPaneview } from 'dockview';
+```
+
+| Property | Type | Optional | Default | Description |
+| ------------------- | ------------------------------------ | -------- | ------- | ----------------------------------------------------------- |
+| onReady | (event: SplitviewReadyEvent) => void | No | | |
+| components | object | No | | |
+| headerComponents | object | Yes | | |
+| className | string | Yes | '' | |
+| disableAutoResizing | boolean | Yes | false | Auto Resizing |
+| disableDnd | boolean | Yes | false | |
+| onDidDrop | Event | Yes | | |
+
+## Paneview API
+
+```tsx
+const MyComponent = (props: IGridviewPanelProps<{ title: string }>) => {
+ // props.containerApi...
+
+ return {`My first panel has the title: ${props.params.title}`}
;
+};
+```
+
+```tsx
+const onReady = (event: GridviewReadyEvent) => {
+ // event.api...
+};
+```
+
+| Property | Type | Description |
+| ------------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
+| height | `number` | Component pixel height |
+| width | `number` | Component pixel width |
+| minimumSize | `number` | The sum of the `minimumSize` property for each panel |
+| maximumSize | `number` | The sum of the `maximumSize` property for each panel |
+| length | `number` | Number of panels |
+| panels | `IPaneviewPanel[]` | All panels |
+| | | |
+| onDidLayoutChange | `Event` | Fires on layout change |
+| onDidLayoutFromJSON | `Event` | Fires of layout change caused by a fromJSON deserialization call |
+| onDidAddView | `Event` | Fires when a view is added |
+| onDidRemoveView | `Event` | Fires when a view is removed |
+| onDidDrop | `EventDrag and Drop) |
+| | | |
+| addPanel | `addPanel(options: AddPaneviewComponentOptions): IPaneviewPanel` | |
+| removePanel | `(panel: IPaneviewPanel): void` | |
+| movePanel | `(from: number, to: number): void` | |
+| getPanel | `(id:string): IPaneviewPanel \| undefined` | |
+| | | |
+| focus | `(): void` | Focus the active panel, if exists |
+| layout | `(width: number, height:number): void` | See Auto Resizing |
+| fromJSON | `(data: SerializedPaneview): void` | Serialization |
+| toJSON | `(): SerializedPaneview` | Serialization |
+| clear | `(): void` | Clears the current layout |
+
+## Gridview Panel API
+
+```tsx
+const MyComponent = (props: IGridviewPanelProps<{ title: string }>) => {
+ // props.api...
+
+ return {`My first panel has the title: ${props.params.title}`}
;
+};
+```
+
+| Property | Type | Description |
+| ---------------------- | ----------------------------------------------------------- | ---------------- |
+| id | `string` | Panel id |
+| isFocused | `boolean` | Is panel focsed |
+| isActive | `boolean` | Is panel active |
+| isVisible | `boolean` | Is panel visible |
+| width | `number` | Panel width |
+| height | `number` | Panel height |
+| | |
+| onDidDimensionsChange | `Event` | |
+| onDidFocusChange | `Event` | |
+| onDidVisibilityChange | `Event` | |
+| onDidActiveChange | `Event` | |
+| onDidConstraintsChange | `onDidConstraintsChange: Event` | |
+| | |
+| setVisible | `(isVisible: boolean): void` | |
+| setActive | `(): void` | |
+| setConstraints | `(value: PanelConstraintChangeEvent2): void;` | |
+| setSize | `(event: SizeEvent): void` | |
+
+## Advanced Features
+
+### Custom Header
+
+The above example shows the default header and will render the `title` along with a small icon to indicate a collapsed or expanded state.
+You can provide a custom header:
+
+```tsx
+const onReady = (event: PaneviewReadyEvent) => {
+ event.api.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ headerComponent: 'myHeaderComponent',
+ params: {
+ valueA: 'A',
+ },
+ title: 'Panel 1',
+ });
+};
+```
+
+The above example shows the default header and will render the `title` along with a small icon to indicate a collapsed or expanded state.
+You can provide a custom header:
+
+```tsx
+const onReady = (event: PaneviewReadyEvent) => {
+ event.api.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ headerComponent: 'myHeaderComponent',
+ params: {
+ valueA: 'A',
+ },
+ title: 'Panel 1',
+ });
+};
+```
+
+You can define a header component and listen to the expanded state to update the component accordingly.
+
+```tsx
+const CustomHeader = (props: IPaneviewPanelProps) => {
+ const [expanded, setExpanded] = React.useState(
+ props.api.isExpanded
+ );
+
+ React.useEffect(() => {
+ const disposable = props.api.onDidExpansionChange((event) => {
+ setExpanded(event.isExpanded);
+ });
+
+ return () => {
+ disposable.dispose();
+ };
+ }, []);
+
+ const onClick = () => {
+ props.api.setExpanded(!expanded);
+ };
+
+ return (
+
+
+
{props.params.title}
+
+ );
+};
+```
+
+You should provide a value for the `headerComponents` React prop.
+
+```tsx
+const headerComponents = { myHeaderComponent: CustomHeader };
+```
+
+### Drag And Drop
diff --git a/build/docs/docs/api/splitview.mdx b/build/docs/docs/api/splitview.mdx
new file mode 100644
index 000000000..b6daf2c4f
--- /dev/null
+++ b/build/docs/docs/api/splitview.mdx
@@ -0,0 +1,243 @@
+import { SimpleSplitview } from '../../src/components/simpleSplitview';
+import { SplitviewExample1 } from '../../src/components/splitview/active';
+import Link from '@docusaurus/Link';
+
+# Splitview
+
+## Introduction
+
+A Splitview is a collection resizable horizontally or vertically stacked panels.
+The Splitview exposes a component level API through the `onReady` event and through the `props.containerApi` variable on the panel props.
+A panel level API is exposed on each panel through it's props as `props.api`.
+
+
+
+
+
+```tsx title="Simple Splitview example"
+import {
+ ISplitviewPanelProps,
+ Orientation,
+ SplitviewReact,
+ SplitviewReadyEvent,
+} from 'dockview';
+
+const components = {
+ default: (props: ISplitviewPanelProps<{ title: string }>) => {
+ return {props.params.title}
;
+ },
+};
+
+export const SimpleSplitview = () => {
+ const onReady = (event: SplitviewReadyEvent) => {
+ event.api.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ title: 'Panel 1',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_2',
+ component: 'default',
+ params: {
+ title: 'Panel 2',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_3',
+ component: 'default',
+ params: {
+ title: 'Panel 3',
+ },
+ });
+ };
+
+ return (
+
+ );
+};
+```
+
+## SplitviewReact Component
+
+You can create a Splitview through the use of the `ReactSplitview` component.
+
+```tsx
+import { ReactSplitview } from 'dockview';
+```
+
+Using the `onReady` prop you can access to the component `api` and add panels either through deserialization or indivial addition of panels.
+
+| Property | Type | Optional | Default | Description |
+| ------------------- | -------------------------------------- | -------- | ------------------------ | --------------------------------------------------------------------------- |
+| onReady | `(event: SplitviewReadyEvent) => void` | No | | Function |
+| components | `Record` | No | | Panel renderers |
+| orientation | `Orientation` | Yes | `Orientation.HORIZONTAL` | Orientation of the Splitview |
+| proportionalLayout | `boolean` | Yes | `true` | See Proportional layout |
+| hideBorders | `boolean` | Yes | `false` | Hide the borders between panels |
+| className | `string` | Yes | `''` | Attaches a classname |
+| disableAutoResizing | `boolean` | Yes | `false` | See Auto Resizing |
+
+## Splitview API
+
+The Splitview API is exposed both at the `onReady` event and on each panel through `props.containerApi`.
+
+```tsx title="Splitview API via Panel component"
+const MyComponent = (props: ISplitviewPanelProps<{ title: string }>) => {
+ // props.containerApi...
+
+ return {`My first panel has the title: ${props.params.title}`}
;
+};
+```
+
+```tsx title="Splitview API via the onReady callback"
+const onReady = (event: SplitviewReadyEvent) => {
+ // event.api...
+};
+```
+
+| Property | Type | Description |
+| ------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------------- |
+| height | `number` | Component pixel height |
+| width | `number` | Component pixel width |
+| minimumSize | `number` | The sum of the `minimumSize` property for each panel |
+| maximumSize | `number` | The sum of the `maximumSize` property for each panel |
+| length | `number` | Number of panels |
+| panels | `ISplitviewPanel[]` | All panels |
+| | | |
+| onDidLayoutChange | `Event` | Fires on layout change |
+| onDidLayoutFromJSON | `Event` | Fires of layout change caused by a fromJSON deserialization call |
+| onDidAddView | `Event` | Fires when a view is added |
+| onDidRemoveView | `Event` | Fires when a view is removed |
+| | | |
+| addPanel | `addPanel(options: AddSplitviewComponentOptions): ISplitviewPanel` | |
+| removePanel | `(panel: ISplitviewPanel, sizing?: Sizing): void` | |
+| getPanel | `(id:string): ISplitviewPanel \| undefined` | |
+| movePanel | `(from: number, to: number): void` | |
+| | |
+| updateOptions | `(options: SplitviewComponentUpdateOptions): void` | |
+| focus | `(): void` | Focus the active panel, if exists |
+| layout | `(width: number, height:number): void` | See Auto Resizing |
+| fromJSON | `(data: SerializedSplitview): void` | Serialization |
+| toJSON | `(): SerializedSplitview` | Serialization |
+| clear | `(): void` | Clears the current layout |
+
+## Splitview Panel API
+
+The Splitview panel API is exposed on each panel and contains actions and variables specific to that panel.
+
+```tsx title="Splitview panel API via Panel component"
+const MyComponent = (props: ISplitviewPanelProps<{ title: string }>) => {
+ // props.api...
+
+ return {`My first panel has the title: ${props.params.title}`}
;
+};
+```
+
+| Property | Type | Description |
+| ---------------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
+| id | `string` | Panel id |
+| isFocused | `boolean` | Is panel focsed |
+| isActive | `boolean` | Is panel active |
+| isVisible | `boolean` | Is panel visible |
+| width | `number` | Panel width |
+| height | `number` | Panel height |
+| | | |
+| onDidDimensionsChange | `Event` | Fires when panel dimensions change |
+| onDidFocusChange | `Event` | Fire when panel is focused and blurred |
+| onDidVisibilityChange | `Event` | Fires when the panels visiblity property is changed (see Panel Visibility) |
+| onDidActiveChange | `Event` | Fires when the panels active property is changed (see Active Panel) |
+| onDidConstraintsChange | `onDidConstraintsChange: Event` | Fires when the panels size contrainsts change (see Panel Constraints) |
+| | | |
+| setVisible | `(isVisible: boolean): void` | |
+| setActive | `(): void` | |
+| | | |
+| setConstraints | `(value: PanelConstraintChangeEvent2): void;` | |
+| setSize | `(event: PanelSizeEvent): void` | |
+
+## Advanced Features
+
+Listed below are some functionality avalaible to you through both the panel and component APIs. The live demo shows examples of these in real-time.
+
+
+
+
+
+### Visibility
+
+A panels visibility can be controlled and monitoring through the following code.
+A panel with visibility set to `false` will remain as a part of the components list of panels but will not be rendered.
+
+```tsx
+const disposable = props.api.onDidVisibilityChange(({ isVisible }) => {
+ //
+});
+```
+
+```tsx
+api.setVisible(true);
+```
+
+### Active
+
+Only one panel in the `splitview` can be the active panel at any one time.
+Setting a panel as active will set all the others as inactive.
+A focused panel is always the active panel but an active panel is not always focused.
+
+```tsx
+const disposable = props.api.onDidActiveChange(({ isActive }) => {
+ //
+});
+```
+
+```tsx
+api.setActive();
+```
+
+### Contraints
+
+When adding a panel you can specify pixel size contraints
+
+```tsx
+event.api.addPanel({
+ id: 'panel_3',
+ component: 'default',
+ minimumSize: 100,
+ maximumSize: 1000,
+});
+```
+
+These contraints can be updated throughout the lifecycle of the `splitview` using the panel API
+
+```tsx
+props.api.onDidConstraintsChange(({ maximumSize, minimumSize }) => {
+ //
+});
+```
+
+```tsx
+api.setConstraints({
+ maximumSize: 200,
+ minimumSize: 400,
+});
+```
diff --git a/build/docs/docs/basics.mdx b/build/docs/docs/basics.mdx
new file mode 100644
index 000000000..2ad80bb6d
--- /dev/null
+++ b/build/docs/docs/basics.mdx
@@ -0,0 +1,117 @@
+---
+sidebar_position: 1
+---
+
+import { SimpleSplitview } from '../src/components/simpleSplitview';
+import { SimpleSplitview2 } from '../src/components/simpleSplitview2';
+
+# Basics
+
+This section will take you through a number of concepts that can be applied to all dockview components.
+
+## Panels
+
+The below examples use `ReactSplitview` but the logic holds for `ReactPaneview`, `ReactGridview` and `ReactDockview` using their respective implementations and interfaces.
+All components require you to provide an `onReady` prop which you can use to build and control your component.
+
+### Adding a panel with parameters
+
+You can pass parameters to a panel through the `params` object
+
+```tsx
+const onReady = (event: SplitviewReadyEvent) => {
+ event.api.addPanel({
+ id: 'panel_1',
+ component: 'myComponent',
+ params: {
+ title: 'My Title',
+ },
+ });
+};
+```
+
+and you can access those properties through the `props.params` object. The TypeScript interface accepts an optional generic type `T` that corresponds to the params objects type.
+
+```tsx
+const MyComponent = (props: ISplitviewPanelProps<{ title: string }>) => {
+ return {`My first panel has the title: ${props.params.title}`}
;
+};
+```
+
+## API
+
+There are two types of API you will interact with using `dockview`.
+
+- The `panel API` is accessible via `props.api` in user defined panels and via the `.api` variable found on panel instances. This API contains actions and variable related to the the individual panel.
+- The `container API` is accessible via `event.api` in the `onReady` events and `props.containerApi` in user defined panels. This API contains actions and variable related to the component as a whole.
+
+```tsx
+const MyComponent = (props: ISplitviewPanelProps<{ title: string }>) => {
+ React.useEffect(() => {
+ const disposable = props.api.onDidActiveChange((event) => {
+ console.log(`is panel active: ${event.isActive}`);
+ });
+
+ return () => {
+ disposable.dispose(); // remember to dispose of any subscriptions
+ };
+ }, [props.api]);
+
+ const addAnotherPanel = React.useCallback(() => {
+ props.containerApi.addPanel({
+ id: 'another_id',
+ component: 'anotherComponent',
+ });
+ }, [props.containerApi]);
+
+ return (
+
+ {`My first panel has the title: ${props.params.title}`}
+ Add Panel
+
+ );
+};
+```
+
+### Serialization
+
+All components support `toJSON(): T` which returns a Typed object representation of the components state. This same Typed object can be used to deserialize a view using `fromJSON(object: T): void`.
+
+## Auto resizing
+
+`SplitviewReact`, `GridviewReact`, `PaneviewReact` and `DockviewReact` will all automatically resize to fill the size of their parent element.
+Internally this is achieved using a [ResizeObserver](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) which some users may need to polyfill.
+You can disable this by settings the `disableAutoResizing` prop to be `true`.
+
+You can manually resize a component using the API method `layout(width: number, height: number): void`.
+An advanced case may use this in conjunction with `disableAutoResizing=true` to allow a parent component to have ultimate control over the dimensions of the component.
+
+## Events
+
+Many API properties can be listened on using the `Event` pattern. For example `api.onDidFocusChange(() => {...})`.
+You should dispose of any event listeners you create cleaning up any listeners you would have created.
+
+```tsx
+React.useEffect(() => {
+ const disposable = api.onDidFocusChange(() => {
+ // write some code
+ });
+
+ return () => {
+ disposable.dispose();
+ };
+}, []);
+```
+
+## Proportional layout
+
+The `proportionalLayout` property indicates the expected behaviour of the component as it's container resizes, should all views resize equally or should just one view expand to fill the new space. `proportionalLayout` can be set as a property on `SplitviewReact` and `GridviewReact` components.
+Although not configurable on `DockviewReact` and `PaneviewReact` these both behave as if `proportionalLayout=true` was set for them.
+
+
+
+
+
+## Browser support
+
+dockview is intended to support all major browsers. Some users may require a polyfill for [ResizeObserver](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).
diff --git a/build/docs/docs/index.mdx b/build/docs/docs/index.mdx
new file mode 100644
index 000000000..1056e63ba
--- /dev/null
+++ b/build/docs/docs/index.mdx
@@ -0,0 +1,150 @@
+---
+sidebar_position: 0
+---
+
+import { SimpleSplitview } from '../src/components/simpleSplitview';
+import { SimpleGridview } from '../src/components/simpleGridview';
+import { SimplePaneview } from '../src/components/simplePaneview';
+import { SimpleDockview } from '../src/components/simpleDockview';
+
+# Dockview
+
+## Introduction
+
+**dockview** is a zero dependency layout manager that supports tab, grids and splitviews.
+
+## Features
+
+- Themable and customizable
+- Support for the serialization and deserialization of layouts
+- Drag and drop support
+
+## Quick start
+
+`dockview` has a peer dependency on `react >= 16.8.0` and `react-dom >= 16.8.0`. To install `dockview` you can run:
+
+```shell
+npm install dockview
+```
+
+You must also import the dockview stylesheet found under [`dockview/dict/styles/dockview.css`](https://unpkg.com/browse/dockview@latest/dist/styles/dockview.css),
+depending on your solution this might be:
+
+```css
+@import './node_modules/dockview/dist/styles/dockview.css';
+```
+
+A dark and light theme are provided, one of these classes (or a custom theme) must be attached at any point above your components in the HTML tree. To cover the entire web page you might attach the class to the `body` component:
+
+```html
+
+ ...
+
+
+ ...
+
+```
+
+There are 4 components you may want to use:
+
+Splitview
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```tsx
+import {
+ DockviewReact,
+ DockviewReadyEvent,
+ PanelCollection,
+ IDockviewPanelProps,
+ IDockviewPanelHeaderProps,
+} from 'dockview';
+
+const components: PanelCollection = {
+ default: (props: IDockviewPanelProps<{ someProps: string }>) => {
+ return {props.params.someProps}
;
+ },
+};
+
+const headers: PanelCollection = {
+ customTab: (props: IDockviewPanelHeaderProps) => {
+ return (
+
+ {props.api.title}
+ props.api.close()}>{'[x]'}
+
+ );
+ },
+};
+
+const Component = () => {
+ const onReady = (event: DockviewReadyEvent) => {
+ event.api.addPanel({
+ id: 'panel1',
+ component: 'default',
+ tabComponent: 'customTab', // optional custom header
+ params: {
+ someProps: 'Hello',
+ },
+ });
+ event.api.addPanel({
+ id: 'panel2',
+ component: 'default',
+ params: {
+ someProps: 'World',
+ },
+ position: { referencePanel: 'panel1', direction: 'below' },
+ });
+ };
+
+ return (
+
+ );
+};
+```
diff --git a/build/docs/docs/theme.mdx b/build/docs/docs/theme.mdx
new file mode 100644
index 000000000..1833dbdaa
--- /dev/null
+++ b/build/docs/docs/theme.mdx
@@ -0,0 +1,80 @@
+---
+sidebar_position: 3
+---
+
+import { CustomCSSDockview } from '../src/components/dockview/customCss';
+
+# Theme
+
+## Introduction
+
+`dockview` requires some css to work correctly.
+The css is exported as one file under [`dockview/dict/styles/dockview.css`](https://unpkg.com/browse/dockview@latest/dist/styles/dockview.css)
+and depending can be imported
+
+```css
+@import './node_modules/dockview/dist/styles/dockview.css';
+```
+
+## Customizing Theme
+
+`dockview` supports theming through the use of css properties.
+You can view the built-in themes at [`dockview/src/theme.scss`](https://github.com/mathuo/dockview/blob/master/packages/dockview/src/theme.scss)
+and are free to build your own themes based on these css properties.
+
+| CSS Property | Description |
+| ---------------------------------------------------- | ----------- |
+| --dv-paneview-active-outline-color | |
+| --dv-tabs-and-actions-container-font-size | |
+| --dv-tabs-and-actions-container-height | |
+| --dv-tab-close-icon | |
+| --dv-drag-over-background-color | |
+| --dv-drag-over-border-color | |
+| --dv-tabs-container-scrollbar-color | |
+| | |
+| --dv-group-view-background-color | |
+| | |
+| --dv-tabs-and-actions-container-background-color | |
+| | |
+| --dv-activegroup-visiblepanel-tab-background-color | |
+| --dv-activegroup-hiddenpanel-tab-background-color | |
+| --dv-inactivegroup-visiblepanel-tab-background-color | |
+| --dv-inactivegroup-hiddenpanel-tab-background-color | |
+| --dv-tab-divider-color | |
+| | |
+| --dv-activegroup-visiblepanel-tab-color | |
+| --dv-activegroup-hiddenpanel-tab-color | |
+| --dv-inactivegroup-visiblepanel-tab-color | |
+| --dv-inactivegroup-hiddenpanel-tab-color | |
+| | |
+| --dv-separator-border | |
+| --dv-paneview-header-border-color | |
+
+You can further customise the theme through adjusting class properties but this is up you.
+As an example if you wanted to add a bottom border to the tab container for an active group in the `DockviewReact` component you could write:
+
+```css
+.groupview {
+ &.active-group {
+ > .tabs-and-actions-container {
+ border-bottom: 2px solid var(--dv-activegroup-visiblepanel-tab-background-color);
+ }
+ }
+ &.inactive-group {
+ > .tabs-and-actions-container {
+ border-bottom: 2px solid var(--dv-inactivegroup-visiblepanel-tab-background-color);
+ }
+ }
+}
+```
+
+
+
+
diff --git a/build/docs/docusaurus.config.js b/build/docs/docusaurus.config.js
new file mode 100644
index 000000000..bfee82b6f
--- /dev/null
+++ b/build/docs/docusaurus.config.js
@@ -0,0 +1,170 @@
+// @ts-check
+// Note: type annotations allow type checking and IDEs autocompletion
+
+const lightCodeTheme = require('prism-react-renderer/themes/github');
+const darkCodeTheme = require('prism-react-renderer/themes/dracula');
+
+const path = require('path');
+
+console.log(`isCI: ${process.env.CI}`);
+
+/** @type {import('@docusaurus/types').Config} */
+const config = {
+ title: 'Dockview',
+ tagline: 'Zero dependency layout manager for React',
+ url: 'https://your-docusaurus-test-site.com',
+ baseUrl: process.env.CI ? `/` : '/',
+ onBrokenLinks: 'throw',
+ onBrokenMarkdownLinks: 'warn',
+ favicon: 'img/favicon.ico',
+
+ // GitHub pages deployment config.
+ // If you aren't using GitHub pages, you don't need these.
+ organizationName: 'mathuo', // Usually your GitHub org/user name.
+ projectName: 'dockview', // Usually your repo name.
+
+ // Even if you don't use internalization, you can use this field to set useful
+ // metadata like html lang. For example, if your site is Chinese, you may want
+ // to replace "en" with "zh-Hans".
+ i18n: {
+ defaultLocale: 'en',
+ locales: ['en'],
+ },
+ plugins: [
+ 'docusaurus-plugin-sass',
+ (context, options) => {
+ return {
+ name: 'webpack',
+ configureWebpack: (config, isServer, utils) => {
+ return {
+ // externals: ['react', 'react-dom'],
+ devtool: 'source-map',
+ resolve: {
+ alias: {
+ react: path.join(
+ __dirname,
+ 'node_modules',
+ 'react'
+ ),
+ 'react-dom': path.join(
+ __dirname,
+ 'node_modules',
+ 'react-dom'
+ ),
+ },
+ },
+ };
+ },
+ };
+ },
+ ],
+ presets: [
+ [
+ 'classic',
+ /** @type {import('@docusaurus/preset-classic').Options} */
+ ({
+ docs: {
+ sidebarPath: require.resolve('./sidebars.js'),
+ // Please change this to your repo.
+ // Remove this to remove the "edit this page" links.
+ editUrl:
+ 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/',
+ },
+ blog: {
+ showReadingTime: true,
+ // Please change this to your repo.
+ // Remove this to remove the "edit this page" links.
+ editUrl:
+ 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/',
+ },
+ theme: {
+ customCss: require.resolve('./src/css/custom.css'),
+ },
+ }),
+ ],
+ ],
+
+ themeConfig:
+ /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
+ ({
+ navbar: {
+ title: 'Dockview',
+ logo: {
+ alt: 'My Site Logo',
+ src: 'img/logo.svg',
+ },
+ items: [
+ {
+ type: 'doc',
+ docId: 'index',
+ position: 'left',
+ label: 'Docs',
+ },
+ { to: '/blog', label: 'Blog', position: 'left' },
+ {
+ href: 'https://github.com/mathuo/dockview',
+ label: 'GitHub',
+ position: 'right',
+ },
+ ],
+ },
+ footer: {
+ style: 'dark',
+ links: [
+ {
+ title: 'Learn',
+ items: [
+ {
+ label: 'Docs',
+ to: '/docs',
+ },
+ ],
+ },
+ {
+ title: 'Community',
+ items: [
+ {
+ label: 'Stack Overflow',
+ href: 'https://stackoverflow.com/questions/tagged/dockview',
+ },
+ ],
+ },
+ {
+ title: 'More',
+ items: [
+ {
+ label: 'Blog',
+ to: '/blog',
+ },
+ {
+ label: 'GitHub',
+ href: 'https://github.com/mathuo/dockview',
+ },
+ ],
+ },
+ ],
+ copyright: `Copyright Β© ${new Date().getFullYear()} Dockview, Inc. Built with Docusaurus.`,
+ },
+ prism: {
+ theme: lightCodeTheme,
+ darkTheme: darkCodeTheme,
+ additionalLanguages: ['java', 'markdown', 'latex'],
+ magicComments: [
+ {
+ className: 'theme-code-block-highlighted-line',
+ line: 'highlight-next-line',
+ block: {
+ start: 'highlight-start',
+ end: 'highlight-end',
+ },
+ },
+ {
+ className: 'code-block-error-line',
+ line: 'This will error',
+ },
+ ],
+ },
+ }),
+};
+
+module.exports = config;
diff --git a/build/docs/jsexamples/dockview.html b/build/docs/jsexamples/dockview.html
new file mode 100644
index 000000000..84a4e165e
--- /dev/null
+++ b/build/docs/jsexamples/dockview.html
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/docs/package.json b/build/docs/package.json
new file mode 100644
index 000000000..a4ce0fce7
--- /dev/null
+++ b/build/docs/package.json
@@ -0,0 +1,54 @@
+{
+ "name": "dockview-docs",
+ "version": "1.4.2",
+ "private": true,
+ "scripts": {
+ "docusaurus": "docusaurus",
+ "start": "docusaurus start",
+ "build": "docusaurus build",
+ "swizzle": "docusaurus swizzle",
+ "deploy": "docusaurus deploy",
+ "clear": "docusaurus clear",
+ "serve": "docusaurus serve",
+ "write-translations": "docusaurus write-translations",
+ "write-heading-ids": "docusaurus write-heading-ids",
+ "typecheck": "tsc",
+ "deploy-docs": "node scripts/package-docs.js"
+ },
+ "dependencies": {
+ "@docusaurus/core": "2.0.0-beta.20",
+ "@docusaurus/preset-classic": "2.0.0-beta.20",
+ "@mdx-js/react": "^1.6.22",
+ "clsx": "^1.1.1",
+ "dockview": "^1.4.2",
+ "prism-react-renderer": "^1.3.1",
+ "react": "^17.0.2",
+ "react-dom": "^17.0.2",
+ "recoil": "^0.7.3-alpha.2"
+ },
+ "devDependencies": {
+ "@docusaurus/module-type-aliases": "2.0.0-beta.20",
+ "@tsconfig/docusaurus": "^1.0.5",
+ "docusaurus-plugin-sass": "^0.2.2",
+ "fs-extra": "^10.1.0",
+ "install": "^0.13.0",
+ "sass": "^1.52.1",
+ "typescript": "^4.6.4"
+ },
+ "resolutions": {
+ "react": "^17.0.2",
+ "react-dom": "^17.0.2"
+ },
+ "browserslist": {
+ "production": [
+ ">0.5%",
+ "not dead",
+ "not op_mini all"
+ ],
+ "development": [
+ "last 1 chrome version",
+ "last 1 firefox version",
+ "last 1 safari version"
+ ]
+ }
+}
diff --git a/build/docs/scripts/package-docs.js b/build/docs/scripts/package-docs.js
new file mode 100644
index 000000000..298cd0a9c
--- /dev/null
+++ b/build/docs/scripts/package-docs.js
@@ -0,0 +1,8 @@
+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/build/docs/sidebars.js b/build/docs/sidebars.js
new file mode 100644
index 000000000..fd342f2cd
--- /dev/null
+++ b/build/docs/sidebars.js
@@ -0,0 +1,31 @@
+/**
+ * Creating a sidebar enables you to:
+ - create an ordered group of docs
+ - render a sidebar for each doc of that group
+ - provide next/previous navigation
+
+ The sidebars can be generated from the filesystem, or explicitly defined here.
+
+ Create as many sidebars as you want.
+ */
+
+// @ts-check
+
+/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
+const sidebars = {
+ // By default, Docusaurus generates a sidebar from the docs folder structure
+ tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
+
+ // But you can create a sidebar manually
+ /*
+ tutorialSidebar: [
+ {
+ type: 'category',
+ label: 'Tutorial',
+ items: ['hello'],
+ },
+ ],
+ */
+};
+
+module.exports = sidebars;
diff --git a/build/docs/src/components/HomepageFeatures/index.tsx b/build/docs/src/components/HomepageFeatures/index.tsx
new file mode 100644
index 000000000..91ef4601d
--- /dev/null
+++ b/build/docs/src/components/HomepageFeatures/index.tsx
@@ -0,0 +1,70 @@
+import React from 'react';
+import clsx from 'clsx';
+import styles from './styles.module.css';
+
+type FeatureItem = {
+ title: string;
+ Svg: React.ComponentType>;
+ description: JSX.Element;
+};
+
+const FeatureList: FeatureItem[] = [
+ {
+ title: 'Easy to Use',
+ Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
+ description: (
+ <>
+ Docusaurus was designed from the ground up to be easily installed and
+ used to get your website up and running quickly.
+ >
+ ),
+ },
+ {
+ title: 'Focus on What Matters',
+ Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default,
+ description: (
+ <>
+ Docusaurus lets you focus on your docs, and we'll do the chores. Go
+ ahead and move your docs into the docs
directory.
+ >
+ ),
+ },
+ {
+ title: 'Powered by React',
+ Svg: require('@site/static/img/undraw_docusaurus_react.svg').default,
+ description: (
+ <>
+ Extend or customize your website layout by reusing React. Docusaurus can
+ be extended while reusing the same header and footer.
+ >
+ ),
+ },
+];
+
+function Feature({title, Svg, description}: FeatureItem) {
+ return (
+
+
+
+
+
+
{title}
+
{description}
+
+
+ );
+}
+
+export default function HomepageFeatures(): JSX.Element {
+ return (
+
+
+
+ {FeatureList.map((props, idx) => (
+
+ ))}
+
+
+
+ );
+}
diff --git a/build/docs/src/components/HomepageFeatures/styles.module.css b/build/docs/src/components/HomepageFeatures/styles.module.css
new file mode 100644
index 000000000..b248eb2e5
--- /dev/null
+++ b/build/docs/src/components/HomepageFeatures/styles.module.css
@@ -0,0 +1,11 @@
+.features {
+ display: flex;
+ align-items: center;
+ padding: 2rem 0;
+ width: 100%;
+}
+
+.featureSvg {
+ height: 200px;
+ width: 200px;
+}
diff --git a/build/docs/src/components/console/console.scss b/build/docs/src/components/console/console.scss
new file mode 100644
index 000000000..f2896c044
--- /dev/null
+++ b/build/docs/src/components/console/console.scss
@@ -0,0 +1,27 @@
+.console-container {
+ background-color: black;
+ color: white;
+ padding-left: 8px;
+ max-height: 200px;
+ overflow-y: scroll;
+ overflow-x: auto;
+
+ .console-line {
+ height: 20px;
+ line-height: 20px;
+ font-size: 13px;
+ border-bottom: 1px solid rgb(30, 30, 30);
+ display: flex;
+ padding-left: 4px;
+
+ .console-line-timestamp {
+ color: lightgray;
+ padding-right: 4px;
+ }
+
+ .console-line-text {
+ padding: 0px 4px;
+ flex-grow: 1;
+ }
+ }
+}
diff --git a/build/docs/src/components/console/console.tsx b/build/docs/src/components/console/console.tsx
new file mode 100644
index 000000000..c936a1476
--- /dev/null
+++ b/build/docs/src/components/console/console.tsx
@@ -0,0 +1,52 @@
+import * as React from 'react';
+import './console.scss';
+
+const formatTime = (now: Date) => {
+ const pad = (x: number) => (x < 10 ? `0${x}` : `${x}`);
+
+ return `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(
+ now.getSeconds()
+ )}.${now.getMilliseconds()}`;
+};
+
+export interface Line {
+ timestamp: Date;
+ text: string;
+ css?: React.CSSProperties;
+}
+
+export interface IConsoleProps {
+ lines: Line[];
+}
+
+export const Console = (props: IConsoleProps) => {
+ const ref = React.useRef();
+
+ React.useLayoutEffect(() => {
+ if (!ref.current) {
+ return;
+ }
+
+ ref.current.scrollTop = Math.max(
+ 0,
+ ref.current.scrollHeight - ref.current.clientHeight
+ );
+ }, [props.lines]);
+
+ return (
+
+ {props.lines.map((line, i) => {
+ return (
+
+
+ {formatTime(line.timestamp)}
+
+
+ {line.text}
+
+
+ );
+ })}
+
+ );
+};
diff --git a/build/docs/src/components/dockview/contextMenu.tsx b/build/docs/src/components/dockview/contextMenu.tsx
new file mode 100644
index 000000000..cac359aa3
--- /dev/null
+++ b/build/docs/src/components/dockview/contextMenu.tsx
@@ -0,0 +1,115 @@
+import {
+ DockviewReact,
+ DockviewReadyEvent,
+ IDockviewPanelHeaderProps,
+ IDockviewPanelProps,
+} from 'dockview';
+import * as React from 'react';
+
+//
+const components = {
+ default: (props: IDockviewPanelProps<{ title: string }>) => {
+ return {props.params.title}
;
+ },
+};
+
+const DefaultTab = (props: IDockviewPanelHeaderProps) => {
+ const [active, setActive] = React.useState(props.api.isActive);
+ const [groupActive, setGroupActive] = React.useState(
+ props.api.isGroupActive
+ );
+
+ React.useEffect(() => {
+ const disposable1 = props.api.onDidActiveChange((e) => {
+ setActive(e.isActive);
+ });
+ const disposable2 = props.containerApi.onDidActiveGroupChange((e) => {
+ setGroupActive(props.api.isGroupActive);
+ });
+
+ return () => {
+ disposable1.dispose();
+ disposable2.dispose();
+ };
+ }, [props.api]);
+
+ return (
+
+
+ {props.api.title}
+
+ props.api.setActive()}
+ style={{
+ display: 'flex',
+ alignItems: 'center',
+ paddingRight: '8px',
+ }}
+ >
+ {'β'}
+
+
+ );
+};
+
+const tabComponents = {
+ default: DefaultTab,
+};
+
+export const ContextMenuDockview = () => {
+ const onReady = (event: DockviewReadyEvent) => {
+ event.api.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ tabComponent: 'default',
+ params: {
+ title: 'Panel 1',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_2',
+ component: 'default',
+ tabComponent: 'default',
+ params: {
+ title: 'Panel 2',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_3',
+ component: 'default',
+ tabComponent: 'default',
+ params: {
+ title: 'Panel 3',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_4',
+ component: 'default',
+ tabComponent: 'default',
+ params: {
+ title: 'Panel 4',
+ },
+ position: { referencePanel: 'panel_1', direction: 'right' },
+ });
+ };
+
+ return (
+
+ );
+};
diff --git a/build/docs/src/components/dockview/customCss.tsx b/build/docs/src/components/dockview/customCss.tsx
new file mode 100644
index 000000000..868bd176e
--- /dev/null
+++ b/build/docs/src/components/dockview/customCss.tsx
@@ -0,0 +1,58 @@
+import {
+ DockviewReact,
+ DockviewReadyEvent,
+ IDockviewPanelProps,
+} from 'dockview';
+import * as React from 'react';
+
+//
+const components = {
+ default: (props: IDockviewPanelProps<{ title: string }>) => {
+ return {props.params.title}
;
+ },
+};
+
+export const CustomCSSDockview = () => {
+ const onReady = (event: DockviewReadyEvent) => {
+ event.api.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ title: 'Panel 1',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_2',
+ component: 'default',
+ params: {
+ title: 'Panel 2',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_3',
+ component: 'default',
+ params: {
+ title: 'Panel 3',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_4',
+ component: 'default',
+ params: {
+ title: 'Panel 4',
+ },
+ position: { referencePanel: 'panel_1', direction: 'right' },
+ });
+ };
+
+ return (
+
+ );
+};
diff --git a/build/docs/src/components/dockview/dnd.tsx b/build/docs/src/components/dockview/dnd.tsx
new file mode 100644
index 000000000..344f30d07
--- /dev/null
+++ b/build/docs/src/components/dockview/dnd.tsx
@@ -0,0 +1,105 @@
+import {
+ DockviewDndOverlayEvent,
+ DockviewDropEvent,
+ DockviewReact,
+ DockviewReadyEvent,
+ IDockviewPanelProps,
+} from 'dockview';
+import * as React from 'react';
+
+const components = {
+ default: (props: IDockviewPanelProps<{ title: string }>) => {
+ return (
+
+ );
+ },
+};
+
+export const DndDockview = (props: { renderVisibleOnly: boolean }) => {
+ const onReady = (event: DockviewReadyEvent) => {
+ event.api.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ title: 'Panel 1',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_2',
+ component: 'default',
+ params: {
+ title: 'Panel 2',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_3',
+ component: 'default',
+ params: {
+ title: 'Panel 3',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_4',
+ component: 'default',
+ params: {
+ title: 'Panel 4',
+ },
+ position: { referencePanel: 'panel_1', direction: 'right' },
+ });
+ };
+
+ const onDidDrop = (event: DockviewDropEvent) => {
+ const { group } = event;
+
+ event.api.addPanel({
+ id: 'test',
+ component: 'default',
+ position: {
+ referencePanel: group.activePanel.id,
+ direction: 'within',
+ },
+ });
+ };
+
+ const showDndOverlay = (event: DockviewDndOverlayEvent) => {
+ return true;
+ };
+
+ return (
+ <>
+
+ Drag me
+
+
+
+
+ >
+ );
+};
diff --git a/build/docs/src/components/dockview/events.tsx b/build/docs/src/components/dockview/events.tsx
new file mode 100644
index 000000000..0ee2b3e43
--- /dev/null
+++ b/build/docs/src/components/dockview/events.tsx
@@ -0,0 +1,342 @@
+import {
+ Orientation,
+ DockviewReact,
+ DockviewReadyEvent,
+ DockviewApi,
+ IDockviewPanelProps,
+} from 'dockview';
+import * as React from 'react';
+import { Console, Line } from '../console/console';
+
+const components = {
+ default: (props: IDockviewPanelProps<{ title: string }>) => {
+ return {props.params.title}
;
+ },
+};
+
+export const EventsDockview = () => {
+ const [lines, setLines] = React.useState([]);
+ const [checked, setChecked] = React.useState(false);
+
+ const [api, setApi] = React.useState();
+
+ React.useEffect(() => {
+ if (!api) {
+ return () => {
+ //noop
+ };
+ }
+
+ const disposables = [
+ api.onDidAddPanel((panel) => {
+ setLines((lines) => [
+ ...lines,
+ {
+ timestamp: new Date(),
+ text: `onDidAddPanel: ${panel.id}`,
+ },
+ ]);
+ }),
+ api.onDidRemovePanel((panel) => {
+ setLines((lines) => [
+ ...lines,
+ {
+ timestamp: new Date(),
+ text: `onDidRemovePanel: ${panel.id}`,
+ },
+ ]);
+ }),
+ api.onDidActivePanelChange((panel) => {
+ setLines((lines) => [
+ ...lines,
+ {
+ timestamp: new Date(),
+ text: `onDidActivePanelChange: ${panel?.id}`,
+ },
+ ]);
+ }),
+ api.onDidAddGroup((panel) => {
+ setLines((lines) => [
+ ...lines,
+ {
+ timestamp: new Date(),
+ text: `onDidAddGroup: ${panel.id}`,
+ },
+ ]);
+ }),
+ api.onDidRemoveGroup((panel) => {
+ setLines((lines) => [
+ ...lines,
+ {
+ timestamp: new Date(),
+ text: `onDidRemoveGroup: ${panel.id}`,
+ },
+ ]);
+ }),
+ api.onDidActiveGroupChange((panel) => {
+ setLines((lines) => [
+ ...lines,
+ {
+ timestamp: new Date(),
+ text: `onDidActiveGroupChange: ${panel?.id}`,
+ },
+ ]);
+ }),
+ api.onDidLayoutChange((panel) => {
+ setLines((lines) => [
+ ...lines,
+ { timestamp: new Date(), text: `onDidLayoutChange` },
+ ]);
+ }),
+ api.onDidLayoutFromJSON((panel) => {
+ setLines((lines) => [
+ ...lines,
+ { timestamp: new Date(), text: `onDidLayoutFromJSON` },
+ ]);
+ }),
+ ];
+
+ return () => {
+ disposables.forEach((disposable) => disposable.dispose());
+ };
+ }, [api]);
+
+ React.useEffect(() => {
+ if (!api) {
+ return;
+ }
+
+ setLines((lines) => [
+ ...lines,
+ {
+ timestamp: new Date(),
+ text: `Rebuilding view fromJSON:${checked}`,
+ css: { color: 'yellow', backgroundColor: 'grey' },
+ },
+ ]);
+
+ if (checked) {
+ api.fromJSON({
+ grid: {
+ root: {
+ type: 'branch',
+ data: [
+ {
+ type: 'leaf',
+ data: {
+ views: ['panel_1', 'panel_2', 'panel_3'],
+ activeView: 'panel_3',
+ id: '77',
+ },
+ size: 262,
+ },
+ {
+ type: 'branch',
+ data: [
+ {
+ type: 'leaf',
+ data: {
+ views: ['panel_5'],
+ activeView: 'panel_5',
+ id: '79',
+ },
+ size: 100,
+ },
+ {
+ type: 'leaf',
+ data: {
+ views: ['panel_6', 'panel_8'],
+ activeView: 'panel_8',
+ id: '80',
+ },
+ size: 100,
+ },
+ {
+ type: 'leaf',
+ data: {
+ views: ['panel_7'],
+ activeView: 'panel_7',
+ id: '81',
+ },
+ size: 100,
+ },
+ ],
+ size: 262,
+ },
+ {
+ type: 'leaf',
+ data: {
+ views: ['panel_4'],
+ activeView: 'panel_4',
+ id: '78',
+ },
+ size: 263.75,
+ },
+ ],
+ size: 300,
+ },
+ width: 787.75,
+ height: 300,
+ orientation: Orientation.HORIZONTAL,
+ },
+ panels: {
+ panel_1: {
+ id: 'panel_1',
+ view: { content: { id: 'default' } },
+ params: { title: 'Panel 1' },
+ title: 'panel_1',
+ },
+ panel_2: {
+ id: 'panel_2',
+ view: { content: { id: 'default' } },
+ params: { title: 'Panel 2' },
+ title: 'panel_2',
+ },
+ panel_3: {
+ id: 'panel_3',
+ view: { content: { id: 'default' } },
+ params: { title: 'Panel 3' },
+ title: 'panel_3',
+ },
+ panel_4: {
+ id: 'panel_4',
+ view: { content: { id: 'default' } },
+ params: { title: 'Panel 4' },
+ title: 'panel_4',
+ },
+ panel_5: {
+ id: 'panel_5',
+ view: { content: { id: 'default' } },
+ params: { title: 'Panel 5' },
+ title: 'panel_5',
+ },
+ panel_6: {
+ id: 'panel_6',
+ view: { content: { id: 'default' } },
+ params: { title: 'Panel 6' },
+ title: 'panel_6',
+ },
+ panel_8: {
+ id: 'panel_8',
+ view: { content: { id: 'default' } },
+ params: { title: 'Panel 8' },
+ title: 'panel_8',
+ },
+ panel_7: {
+ id: 'panel_7',
+ view: { content: { id: 'default' } },
+ params: { title: 'Panel 7' },
+ title: 'panel_7',
+ },
+ },
+ activeGroup: '80',
+ options: {},
+ });
+ return;
+ }
+
+ api.clear();
+
+ api.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ title: 'Panel 1',
+ },
+ });
+
+ api.addPanel({
+ id: 'panel_2',
+ component: 'default',
+ params: {
+ title: 'Panel 2',
+ },
+ });
+
+ api.addPanel({
+ id: 'panel_3',
+ component: 'default',
+ params: {
+ title: 'Panel 3',
+ },
+ });
+
+ api.addPanel({
+ id: 'panel_4',
+ component: 'default',
+ params: {
+ title: 'Panel 4',
+ },
+ position: { referencePanel: 'panel_1', direction: 'right' },
+ });
+
+ api.addPanel({
+ id: 'panel_5',
+ component: 'default',
+ params: {
+ title: 'Panel 5',
+ },
+ position: { referencePanel: 'panel_3', direction: 'right' },
+ });
+
+ api.addPanel({
+ id: 'panel_6',
+ component: 'default',
+ params: {
+ title: 'Panel 6',
+ },
+ position: { referencePanel: 'panel_5', direction: 'below' },
+ });
+
+ api.addPanel({
+ id: 'panel_7',
+ component: 'default',
+ params: {
+ title: 'Panel 7',
+ },
+ position: { referencePanel: 'panel_6', direction: 'below' },
+ });
+
+ api.addPanel({
+ id: 'panel_8',
+ component: 'default',
+ params: {
+ title: 'Panel 8',
+ },
+ position: { referencePanel: 'panel_6', direction: 'within' },
+ });
+ }, [api, checked]);
+
+ const onReady = (event: DockviewReadyEvent) => {
+ setApi(event.api);
+ };
+
+ return (
+ <>
+
+ setChecked(e.target.checked)}
+ />
+ {'fromJSON'}
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/build/docs/src/components/dockview/rendering.tsx b/build/docs/src/components/dockview/rendering.tsx
new file mode 100644
index 000000000..9dcf9d152
--- /dev/null
+++ b/build/docs/src/components/dockview/rendering.tsx
@@ -0,0 +1,158 @@
+import {
+ DockviewReact,
+ DockviewReadyEvent,
+ IDockviewPanelProps,
+ PanelApi,
+} from 'dockview';
+import * as React from 'react';
+
+import { atom, useRecoilState, useRecoilValue } from 'recoil';
+
+const renderVisibleComponentsOnlyAtom = atom({
+ key: 'renderVisibleComponentsOnlyAtom',
+ default: false,
+});
+
+function RenderWhenVisible<
+ T extends { api: Pick }
+>(component: React.FunctionComponent) {
+ const HigherOrderComponent = (props: T) => {
+ const [visible, setVisible] = React.useState(
+ props.api.isVisible
+ );
+
+ const render = useRecoilValue(renderVisibleComponentsOnlyAtom);
+
+ React.useEffect(() => {
+ const disposable = props.api.onDidVisibilityChange((event) =>
+ setVisible(event.isVisible)
+ );
+
+ return () => {
+ disposable.dispose();
+ };
+ }, [props.api]);
+
+ if (!visible && render) {
+ return null;
+ }
+
+ return React.createElement(component, props);
+ };
+ return HigherOrderComponent;
+}
+
+const formatLine = (line: string) => {
+ const now = new Date();
+
+ const pad = (x: number) => (x < 10 ? `0${x}` : `${x}`);
+
+ const time = `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(
+ now.getSeconds()
+ )}`;
+
+ return `[${time}] ${line}`;
+};
+
+const components = {
+ default: RenderWhenVisible(
+ (props: IDockviewPanelProps<{ title: string }>) => {
+ const [lines, setLines] = React.useState([
+ formatLine('Component created'),
+ ]);
+
+ React.useEffect(() => {
+ setLines((lines) => [
+ ...lines,
+ formatLine('Running task for 5 seconds'),
+ ]);
+ const timeout = setTimeout(() => {
+ setLines((lines) => [
+ ...lines,
+ formatLine('Task completed'),
+ ]);
+ }, 5000);
+
+ return () => {
+ clearTimeout(timeout);
+ };
+ }, []);
+
+ return (
+
+
{props.params.title}
+ {lines.map((line, i) => (
+
{line}
+ ))}
+
+ );
+ }
+ ),
+};
+
+export const RenderingDockview = (props: { renderVisibleOnly: boolean }) => {
+ const [render, setRender] = useRecoilState(renderVisibleComponentsOnlyAtom);
+
+ React.useEffect(
+ () => setRender(props.renderVisibleOnly),
+ [props.renderVisibleOnly]
+ );
+
+ const onReady = (event: DockviewReadyEvent) => {
+ event.api.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ title: 'Panel 1',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_2',
+ component: 'default',
+ params: {
+ title: 'Panel 2',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_3',
+ component: 'default',
+ params: {
+ title: 'Panel 3',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_4',
+ component: 'default',
+ params: {
+ title: 'Panel 4',
+ },
+ position: { referencePanel: 'panel_1', direction: 'right' },
+ });
+ };
+
+ return (
+
+ );
+};
+
+export const Checkbox = () => {
+ const [render, setRender] = useRecoilState(renderVisibleComponentsOnlyAtom);
+
+ return (
+
+ Render only when visible
+ setRender(e.target.checked)}
+ />
+
+ );
+};
diff --git a/build/docs/src/components/gridview/events.tsx b/build/docs/src/components/gridview/events.tsx
new file mode 100644
index 000000000..ee26959f9
--- /dev/null
+++ b/build/docs/src/components/gridview/events.tsx
@@ -0,0 +1,339 @@
+import {
+ IGridviewPanelProps,
+ Orientation,
+ GridviewReact,
+ GridviewReadyEvent,
+ GridviewApi,
+} from 'dockview';
+import * as React from 'react';
+import { Console, Line } from '../console/console';
+
+const components = {
+ default: (props: IGridviewPanelProps<{ title: string }>) => {
+ return {props.params.title}
;
+ },
+};
+
+export const EventsGridview = () => {
+ const [lines, setLines] = React.useState([]);
+ const [checked, setChecked] = React.useState(false);
+
+ const [api, setApi] = React.useState();
+
+ React.useEffect(() => {
+ if (!api) {
+ return () => {
+ //noop
+ };
+ }
+
+ const disposables = [
+ api.onDidAddPanel((panel) => {
+ setLines((lines) => [
+ ...lines,
+ {
+ timestamp: new Date(),
+ text: `onDidAddPanel: ${panel.id}`,
+ },
+ ]);
+ }),
+ api.onDidRemovePanel((panel) => {
+ setLines((lines) => [
+ ...lines,
+ {
+ timestamp: new Date(),
+ text: `onDidRemovePanel: ${panel.id}`,
+ },
+ ]);
+ }),
+ api.onDidActivePanelChange((panel) => {
+ setLines((lines) => [
+ ...lines,
+ {
+ timestamp: new Date(),
+ text: `onDidActivePanelChange: ${panel?.id}`,
+ },
+ ]);
+ }),
+ api.onDidLayoutChange((panel) => {
+ setLines((lines) => [
+ ...lines,
+ { timestamp: new Date(), text: `onDidLayoutChange` },
+ ]);
+ }),
+ api.onDidLayoutFromJSON((panel) => {
+ setLines((lines) => [
+ ...lines,
+ { timestamp: new Date(), text: `onDidLayoutFromJSON` },
+ ]);
+ }),
+ ];
+
+ return () => {
+ disposables.forEach((disposable) => disposable.dispose());
+ };
+ }, [api]);
+
+ React.useEffect(() => {
+ if (!api) {
+ return;
+ }
+
+ setLines((lines) => [
+ ...lines,
+ {
+ timestamp: new Date(),
+ text: `Rebuilding view fromJSON:${checked}`,
+ css: { color: 'yellow', backgroundColor: 'grey' },
+ },
+ ]);
+
+ if (checked) {
+ api.fromJSON({
+ grid: {
+ root: {
+ type: 'branch',
+ data: [
+ {
+ type: 'branch',
+ data: [
+ {
+ type: 'leaf',
+ data: {
+ id: 'panel_3',
+ component: 'default',
+ params: { title: 'Panel 3' },
+ snap: false,
+ },
+ size: 394,
+ },
+ {
+ type: 'branch',
+ data: [
+ {
+ type: 'leaf',
+ data: {
+ id: 'panel_5',
+ component: 'default',
+ params: {
+ title: 'Panel 5',
+ },
+ snap: false,
+ },
+ size: 50,
+ },
+ {
+ type: 'branch',
+ data: [
+ {
+ type: 'leaf',
+ data: {
+ id: 'panel_6',
+ component:
+ 'default',
+ params: {
+ title: 'Panel 6',
+ },
+ minimumWidth: 10,
+ snap: false,
+ },
+ size: 131,
+ },
+ {
+ type: 'leaf',
+ data: {
+ id: 'panel_8',
+ component:
+ 'default',
+ params: {
+ title: 'Panel 8',
+ },
+ minimumWidth: 10,
+ snap: false,
+ },
+ size: 131,
+ },
+ {
+ type: 'leaf',
+ data: {
+ id: 'panel_7',
+ component:
+ 'default',
+ params: {
+ title: 'Panel 7',
+ },
+ minimumWidth: 10,
+ snap: false,
+ },
+ size: 132,
+ },
+ ],
+ size: 50,
+ },
+ ],
+ size: 394,
+ },
+ ],
+ size: 100,
+ },
+ {
+ type: 'leaf',
+ data: {
+ id: 'panel_2',
+ component: 'default',
+ params: { title: 'Panel 2' },
+ snap: false,
+ },
+ size: 100,
+ },
+ {
+ type: 'branch',
+ data: [
+ {
+ type: 'leaf',
+ data: {
+ id: 'panel_1',
+ component: 'default',
+ params: { title: 'Panel 1' },
+ snap: false,
+ },
+ size: 394,
+ },
+ {
+ type: 'leaf',
+ data: {
+ id: 'panel_4',
+ component: 'default',
+ params: { title: 'Panel 4' },
+ snap: false,
+ },
+ size: 394,
+ },
+ ],
+ size: 100,
+ },
+ ],
+ size: 788,
+ },
+ width: 788,
+ height: 300,
+ orientation: Orientation.VERTICAL,
+ },
+ activePanel: 'panel_8',
+ });
+ return;
+ }
+
+ api.clear();
+ api.orientation = Orientation.VERTICAL;
+
+ api.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ title: 'Panel 1',
+ },
+ });
+
+ api.addPanel({
+ id: 'panel_2',
+ component: 'default',
+ params: {
+ title: 'Panel 2',
+ },
+ });
+
+ api.addPanel({
+ id: 'panel_3',
+ component: 'default',
+ params: {
+ title: 'Panel 3',
+ },
+ });
+
+ console.log('sdf');
+
+ api.addPanel({
+ id: 'panel_4',
+ component: 'default',
+ params: {
+ title: 'Panel 4',
+ },
+ position: { referencePanel: 'panel_1', direction: 'right' },
+ });
+
+ api.addPanel({
+ id: 'panel_5',
+ component: 'default',
+ params: {
+ title: 'Panel 5',
+ },
+ position: { referencePanel: 'panel_3', direction: 'right' },
+ });
+
+ api.addPanel({
+ id: 'panel_6',
+ component: 'default',
+ params: {
+ title: 'Panel 6',
+ },
+ position: { referencePanel: 'panel_5', direction: 'below' },
+ minimumWidth: 10,
+ });
+
+ api.addPanel({
+ id: 'panel_7',
+ component: 'default',
+ params: {
+ title: 'Panel 7',
+ },
+ position: { referencePanel: 'panel_6', direction: 'right' },
+ minimumWidth: 10,
+ });
+
+ api.addPanel({
+ id: 'panel_8',
+ component: 'default',
+ params: {
+ title: 'Panel 8',
+ },
+ position: { referencePanel: 'panel_6', direction: 'right' },
+ minimumWidth: 10,
+ });
+ }, [api, checked]);
+
+ const onReady = (event: GridviewReadyEvent) => {
+ setApi(event.api);
+ };
+
+ return (
+ <>
+
+ setChecked(e.target.checked)}
+ />
+ {'fromJSON'}
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/build/docs/src/components/release.tsx b/build/docs/src/components/release.tsx
new file mode 100644
index 000000000..9f60e71f2
--- /dev/null
+++ b/build/docs/src/components/release.tsx
@@ -0,0 +1,2 @@
+import * as React from 'react';
+const URL = 'https://api.github.com/repos/mathuo/dockview/releases';
diff --git a/build/docs/src/components/simpleDockview.tsx b/build/docs/src/components/simpleDockview.tsx
new file mode 100644
index 000000000..64a704d93
--- /dev/null
+++ b/build/docs/src/components/simpleDockview.tsx
@@ -0,0 +1,116 @@
+import {
+ DockviewReact,
+ DockviewReadyEvent,
+ IDockviewPanelProps,
+ PanelApi,
+} from 'dockview';
+import * as React from 'react';
+
+const components = {
+ default: (props: IDockviewPanelProps<{ title: string }>) => {
+ return {props.params.title}
;
+ },
+};
+
+const RenderWhenVisible = (
+ props: T & {
+ children: React.FunctionComponent;
+ api: Pick;
+ }
+) => {
+ const [visible, setVisible] = React.useState(props.api.isVisible);
+
+ React.useEffect(() => {
+ const disposable = props.api.onDidVisibilityChange((event) =>
+ setVisible(event.isVisible)
+ );
+
+ return () => {
+ disposable.dispose();
+ };
+ }, [props.api]);
+
+ if (!visible) {
+ return null;
+ }
+
+ return React.createElement(props.children, props);
+};
+
+export const SimpleDockview = () => {
+ const onReady = (event: DockviewReadyEvent) => {
+ const panel = event.api.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ title: 'Panel 1',
+ },
+ });
+
+ panel.group.locked = true;
+ panel.group.header.hidden = true;
+
+ event.api.addPanel({
+ id: 'panel_2',
+ component: 'default',
+ params: {
+ title: 'Panel 2',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_3',
+ component: 'default',
+ params: {
+ title: 'Panel 3',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_4',
+ component: 'default',
+ params: {
+ title: 'Panel 4',
+ },
+ position: { referencePanel: 'panel_1', direction: 'right' },
+ });
+
+ const panel5 = event.api.addPanel({
+ id: 'panel_5',
+ component: 'default',
+ params: {
+ title: 'Panel 5',
+ },
+ position: { referencePanel: 'panel_3', direction: 'right' },
+ });
+
+ // panel5.group!.model.header.hidden = true;
+ // panel5.group!.model.locked = true;
+
+ event.api.addPanel({
+ id: 'panel_6',
+ component: 'default',
+ params: {
+ title: 'Panel 6',
+ },
+ position: { referencePanel: 'panel_5', direction: 'below' },
+ });
+
+ event.api.addPanel({
+ id: 'panel_7',
+ component: 'default',
+ params: {
+ title: 'Panel 7',
+ },
+ position: { referencePanel: 'panel_6', direction: 'right' },
+ });
+ };
+
+ return (
+
+ );
+};
diff --git a/build/docs/src/components/simpleGridview.tsx b/build/docs/src/components/simpleGridview.tsx
new file mode 100644
index 000000000..1d468e339
--- /dev/null
+++ b/build/docs/src/components/simpleGridview.tsx
@@ -0,0 +1,99 @@
+import {
+ IGridviewPanelProps,
+ Orientation,
+ GridviewReact,
+ GridviewReadyEvent,
+} from 'dockview';
+import * as React from 'react';
+
+const components = {
+ default: (props: IGridviewPanelProps<{ title: string }>) => {
+ return {props.params.title}
;
+ },
+};
+
+export const SimpleGridview = () => {
+ const onReady = (event: GridviewReadyEvent) => {
+ event.api.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ title: 'Panel 1',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_2',
+ component: 'default',
+ params: {
+ title: 'Panel 2',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_3',
+ component: 'default',
+ params: {
+ title: 'Panel 3',
+ },
+ });
+
+ event.api.addPanel({
+ id: 'panel_4',
+ component: 'default',
+ params: {
+ title: 'Panel 4',
+ },
+ position: { referencePanel: 'panel_1', direction: 'right' },
+ });
+
+ event.api.addPanel({
+ id: 'panel_5',
+ component: 'default',
+ params: {
+ title: 'Panel 5',
+ },
+ position: { referencePanel: 'panel_3', direction: 'right' },
+ });
+
+ event.api.addPanel({
+ id: 'panel_6',
+ component: 'default',
+ params: {
+ title: 'Panel 6',
+ },
+ position: { referencePanel: 'panel_5', direction: 'below' },
+ minimumWidth: 10,
+ });
+
+ event.api.addPanel({
+ id: 'panel_7',
+ component: 'default',
+ params: {
+ title: 'Panel 7',
+ },
+ position: { referencePanel: 'panel_6', direction: 'right' },
+ minimumWidth: 10,
+ });
+
+ event.api.addPanel({
+ id: 'panel_8',
+ component: 'default',
+ params: {
+ title: 'Panel 8',
+ },
+ position: { referencePanel: 'panel_6', direction: 'right' },
+ minimumWidth: 10,
+ });
+ };
+
+ return (
+
+ );
+};
diff --git a/build/docs/src/components/simplePaneview.tsx b/build/docs/src/components/simplePaneview.tsx
new file mode 100644
index 000000000..d906406e5
--- /dev/null
+++ b/build/docs/src/components/simplePaneview.tsx
@@ -0,0 +1,102 @@
+import {
+ IPaneviewPanelProps,
+ PaneviewReact,
+ PaneviewReadyEvent,
+} from 'dockview';
+import * as React from 'react';
+
+const components = {
+ default: (props: IPaneviewPanelProps<{ title: string }>) => {
+ return (
+
+ {props.params.title}
+
+ );
+ },
+};
+
+const MyHeaderComponent = (props: IPaneviewPanelProps<{ title: string }>) => {
+ const [expanded, setExpanded] = React.useState(
+ props.api.isExpanded
+ );
+
+ React.useEffect(() => {
+ const disposable = props.api.onDidExpansionChange((event) => {
+ setExpanded(event.isExpanded);
+ });
+
+ return () => {
+ disposable.dispose();
+ };
+ }, []);
+
+ const onClick = () => {
+ props.api.setExpanded(!expanded);
+ };
+
+ return (
+
+
+
{props.params.title}
+
+ );
+};
+
+const headerComponents = {
+ myHeaderComponent: MyHeaderComponent,
+};
+
+export const SimplePaneview = () => {
+ const onReady = (event: PaneviewReadyEvent) => {
+ event.api.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ title: 'Panel 1',
+ },
+ title: 'Panel 1',
+ });
+
+ event.api.addPanel({
+ id: 'panel_2',
+ component: 'default',
+ params: {
+ title: 'Panel 2',
+ },
+ title: 'Panel 2',
+ });
+
+ event.api.addPanel({
+ id: 'panel_3',
+ component: 'default',
+ params: {
+ title: 'Panel 3',
+ },
+ title: 'Panel 3',
+ });
+ };
+
+ return (
+
+ );
+};
diff --git a/build/docs/src/components/simpleSplitview.tsx b/build/docs/src/components/simpleSplitview.tsx
new file mode 100644
index 000000000..219bf6088
--- /dev/null
+++ b/build/docs/src/components/simpleSplitview.tsx
@@ -0,0 +1,54 @@
+import {
+ ISplitviewPanelProps,
+ Orientation,
+ SplitviewReact,
+ SplitviewReadyEvent,
+} from 'dockview';
+import * as React from 'react';
+
+const components = {
+ default: (props: ISplitviewPanelProps<{ title: string }>) => {
+ return {props.params.title}
;
+ },
+};
+
+export const SimpleSplitview = (props: { proportional?: boolean }) => {
+ const onReady = (event: SplitviewReadyEvent) => {
+ event.api.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ title: 'Panel 1',
+ },
+ minimumSize: 100,
+ });
+
+ event.api.addPanel({
+ id: 'panel_2',
+ component: 'default',
+ params: {
+ title: 'Panel 2',
+ },
+ minimumSize: 100,
+ });
+
+ event.api.addPanel({
+ id: 'panel_3',
+ component: 'default',
+ params: {
+ title: 'Panel 3',
+ },
+ minimumSize: 100,
+ });
+ };
+
+ return (
+
+ );
+};
diff --git a/build/docs/src/components/simpleSplitview2.tsx b/build/docs/src/components/simpleSplitview2.tsx
new file mode 100644
index 000000000..1ffd12356
--- /dev/null
+++ b/build/docs/src/components/simpleSplitview2.tsx
@@ -0,0 +1,60 @@
+import { SimpleSplitview } from './simpleSplitview';
+import * as React from 'react';
+
+export const SimpleSplitview2 = (props: { proportional?: boolean }) => {
+ const [value, setValue] = React.useState(50);
+
+ const onChange = (event: React.ChangeEvent) => {
+ setValue(Number(event.target.value));
+ };
+
+ return (
+
+
+
+
+ Slide to resize the splitview container
+
+
+
+
+ );
+};
diff --git a/build/docs/src/components/splitview/active.tsx b/build/docs/src/components/splitview/active.tsx
new file mode 100644
index 000000000..bf8f5fcd9
--- /dev/null
+++ b/build/docs/src/components/splitview/active.tsx
@@ -0,0 +1,161 @@
+import {
+ ISplitviewPanel,
+ ISplitviewPanelProps,
+ Orientation,
+ SplitviewReact,
+ SplitviewReadyEvent,
+} from 'dockview';
+import * as React from 'react';
+
+const components = {
+ default: (props: ISplitviewPanelProps<{ title: string }>) => {
+ const [active, setActive] = React.useState(props.api.isActive);
+ const [visible, setVisible] = React.useState(
+ props.api.isVisible
+ );
+ const [focused, setFocused] = React.useState(
+ props.api.isFocused
+ );
+ const [dimensions, setDimensions] = React.useState<{
+ height: number;
+ width: number;
+ }>({
+ height: props.api.height,
+ width: props.api.width,
+ });
+
+ React.useEffect(() => {
+ const disposable1 = props.api.onDidActiveChange((event) =>
+ setActive(event.isActive)
+ );
+ const disposable2 = props.api.onDidVisibilityChange((event) =>
+ setVisible(event.isVisible)
+ );
+ const disposable3 = props.api.onDidFocusChange((event) =>
+ setFocused(event.isFocused)
+ );
+ const disposable4 = props.api.onDidDimensionsChange((event) => {
+ setDimensions({ height: event.height, width: event.width });
+ });
+
+ return () => {
+ disposable1.dispose();
+ disposable2.dispose();
+ disposable3.dispose();
+ disposable4.dispose();
+ };
+ }, []);
+
+ return (
+
+ {'Panel ID: '}
+ {props.api.id}
+ {'Height: '}
+ {`${dimensions.height}px`}
+ {'Width: '}
+ {`${dimensions.width}px`}
+ {'Focused: '}
+ {`${
+ focused ? 'True' : 'False'
+ }`}
+
+ {'Active: '}
+ {`${
+ active ? 'True' : 'False'
+ }`}
+
+ {'Visible: '}
+ {`${
+ visible ? 'True' : 'False'
+ }`}
+
+ );
+ },
+};
+
+export const SplitviewExample1 = (props: { proportional?: boolean }) => {
+ const [panels, setPanels] = React.useState([]);
+
+ const onReady = React.useCallback((event: SplitviewReadyEvent) => {
+ event.api.onDidAddView((panel) => setPanels(event.api.panels));
+ event.api.onDidRemoveView((panel) => setPanels(event.api.panels));
+
+ event.api.addPanel({
+ id: 'panel_1',
+ component: 'default',
+ params: {
+ title: 'Panel 1',
+ },
+ minimumSize: 100,
+ });
+
+ event.api.addPanel({
+ id: 'panel_2',
+ component: 'default',
+ params: {
+ title: 'Panel 2',
+ },
+ minimumSize: 100,
+ });
+
+ event.api.addPanel({
+ id: 'panel_3',
+ component: 'default',
+ params: {
+ title: 'Panel 3',
+ },
+ minimumSize: 100,
+ });
+ }, []);
+
+ return (
+ <>
+
+
+
+
+ {panels.map((panel) => {
+ return (
+
+
{panel.id}
+
+
+ panel.api.setVisible(
+ !panel.api.isVisible
+ )
+ }
+ >
+ Toggle Visiblity
+
+ panel.api.setActive()}>
+ Set Active
+
+
+
+ );
+ })}
+
+ >
+ );
+};
diff --git a/build/docs/src/components/splitview/math.scss b/build/docs/src/components/splitview/math.scss
new file mode 100644
index 000000000..b62b97281
--- /dev/null
+++ b/build/docs/src/components/splitview/math.scss
@@ -0,0 +1,63 @@
+.splitview-math-blog {
+ .sash {
+ background-color: orange;
+ position: absolute;
+ top: 0px;
+ width: 4px;
+ height: 100%;
+ z-index: 2;
+ cursor: ew-resize;
+ user-select: none;
+ }
+
+ .debug-sash-max {
+ height: 10px;
+ width: 1px;
+ position: absolute;
+ z-index: 999;
+ top: -10px;
+ }
+
+ .debug-sash-min {
+ height: 10px;
+ width: 1px;
+ position: absolute;
+ z-index: 999;
+ top: 100%;
+ }
+
+ .debug-sash-text {
+ height: 20px;
+ line-height: 20px;
+ width: 80px;
+ display: flex;
+ justify-content: center;
+ position: absolute;
+ z-index: 999;
+ font-size: 14px;
+ }
+
+ .sash-container {
+ position: absolute;
+ height: 100%;
+ }
+
+ .view-container {
+ position: relative;
+ height: 100%;
+ }
+
+ .view {
+ position: absolute;
+ height: 100%;
+ background-color: dodgerblue;
+ z-index: 1;
+ top: 0px;
+ padding: 10px;
+ color: white;
+ }
+
+ .sash.drag-sash {
+ background-color: red;
+ }
+}
diff --git a/build/docs/src/components/splitview/math.tsx b/build/docs/src/components/splitview/math.tsx
new file mode 100644
index 000000000..eeec3b559
--- /dev/null
+++ b/build/docs/src/components/splitview/math.tsx
@@ -0,0 +1,342 @@
+import * as React from 'react';
+import './math.scss';
+
+const min = 100;
+const max = 300;
+
+interface IDebugResize {
+ leftmin: number;
+ leftmax: number;
+ rightmin: number;
+ rightmax: number;
+ min: number;
+ max: number;
+}
+
+const resize = (
+ index: number,
+ delta: number,
+ sizes: number[],
+ mode: number
+) => {
+ const nextSizes = [...sizes];
+
+ const left = nextSizes.filter((_, i) => i <= index);
+ const right = nextSizes.filter((_, i) => i > index);
+
+ let result: IDebugResize = {
+ leftmin: undefined,
+ leftmax: undefined,
+ rightmin: undefined,
+ rightmax: undefined,
+ max: undefined,
+ min: undefined,
+ };
+
+ // step 3
+ if (mode > 2) {
+ const leftMinimumsDelta = left
+ .map((x) => min - x)
+ .reduce((x, y) => x + y, 0);
+ const leftMaximumsDelta = left
+ .map((x) => max - x)
+ .reduce((x, y) => x + y, 0);
+ const rightMinimumsDelta = right
+ .map((x) => x - min)
+ .reduce((x, y) => x + y, 0);
+ const rightMaximumsDelta = right
+ .map((x) => x - max)
+ .reduce((x, y) => x + y, 0);
+ const _min = Math.max(leftMinimumsDelta, rightMaximumsDelta);
+ const _max = Math.min(leftMaximumsDelta, rightMinimumsDelta);
+ const clamp = Math.max(_min, Math.min(_max, delta));
+
+ result = {
+ leftmin: leftMinimumsDelta,
+ leftmax: leftMaximumsDelta,
+ rightmin: rightMinimumsDelta,
+ rightmax: rightMaximumsDelta,
+ max: _max,
+ min: _min,
+ };
+ delta = clamp;
+ }
+
+ let usedDelta = 0;
+ let remainingDelta = delta;
+
+ // Step 1
+ for (let i = left.length - 1; i > -1; i--) {
+ const x = Math.max(min, Math.min(max, left[i] + remainingDelta));
+ const viewDelta = x - left[i];
+ usedDelta += viewDelta;
+ remainingDelta -= viewDelta;
+ left[i] = x;
+ }
+
+ // Step 2
+ if (mode > 1) {
+ for (let i = 0; i < right.length; i++) {
+ const x = Math.max(min, Math.min(max, right[i] - usedDelta));
+ const viewDelta = x - right[i];
+ usedDelta += viewDelta;
+ right[i] = x;
+ }
+ }
+
+ return { ...result, sizes: [...left, ...right] };
+};
+
+interface ILayoutState {
+ sashes: number[];
+ views: number[];
+ deltas: number[];
+ left: number;
+ right: number;
+ debug: IDebugResize;
+ drag: number;
+}
+
+export const Splitview = (props: { mode: number; debug: boolean }) => {
+ // keep the sashes and views in one state to prevent weird out-of-sync-ness
+ const [layout, setLayout] = React.useState({
+ sashes: [200, 400],
+ views: [200, 200, 200],
+ deltas: [0, 0, 0],
+ left: 0,
+ right: 0,
+ debug: undefined,
+ drag: -1,
+ });
+
+ const ref = React.useRef();
+
+ const onMouseDown = (index: number) => (ev: React.MouseEvent) => {
+ const start = ev.clientX;
+ const sizes = [...layout.views];
+
+ const mousemove = (ev: MouseEvent) => {
+ const current = ev.clientX;
+ const delta = current - start;
+ const {
+ sizes: nextLayout,
+ rightmin,
+ rightmax,
+ leftmin,
+ leftmax,
+ max,
+ min,
+ } = resize(index, delta, sizes, props.mode);
+ const sashes = nextLayout.reduce(
+ (x, y) => [...x, y + (x.length === 0 ? 0 : x[x.length - 1])],
+ []
+ );
+ sashes.splice(sashes.length - 1, 1);
+ const deltas = sizes.map((x, i) => nextLayout[i] - x);
+
+ const offset = start - ref.current?.getBoundingClientRect().left;
+
+ setLayout({
+ views: nextLayout,
+ sashes,
+ deltas,
+ left: deltas
+ .filter((_, i) => i <= index)
+ .reduce((x, y) => x + y, 0),
+ right: deltas
+ .filter((_, i) => i > index)
+ .reduce((x, y) => x + y, 0),
+ debug: {
+ leftmax: leftmax + offset,
+ leftmin: leftmin + offset,
+ rightmax: rightmax + offset,
+ rightmin: rightmin + offset,
+ min: min + offset,
+ max: max + offset,
+ },
+ drag: index,
+ });
+ };
+
+ const end = (ev: MouseEvent) => {
+ document.removeEventListener('mousemove', mousemove);
+ document.removeEventListener('mouseup', end);
+ setLayout((_) => ({
+ ..._,
+ deltas: _.deltas.map((_) => 0),
+ left: 0,
+ right: 0,
+ drag: -1,
+ }));
+ };
+
+ document.addEventListener('mousemove', mousemove);
+ document.addEventListener('mouseup', end);
+ };
+
+ const extras = React.useMemo(() => {
+ if (!props.debug || !layout.debug || props.mode < 3) {
+ return null;
+ }
+ return (
+ <>
+
+ left-max
+
+
+ left-min
+
+
+ right-max
+
+
+ right-min
+
+
+
+
+
+ >
+ );
+ }, [layout.debug]);
+
+ return (
+
+ {props.debug && (
+
+ {`Change to left ${layout?.left}`}
+ {`Change to right ${layout?.right}`}
+ {`Total size ${layout?.views.reduce(
+ (x, y) => x + y,
+ 0
+ )}`}
+
+ )}
+
+
+ {layout.sashes.map((x, i) => {
+ const className =
+ layout.drag === i ? 'sash drag-sash' : 'sash';
+ return (
+
+ );
+ })}
+ {extras}
+
+
+ {layout.views.map((x, i) => {
+ const isMax = x >= max;
+ const isMin = x <= min;
+
+ return (
+
+ {props.debug && (
+ <>
+
+ {`${layout.views[i]} (${
+ layout.deltas[i] > -1 ? '+' : ''
+ }${layout.deltas[i]})`}
+
+
{`isMin = ${isMin}`}
+
{`isMax = ${isMax}`}
+ >
+ )}
+
+ );
+ })}
+
+
+
+ );
+};
diff --git a/build/docs/src/css/custom.css b/build/docs/src/css/custom.css
new file mode 100644
index 000000000..9a917885e
--- /dev/null
+++ b/build/docs/src/css/custom.css
@@ -0,0 +1,32 @@
+/**
+ * Any CSS included here will be global. The classic template
+ * bundles Infima by default. Infima is a CSS framework designed to
+ * work well for content-centric websites.
+ */
+
+/* You can override the default Infima variables here. */
+:root {
+ --ifm-color-primary: #2e8555;
+ --ifm-color-primary-dark: #29784c;
+ --ifm-color-primary-darker: #277148;
+ --ifm-color-primary-darkest: #205d3b;
+ --ifm-color-primary-light: #33925d;
+ --ifm-color-primary-lighter: #359962;
+ --ifm-color-primary-lightest: #3cad6e;
+ --ifm-code-font-size: 95%;
+ --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
+}
+
+/* For readability concerns, you should choose a lighter palette in dark mode. */
+[data-theme='dark'] {
+ --ifm-color-primary: #25c2a0;
+ --ifm-color-primary-dark: #21af90;
+ --ifm-color-primary-darker: #1fa588;
+ --ifm-color-primary-darkest: #1a8870;
+ --ifm-color-primary-light: #29d5b0;
+ --ifm-color-primary-lighter: #32d8b4;
+ --ifm-color-primary-lightest: #4fddbf;
+ --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
+}
+
+@import "~dockview/dist/styles/dockview.css"
diff --git a/build/docs/src/misc/math/constraints.jpg b/build/docs/src/misc/math/constraints.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a43a30933c6879ed4668e84e97e4730de71c5d39
GIT binary patch
literal 137417
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
z
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 +3}
zFDOJrWmmq%6Q8ktfN%@S>GEYp03Mw_zku}0iy^|A37+A3W&}FMh%vuZqLA7{a&E>;
zsNh#4`V)zf+k~?0G+M_2hM;3YDO6jQ{;d|?S%7z-avnm?#AXtYsfQbimx{C~knm!f
zH5S|VG8+uhU$#(Y21b{%JN&q9C2HHcH4K(&S3tL|q-S(}hgE9cpLY?x#8Y=0inS$;&}w&)SRovc|l2TOk$pJs*JL
zTu*iZigWFep^C;g8!(pxDjn&yH!LB^Re>LhyKPv}$Z3KvJ*r%(
zIYjz7Ze&?rJ9jT1k?QE7pMInhcloUEnj^$sXE?DT85yfTK)t~^My&fc!&eUh3Og?m
z4mRyzNy1=9lpcnbInNb^Ur``%ZpO)%eEEr!@B6Acm71m&wk&auJJ`$_JiFA_D$cp#
ziN>h4x$Y;oZz=0mv