Merge pull request #217 from mathuo/208-documentation-examples-1

chore: docs
This commit is contained in:
mathuo 2023-03-25 20:38:01 +00:00 committed by GitHub
commit a51740c123
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 4270 additions and 4108 deletions

View File

@ -6,7 +6,9 @@
"sandboxes": [
"/packages/docs/sandboxes/constraints-dockview",
"/packages/docs/sandboxes/customheader-dockview",
"/packages/docs/sandboxes/demo-dockview",
"/packages/docs/sandboxes/dnd-dockview",
"/packages/docs/sandboxes/dockview-app",
"/packages/docs/sandboxes/events-dockview",
"/packages/docs/sandboxes/externaldnd-dockview",
"/packages/docs/sandboxes/fullwidthtab-dockview",

View File

@ -1,7 +1,7 @@
{
"out": "typedocs",
"entryPoints": ["./src/index.ts"],
"exclude": ["**/_test/**/*.*", "**/index.ts"],
"excludeExternals": true,
"excludePrivate": true
"out": "typedocs",
"entryPoints": ["./src/index.ts"],
"exclude": ["**/_test/**/*.*", "**/index.ts"],
"excludeExternals": true,
"excludePrivate": true
}

View File

@ -1,7 +1,7 @@
{
"out": "typedocs",
"entryPoints": ["./src/index.ts"],
"exclude": ["**/_test/**/*.*", "**/index.ts"],
"excludeExternals": true,
"excludePrivate": true
"out": "typedocs",
"entryPoints": ["./src/index.ts"],
"exclude": ["**/_test/**/*.*", "**/index.ts"],
"excludeExternals": true,
"excludePrivate": true
}

View File

@ -0,0 +1,28 @@
---
slug: dockview-1.7.0-release
title: Dockview 1.7.0
tags: [release]
---
# Release Notes
Please reference to docs @ [dockview.dev](https://dockview.dev).
If you feel anything is missing or unclear please let me know.
## 🚀 Features
- The `title` parameter for dockview panels has been made optional [#197](https://github.com/mathuo/dockview/pull/197).
- Simplify dockview `toJSON()` format. `1.7.0` will continue to load legacy formats successfully. [#199](https://github.com/mathuo/dockview/pull/199).
- Examples found @ [dockview.dev](https://dockview.dev) now all link to CodeSandboxes where you can try them out for yourself and view the underlying code.
- Fix dockview group api `setContaints` method to work as expected. [#212](https://github.com/mathuo/dockview/pull/212).
- Fix dnd events for third-party dnd controls within dockview panels [#126](https://github.com/mathuo/dockview/pull/216).
## 🛠 Miscs
- Split `dockview` into two packages, `dockview-core` containing the core logic and `dockview` containing the react wrapper. [#174](https://github.com/mathuo/dockview/pull/174) [#199](https://github.com/mathuo/dockview/pull/199).
- `dockview` depends on `dockview-core` so no installation changes are required, you still only need to install `dockview`.
- This is work in progress for supporting a vanilla JS version of dockview. At this time `dockview-core` is not designed to be used directly.
## 🔥 Breaking changes
- Remove `setConstraints` from the dockview panel api. [#212](https://github.com/mathuo/dockview/pull/212).

View File

@ -2,11 +2,7 @@
description: Dockview Documentation
---
import { Container } from '@site/src/components/container';
import {
RenderingDockview,
Checkbox,
} from '@site/src/components/dockview/rendering';
import { Container } from '@site/src/components/ui/container';
import Link from '@docusaurus/Link';
import useBaseUrl from '@docusaurus/useBaseUrl';
@ -24,6 +20,7 @@ import CustomHeadersDockview from '@site/sandboxes/customheader-dockview/src/app
import DockviewNative from '@site/sandboxes/fullwidthtab-dockview/src/app';
import DockviewNative2 from '@site/sandboxes/nativeapp-dockview/src/app';
import DockviewSetTitle from '@site/sandboxes/updatetitle-dockview/src/app';
import RenderingDockview from '@site/sandboxes/rendering-dockview/src/app';
import DockviewExternalDnd from '@site/sandboxes/externaldnd-dockview/src/app';
// import { attach as attachDockviewVanilla } from '@site/sandboxes/vanilla-dockview/src/app';
@ -42,10 +39,10 @@ The group will always be defined and will change if a panel is moved into anothe
## DockviewReact Component
You can create a Dockview through the use of the `ReactDockview` component.
You can create a Dockview through the use of the `DockviewReact` component.
```tsx
import { ReactDockview } from 'dockview';
import { DockviewReact } from 'dockview';
```
| Property | Type | Optional | Default | Description |
@ -470,17 +467,9 @@ const components = { default: RenderWhenVisible(MyComponent) };
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.
<Checkbox />
<div
style={{
height: '300px',
backgroundColor: 'rgb(30,30,30)',
color: 'white',
margin: '20px 0px',
}}
>
<Container sandboxId="rendering-dockview">
<RenderingDockview renderVisibleOnly={false} />
</div>
</Container>
## Headers

View File

@ -16,8 +16,9 @@
"deploy-docs": "node scripts/package-docs.js"
},
"dependencies": {
"@docusaurus/core": "2.3.1",
"@docusaurus/preset-classic": "2.3.1",
"@docusaurus/core": "^2.4.0",
"@docusaurus/module-type-aliases": "^2.4.0",
"@docusaurus/preset-classic": "^2.4.0",
"@mdx-js/react": "^1.6.22",
"@minoru/react-dnd-treeview": "^3.4.3",
"axios": "^1.3.3",

View File

@ -19,6 +19,13 @@ const components = {
});
}, []);
const onClick = () => {
props.api.group.api.setConstraints({
maximumWidth: 300,
maximumHeight: 300,
});
};
return (
<div
style={{
@ -28,6 +35,7 @@ const components = {
color: 'white',
}}
>
<button onClick={onClick}>Set</button>
{contraints && (
<div style={{ fontSize: '13px' }}>
{typeof contraints.maximumHeight === 'number' && (
@ -127,11 +135,6 @@ const App = () => {
direction: 'below',
},
});
panel2.api.group.api.setConstraints({
maximumWidth: 300,
maximumHeight: 300,
});
};
return (

View File

@ -0,0 +1,31 @@
{
"name": "watermark-dockview",
"description": "",
"keywords": [
"dockview"
],
"version": "1.0.0",
"main": "src/index.tsx",
"dependencies": {
"dockview": "*",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"typescript": "^4.9.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

View File

@ -1,19 +1,3 @@
.news-panel {
height: 100%;
overflow: auto;
.story {
display: flex;
flex-direction: column;
justify-content: start;
.link {
color: white !important;
font-size: 11px;
}
}
}
.group-control {
.action {
padding: 4px;

View File

@ -8,114 +8,12 @@ import {
} from 'dockview';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { CURRENCIES, Currency, getCurrencies, getPrice } from './api';
import './demo.scss';
const CurrencyRow = (props: { currency: Currency }) => {
const [price, setPrice] = React.useState<number>();
React.useEffect(() => {
getPrice(props.currency.id, 'USD').then((result) => {
setPrice(Number(result.data.amount));
});
}, [props.currency]);
return (
<>
<div>{props.currency.id}</div>
<div>{`${typeof price === 'number' ? `$${price}` : '-'}`}</div>
</>
);
};
const Currencies = () => {
const [currencies, setCurrencies] = React.useState<Currency[]>([]);
React.useEffect(() => {
Promise.all(CURRENCIES.map(getCurrencies)).then((results) => {
setCurrencies(results.filter(Boolean));
});
}, []);
return (
<div
style={{
height: '100%',
overflow: 'auto',
margin: '10px',
}}
>
<div
style={{
display: 'grid',
gridTemplateColumns: '50px 100px',
justifyItems: 'start',
}}
>
{currencies.map((currency) => (
<CurrencyRow key={currency.id} currency={currency} />
))}
</div>
</div>
);
};
import axios from 'axios';
import { BrowserHeader } from '../browserHeader';
type Article = {
id: 15255;
title: string;
url: string;
imageUrl: string;
newsSite: string;
summary: string;
publishedAt: string;
updatedAt: string;
featured: boolean;
launches: any[];
events: any[];
};
async function getStories(): Promise<Article[]> {
const response = await axios.get<Article[]>(
'https://api.spaceflightnewsapi.net/v3/articles'
);
return response.data;
}
const News = () => {
const [stories, setStories] = React.useState<Article[]>([]);
React.useEffect(() => {
getStories().then(setStories);
}, []);
return (
<div className="news-panel">
{stories.map((story) => {
return (
<div className="story">
<div className="metadata">
<span>{story.title}</span>
</div>
<div className="link">
<a href={story.url}>{story.url.substring(0, 10)}</a>
</div>
</div>
);
})}
</div>
);
};
import './app.scss';
const components = {
default: (props: IDockviewPanelProps<{ title: string }>) => {
return <div style={{ padding: '20px' }}>{props.params.title}</div>;
},
currencies: Currencies,
news: News,
};
const headerComponents = {
@ -154,7 +52,7 @@ const Popover = (props: {
target = target.parentElement;
}
} else {
target = undefined;
target = null;
}
}
@ -170,7 +68,7 @@ const Popover = (props: {
}, [props.close, uuid]);
if (!props.position) {
return;
return null;
}
return ReactDOM.createPortal(
@ -209,8 +107,9 @@ const Icon = (props: {
};
const Button = () => {
const [position, setPosition] =
React.useState<{ x: number; y: number } | undefined>(undefined);
const [position, setPosition] = React.useState<
{ x: number; y: number } | undefined
>(undefined);
const close = () => setPosition(undefined);
@ -263,10 +162,8 @@ const GroupControls = (props: IDockviewGroupControlProps) => {
);
};
export const DockviewDemo = () => {
const DockviewDemo = () => {
const onReady = (event: DockviewReadyEvent) => {
const d = localStorage.getItem('test');
event.api.addPanel({
id: 'panel_1',
component: 'default',
@ -317,39 +214,18 @@ export const DockviewDemo = () => {
event.api.addGroup();
event.api.getPanel('panel_1').api.setActive();
// setInterval(() => {
// event.api.getPanel('panel_1').update({
// params: {
// params: {
// title: Date.now().toString(),
// },
// },
// });
// }, 1000);
event.api.getPanel('panel_1')!.api.setActive();
};
return (
<div
id="homepage-dockview-demo"
style={{
height: '530px',
margin: '40px 0px',
display: 'flex',
flexDirection: 'column',
}}
>
<BrowserHeader />
<div style={{ flexGrow: 1 }}>
<DockviewReact
components={components}
defaultTabComponent={headerComponents.default}
groupControlComponent={GroupControls}
onReady={onReady}
className="dockview-theme-abyss"
/>
</div>
</div>
<DockviewReact
components={components}
defaultTabComponent={headerComponents.default}
groupControlComponent={GroupControls}
onReady={onReady}
className="dockview-theme-abyss"
/>
);
};
export default DockviewDemo;

View File

@ -0,0 +1,20 @@
import { StrictMode } from 'react';
import * as ReactDOMClient from 'react-dom/client';
import './styles.css';
import 'dockview/dist/styles/dockview.css';
import App from './app';
const rootElement = document.getElementById('root');
if (rootElement) {
const root = ReactDOMClient.createRoot(rootElement);
root.render(
<StrictMode>
<div className="app">
<App />
</div>
</StrictMode>
);
}

View File

@ -0,0 +1,16 @@
body {
margin: 0px;
color: white;
font-family: sans-serif;
text-align: center;
}
#root {
height: 100vh;
width: 100vw;
}
.app {
height: 100%;
}

View File

@ -0,0 +1,20 @@
{
"compilerOptions": {
"outDir": "build/dist",
"module": "esnext",
"target": "es5",
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"jsx": "react-jsx",
"moduleResolution": "node",
"rootDir": "src",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true
}
}

View File

@ -0,0 +1,31 @@
{
"name": "watermark-dockview",
"description": "",
"keywords": [
"dockview"
],
"version": "1.0.0",
"main": "src/index.tsx",
"dependencies": {
"dockview": "*",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"typescript": "^4.9.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

View File

@ -7,8 +7,6 @@ import {
PaneviewReadyEvent,
} from 'dockview';
import * as React from 'react';
import { BrowserHeader } from '../browserHeader';
import './demo2.scss';
const paneComponents = {
default: (props: IPaneviewPanelProps) => {
@ -71,17 +69,11 @@ const components = {
});
};
return (
<PaneviewReact
onReady={onReady}
components={paneComponents}
className="paneview-background"
/>
);
return <PaneviewReact onReady={onReady} components={paneComponents} />;
},
};
export const DockviewDemo2 = () => {
const DockviewDemo2 = () => {
const onReady = (event: GridviewReadyEvent) => {
event.api.addPanel({
id: 'panes',
@ -116,22 +108,12 @@ export const DockviewDemo2 = () => {
};
return (
<div
style={{
height: '530px',
margin: '40px 0px',
display: 'flex',
flexDirection: 'column',
}}
>
<BrowserHeader />
<div style={{ flexGrow: 1 }}>
<GridviewReact
onReady={onReady}
components={components}
className="dockview-theme-abyss"
/>
</div>
</div>
<GridviewReact
onReady={onReady}
components={components}
className="dockview-theme-abyss"
/>
);
};
export default DockviewDemo2;

View File

@ -0,0 +1,20 @@
import { StrictMode } from 'react';
import * as ReactDOMClient from 'react-dom/client';
import './styles.css';
import 'dockview/dist/styles/dockview.css';
import App from './app';
const rootElement = document.getElementById('root');
if (rootElement) {
const root = ReactDOMClient.createRoot(rootElement);
root.render(
<StrictMode>
<div className="app">
<App />
</div>
</StrictMode>
);
}

View File

@ -0,0 +1,16 @@
body {
margin: 0px;
color: white;
font-family: sans-serif;
text-align: center;
}
#root {
height: 100vh;
width: 100vw;
}
.app {
height: 100%;
}

View File

@ -0,0 +1,20 @@
{
"compilerOptions": {
"outDir": "build/dist",
"module": "esnext",
"target": "es5",
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"jsx": "react-jsx",
"moduleResolution": "node",
"rootDir": "src",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true
}
}

View File

@ -0,0 +1,31 @@
{
"name": "watermark-dockview",
"description": "",
"keywords": [
"dockview"
],
"version": "1.0.0",
"main": "src/index.tsx",
"dependencies": {
"dockview": "*",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"typescript": "^4.9.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

View File

@ -89,7 +89,22 @@ const components = {
),
};
export const RenderingDockview = (props: { renderVisibleOnly: boolean }) => {
const Checkbox = () => {
const [render, setRender] = useRecoilState(renderVisibleComponentsOnlyAtom);
return (
<label>
Render only when visible
<input
type="checkbox"
checked={render}
onChange={(e) => setRender(e.target.checked)}
/>
</label>
);
};
const RenderingDockview = (props: { renderVisibleOnly: boolean }) => {
const [render, setRender] = useRecoilState(renderVisibleComponentsOnlyAtom);
React.useEffect(
@ -133,25 +148,23 @@ export const RenderingDockview = (props: { renderVisibleOnly: boolean }) => {
};
return (
<DockviewReact
components={components}
onReady={onReady}
className="dockview-theme-abyss"
/>
<div
style={{
display: 'flex',
flexDirection: 'column',
height: '100%',
}}
>
<Checkbox />
<div style={{ flexGrow: 1, color: 'white' }}>
<DockviewReact
components={components}
onReady={onReady}
className="dockview-theme-abyss"
/>
</div>
</div>
);
};
export const Checkbox = () => {
const [render, setRender] = useRecoilState(renderVisibleComponentsOnlyAtom);
return (
<label>
Render only when visible
<input
type="checkbox"
checked={render}
onChange={(e) => setRender(e.target.checked)}
/>
</label>
);
};
export default RenderingDockview;

View File

@ -0,0 +1,20 @@
import { StrictMode } from 'react';
import * as ReactDOMClient from 'react-dom/client';
import './styles.css';
import 'dockview/dist/styles/dockview.css';
import App from './app';
const rootElement = document.getElementById('root');
if (rootElement) {
const root = ReactDOMClient.createRoot(rootElement);
root.render(
<StrictMode>
<div className="app">
<App />
</div>
</StrictMode>
);
}

View File

@ -0,0 +1,16 @@
body {
margin: 0px;
color: white;
font-family: sans-serif;
text-align: center;
}
#root {
height: 100vh;
width: 100vw;
}
.app {
height: 100%;
}

View File

@ -0,0 +1,20 @@
{
"compilerOptions": {
"outDir": "build/dist",
"module": "esnext",
"target": "es5",
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"jsx": "react-jsx",
"moduleResolution": "node",
"rootDir": "src",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true
}
}

View File

@ -1,109 +0,0 @@
import * as React from 'react';
import './container.scss';
const BASE_SANDBOX_URL =
'https://codesandbox.io/s/github/mathuo/dockview/tree/master/packages/docs/sandboxes';
const createSvgElementFromPath = (params: {
height: string;
width: string;
viewbox: string;
path: string;
}) => {
return (
<svg
height={params.height}
width={params.width}
viewBox={params.viewbox}
focusable={false}
className={'dockview-svg'}
>
<path d={params.path} />
</svg>
);
};
export const CreateCloseButton = () =>
createSvgElementFromPath({
width: '16',
height: '16',
viewbox: '0 0 50 58',
path: 'M22.5581 50.9938V30.1717L4.65116 19.869V31.7386L12.8536 36.4939V45.4198L22.5581 50.9938ZM27.2093 51.1162L37.0931 45.4226V36.2851L45.3488 31.501V19.7801L27.2093 30.2529V51.1162ZM42.9633 15.7867L33.4288 10.2615L25.0571 15.1193L16.6219 10.2567L7.00237 15.8557L24.9542 26.1842L42.9633 15.7867ZM0 43.4008V14.5498L24.9974 0L50 14.4887V43.3552L24.9969 57.7584L0 43.4008Z',
});
export const Container = (props: {
children?: React.ReactNode;
height?: number;
injectVanillaJS?: (parent: HTMLElement) => void;
sandboxId?: string;
}) => {
const ref = React.useRef<HTMLDivElement>(null);
const url = React.useMemo(() => {
if (!props.sandboxId) {
return '';
}
return `${BASE_SANDBOX_URL}/${props.sandboxId}`;
}, [props.sandboxId]);
React.useEffect(() => {
if (!props.injectVanillaJS) {
return;
}
props.injectVanillaJS(ref.current);
}, [props.injectVanillaJS]);
return (
<>
<div
ref={ref}
style={{
height: props.height ? `${props.height}px` : '300px',
}}
>
{props.children}
</div>
<div
style={{
padding: '2px 0px',
display: 'flex',
alignItems: 'center',
fontSize: '14px',
}}
>
<span style={{ flexGrow: 1 }} />
{url && (
<span
className="codesandbox-button"
style={{ display: 'flex', alignItems: 'center' }}
>
<span className="codesandbox-button-pretext">{`Open in `}</span>
<a
href={url}
target={'_blank'}
className="codesandbox-button-content"
>
<span
style={{
fontWeight: 'bold',
paddingRight: '4px',
}}
>
CodeSandbox
</span>
<CreateCloseButton />
</a>
</span>
)}
{/* <span
style={{ fontSize: '16px' }}
className="material-symbols-outlined"
>
open_in_new
</span> */}
</div>
</>
);
};

View File

@ -1,72 +0,0 @@
import axios from 'axios';
const EXCHANGE_URL = 'https://api.exchange.coinbase.com';
const URL = 'https://api.coinbase.com/v2';
export interface Currency {
id: string;
name: string;
min_size: string;
max_precision: string;
status: string;
details: {
type: string;
symbol: string;
sort_order: number;
push_payment_methods: string[];
display_name: string;
group_types: string[];
};
}
export interface Price {
data: { base: string; currency: string; amount: string };
}
export async function allCurrencies(): Promise<Currency[]> {
try {
const response = await axios.get<Currency[]>(
`${EXCHANGE_URL}/currencies`,
{
headers: { Accept: 'application/json' },
}
);
return response.data;
} catch (err) {
return [];
}
}
export async function getCurrencies(id: string): Promise<Currency | null> {
try {
const response = await axios.get<Currency>(
`${EXCHANGE_URL}/currencies/${id}`,
{
headers: { Accept: 'application/json' },
}
);
return response.data;
} catch (err) {
return null;
}
}
export async function getPrice(base: string, quote: string) {
try {
const response = await axios.get<Price>(
`${URL}/prices/${base}-${quote}/buy`,
{
headers: { Accept: 'application/json' },
}
);
return response.data;
} catch (err) {
return null;
}
}
export const CURRENCIES = ['BTC', 'ETH', 'LTC'];

View File

@ -1,3 +0,0 @@
.paneview-background {
background-color: var(--dv-group-view-background-color);
}

View File

@ -1,126 +0,0 @@
import {
DockviewReact,
DockviewReadyEvent,
IDockviewPanelProps,
Position,
Direction,
IDockviewPanelHeaderProps,
} from 'dockview';
import * as React from 'react';
import './native.scss';
const components = {
default: (props: IDockviewPanelProps<{ title: string; x?: number }>) => {
return (
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
color: 'white',
height: '100%',
}}
>
<span>{`${props.params.title}`}</span>
{props.params.x && <span>{` ${props.params.x}`}</span>}
</div>
);
},
isolatedApp: (
props: IDockviewPanelProps<{ title: string; x?: number }>
) => {
const onReady = (event: DockviewReadyEvent) => {
const panel1 = event.api.addPanel({
id: 'panel_1',
component: 'default',
params: {
title: 'Tab 1',
},
});
const panel2 = event.api.addPanel({
id: 'panel_2',
component: 'default',
params: {
title: 'Tab 2',
},
});
const panel3 = event.api.addPanel({
id: 'panel_3',
component: 'default',
params: {
title: 'Tab 3',
},
});
};
return (
<DockviewReact
onReady={onReady}
components={components}
className="dockview-theme-abyss"
/>
);
},
};
export const DockviewFullWidthTabs = () => {
const onReady = (event: DockviewReadyEvent) => {
const panel1 = event.api.addPanel({
id: 'panel_1',
component: 'default',
params: {
title: 'Tab 1',
},
});
const panel2 = event.api.addPanel({
id: 'panel_2',
component: 'default',
params: {
title: 'Tab 2',
},
position: {
direction: 'right',
},
});
const panel3 = event.api.addPanel({
id: 'panel_3',
component: 'default',
params: {
title: 'Tab 3',
},
position: {
direction: 'below',
},
});
const panel4 = event.api.addPanel({
id: 'panel_4',
component: 'default',
params: {
title: 'Tab 3',
},
position: {
referencePanel: panel3,
},
});
};
return (
<div
style={{
height: '500px',
display: 'flex',
padding: '8px',
flexDirection: 'column',
}}
>
<DockviewReact
onReady={onReady}
components={components}
className="dockview-theme-abyss"
singleTabMode="fullwidth"
/>
</div>
);
};

View File

@ -6,7 +6,7 @@ import {
GridviewApi,
} from 'dockview';
import * as React from 'react';
import { Console, Line } from '../console/console';
import { Console, Line } from '../ui/console/console';
const components = {
default: (props: IGridviewPanelProps<{ title: string }>) => {

View File

@ -6,7 +6,7 @@ import {
PaneviewDndOverlayEvent,
} from 'dockview';
import * as React from 'react';
import { Console, Line } from '../console/console';
import { Console, Line } from '../ui/console/console';
import './sideBySide.scss';
const components = {

View File

@ -1,2 +0,0 @@
import * as React from 'react';
const URL = 'https://api.github.com/repos/mathuo/dockview/releases';

View File

@ -0,0 +1,65 @@
import * as React from 'react';
import './codeSandboxButton.scss';
const BASE_SANDBOX_URL =
'https://codesandbox.io/s/github/mathuo/dockview/tree/master/packages/docs/sandboxes';
const createSvgElementFromPath = (params: {
height: string;
width: string;
viewbox: string;
path: string;
}) => {
return (
<svg
height={params.height}
width={params.width}
viewBox={params.viewbox}
focusable={false}
className={'dockview-svg'}
>
<path d={params.path} />
</svg>
);
};
const CloseButton = () =>
createSvgElementFromPath({
width: '16',
height: '16',
viewbox: '0 0 50 58',
path: 'M22.5581 50.9938V30.1717L4.65116 19.869V31.7386L12.8536 36.4939V45.4198L22.5581 50.9938ZM27.2093 51.1162L37.0931 45.4226V36.2851L45.3488 31.501V19.7801L27.2093 30.2529V51.1162ZM42.9633 15.7867L33.4288 10.2615L25.0571 15.1193L16.6219 10.2567L7.00237 15.8557L24.9542 26.1842L42.9633 15.7867ZM0 43.4008V14.5498L24.9974 0L50 14.4887V43.3552L24.9969 57.7584L0 43.4008Z',
});
export const CodeSandboxButton = (props: { id: string }) => {
const url = React.useMemo(() => {
if (!props.id) {
return '';
}
return `${BASE_SANDBOX_URL}/${props.id}`;
}, [props.id]);
return (
<span
className="codesandbox-button"
style={{ display: 'flex', alignItems: 'center' }}
>
<span className="codesandbox-button-pretext">{`Open in `}</span>
<a
href={url}
target={'_blank'}
className="codesandbox-button-content"
>
<span
style={{
fontWeight: 'bold',
paddingRight: '4px',
}}
>
CodeSandbox
</span>
<CloseButton />
</a>
</span>
);
};

View File

@ -0,0 +1,43 @@
import * as React from 'react';
import { CodeSandboxButton } from './codeSandboxButton';
export const Container = (props: {
children?: React.ReactNode;
height?: number;
injectVanillaJS?: (parent: HTMLElement) => void;
sandboxId?: string;
}) => {
const ref = React.useRef<HTMLDivElement>(null);
React.useEffect(() => {
if (!props.injectVanillaJS) {
return;
}
props.injectVanillaJS(ref.current);
}, [props.injectVanillaJS]);
return (
<>
<div
ref={ref}
style={{
height: props.height ? `${props.height}px` : '300px',
}}
>
{props.children}
</div>
<div
style={{
padding: '2px 0px',
display: 'flex',
alignItems: 'center',
fontSize: '14px',
}}
>
<span style={{ flexGrow: 1 }} />
{props.sandboxId && <CodeSandboxButton id={props.sandboxId} />}
</div>
</>
);
};

View File

@ -1,80 +0,0 @@
import {
DockviewComponent,
GroupPanelContentPartInitParameters,
IContentRenderer,
ITabRenderer,
} from 'dockview-core';
import * as React from 'react';
class CustomPanel implements IContentRenderer {
element = document.createElement('div');
init(parameters: GroupPanelContentPartInitParameters): void {
//
}
}
class CustomTab implements ITabRenderer {
element = document.createElement('div');
init(parameters: GroupPanelContentPartInitParameters): void {
this.element.textContent = `Custom (${parameters.api.title})`;
}
}
export const DockviewVanilla = () => {
const ref = React.useRef<HTMLDivElement>();
React.useEffect(() => {
if (!ref.current) {
return;
}
const container = document.createElement('div');
ref.current.appendChild(container);
const dockviewComponent = new DockviewComponent(container, {
components: {
myCustomPanel: CustomPanel,
},
tabComponents: {
myCustomTab: CustomTab,
},
});
const observer = new ResizeObserver((entires) => {
const firstEntry = entires[0];
const { width, height } = firstEntry.contentRect;
dockviewComponent.layout(width, height);
});
observer.observe(ref.current);
dockviewComponent.addPanel({
component: 'myCustomPanel',
tabComponent: 'myCustomTab',
id: '1',
title: 'Panel 1',
});
dockviewComponent.addPanel({
component: 'myCustomPanel',
id: '2',
title: 'Panel 2',
});
return () => {
dockviewComponent.dispose();
};
}, []);
return (
<div
className="dockview-theme-abyss"
ref={ref}
style={{
height: '500px',
backgroundColor: 'red',
}}
></div>
);
};

View File

@ -5,10 +5,12 @@ import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import styles from './index.module.css';
import HomepageFeatures from '@site/src/components/HomepageFeatures';
import { DockviewDemo } from '../components/dockview/demo';
import useBaseUrl from '@docusaurus/useBaseUrl';
import DockviewDemo from '@site/sandboxes/demo-dockview/src/app';
import DockviewDemo2 from '@site/sandboxes/dockview-app/src/app';
import { Container } from '../components/ui/container';
import { BrowserHeader } from '../components/ui/browserHeader';
import './index.scss';
import { DockviewDemo2 } from '../components/dockview/demo2';
function HomepageHeader() {
const { siteConfig } = useDocusaurusContext();
@ -91,8 +93,18 @@ export default function Home(): JSX.Element {
Dockview Live Demos
</span>
</div>
<DockviewDemo />
<DockviewDemo2 />
<div style={{ padding: '20px' }}>
<BrowserHeader />
<Container height={500} sandboxId="demo-dockview">
<DockviewDemo />
</Container>
</div>
<div style={{ padding: '20px' }}>
<BrowserHeader />
<Container height={500} sandboxId="dockview-app">
<DockviewDemo2 />
</Container>
</div>
</main>
</Layout>
);

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 55 KiB

View File

@ -2,24 +2,26 @@
description: Dockview Documentation
---
import {
RenderingDockview,
Checkbox,
} from '@site/src/components/dockview/rendering';
import { Container } from '@site/src/components/ui/container';
import Link from '@docusaurus/Link';
import useBaseUrl from '@docusaurus/useBaseUrl';
import DockviewPersistance from '@site/sandboxes/layout-dockview/src/app';
import SimpleDockview from '@site/sandboxes/simple-dockview/src/app';
import ResizeDockview from '@site/sandboxes/resize-dockview/src/app';
import DockviewWatermark from '@site/sandboxes/watermark-dockview/src/app';
import DockviewConstraints from '@site/sandboxes/constraints-dockview/src/app';
import DndDockview from '@site/sandboxes/dnd-dockview/src/app';
import NestedDockview from '@site/sandboxes/nested-dockview/src/app';
import EventsDockview from '@site/sandboxes/events-dockview/src/app';
import DndDockview from '@site/sandboxes/dnd-dockview/src/app';
import DockviewGroupControl from '@site/sandboxes/groupcontrol-dockview/src/app';
import DockviewWatermark from '@site/sandboxes/watermark-dockview/src/app';
import CustomHeadersDockview from '@site/sandboxes/customheader-dockview/src/app';
import DockviewNative from '@site/sandboxes/fullwidthtab-dockview/src/app';
import DockviewNative2 from '@site/sandboxes/nativeapp-dockview/src/app';
import DockviewSetTitle from '@site/sandboxes/updatetitle-dockview/src/app';
import RenderingDockview from '@site/sandboxes/rendering-dockview/src/app';
// import { attach as attachDockviewVanilla } from '@site/sandboxes/vanilla-dockview/src/app';
# Dockview
@ -27,26 +29,19 @@ import DockviewNative2 from '@site/sandboxes/nativeapp-dockview/src/app';
Dockview is an abstraction built on top of [Gridviews](./gridview) where each view is a container of many tabbed panels.
<div
style={{
height: '300px',
backgroundColor: 'rgb(30,30,30)',
color: 'white',
margin: '20px 0px',
}}
>
<Container sandboxId="simple-dockview">
<SimpleDockview />
</div>
</Container>
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
You can create a Dockview through the use of the `ReactDockview` component.
You can create a Dockview through the use of the `DockviewReact` component.
```tsx
import { ReactDockview } from 'dockview';
import { DockviewReact } from 'dockview';
```
| Property | Type | Optional | Default | Description |
@ -211,7 +206,9 @@ const onReady = (event: DockviewReadyEvent) => {
Here is an example using the above code loading from and saving to localStorage.
If you refresh the page you should notice your layout is loaded as you left it.
<DockviewPersistance />
<Container sandboxId="layout-dockview">
<DockviewPersistance />
</Container>
## Resizing
@ -238,7 +235,9 @@ props.api.group.api.setSize({
You can see an example invoking both approaches below.
<ResizeDockview />
<Container sandboxId="resize-dockview">
<ResizeDockview />
</Container>
## Watermark
@ -246,7 +245,9 @@ When the dockview is empty you may want to display some fallback content, this i
By default there the watermark has no content but you can provide as a prop to `DockviewReact` a `watermarkComponent`
which will be rendered when there are no panels or groups.
<DockviewWatermark />
<Container sandboxId="watermark-dockview">
<DockviewWatermark />
</Container>
## Drag And Drop
@ -323,7 +324,9 @@ return (
);
```
<DndDockview />
<Container sandboxId="dnd-dockview">
<DndDockview />
</Container>
## Panels
@ -455,17 +458,9 @@ const components = { default: RenderWhenVisible(MyComponent) };
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.
<Checkbox />
<div
style={{
height: '300px',
backgroundColor: 'rgb(30,30,30)',
color: 'white',
margin: '20px 0px',
}}
>
<Container sandboxId="rendering-dockview">
<RenderingDockview renderVisibleOnly={false} />
</div>
</Container>
## Headers
@ -514,12 +509,14 @@ You can also override the default tab renderer which will be used when no `tabCo
<DockviewReact defaultTabComponent={MyCustomHeader} ... />;
```
As a simple example the below attachs a custom event handler for the context menu on all tabs as a default tab renderer
As a simple example the below attaches a custom event handler for the context menu on all tabs as a default tab renderer
The below example uses a custom tab renderer to reigster a popover when the user right clicked on a tab.
This still makes use of the `DockviewDefaultTab` since it's only a minor change.
<CustomHeadersDockview />
<Container sandboxId="customheader-dockview">
<CustomHeadersDockview />
</Container>
### Default Tab Title
@ -537,11 +534,15 @@ You can update the title through the panel api which can be accessed via `props.
component or via `api.getPanel('panel1').api` if you are accessing from outside of the panel component.
```tsx
api.updateTitle('my_new_custom_title');
api.setTitle('my_new_custom_title');
```
> Note this only works when using the default tab implementation.
<Container sandboxId="updatetitle-dockview">
<DockviewSetTitle />
</Container>
### Custom Tab Title
If you are using a custom tab implementation you should pass variables through as a parameter and render them
@ -587,7 +588,9 @@ to the entire width of the group. For example:
<DockviewReactComponent singleTabMode="fullwidth" {...otherProps} />
```
<DockviewNative />
<Container sandboxId="fullwidthtab-dockview">
<DockviewNative />
</Container>
## Groups
@ -639,11 +642,33 @@ const GroupControlComponent = (props: IDockviewGroupControlProps) => {
};
```
<DockviewGroupControl />
<Container sandboxId="groupcontrol-dockview">
<DockviewGroupControl />
</Container>
### Constraints
You may wish to specify a minimum or maximum height or width for a group which can be done through the group api.
```tsx
api.group.api.setConstraints(...)
```
> Constraints are currently only supported for groups and not individual panels.
> If you specific a constraint on a group and move a panel within that group to another group it will no
> longer be subject to those constraints since those constraints were on the group and not on the individual panel.
<Container height={500} sandboxId="constraints-dockview">
<DockviewConstraints />
</Container>
## Events
<EventsDockview />
A simple example showing events fired by `dockviewz that can be interacted with.
<Container height={600} sandboxId="events-dockview">
<EventsDockview />
</Container>
## Advanced Examples
@ -652,10 +677,30 @@ const GroupControlComponent = (props: IDockviewGroupControlProps) => {
You can safely create multiple dockview instances within one page and nest dockviews within other dockviews.
If you wish to interact with the drop event from one dockview instance in another dockview instance you can implement the `showDndOverlay` and `onDidDrop` props on `DockviewReact`.
<NestedDockview />
<Container sandboxId="nested-dockview">
<NestedDockview />
</Container>
### Example
hello
<DockviewNative2 />
hello 2
<div style={{ height: '400px', width: '100%' }}>
<App />
</div>
<!-- ## VanillaJS
> Note: This section is experimental and support for Vanilla JS is a work in progress.
The `dockview` package contains `ReactJS` wrappers for the core library.
The core library is published as an independant package under the name `dockview-core` which you can install standalone.
> When using `dockview` there is no need to also install `dockview-core`.
> `dockview-core` is a dependency of `dockview` and automatically installed during the installation process of `dockview` via `npm install dockview`.
<Container injectVanillaJS={attachDockviewVanilla} /> -->

View File

@ -1,3 +1,3 @@
[
"1.6.0"
"1.7.0"
]

6979
yarn.lock

File diff suppressed because it is too large Load Diff